@@ -195,10 +195,10 @@ def _select_unique(paths):
195195 yielded = set ()
196196 try :
197197 for path in paths :
198- raw_path = path . _raw_path
199- if raw_path not in yielded :
198+ path_str = str ( path )
199+ if path_str not in yielded :
200200 yield path
201- yielded .add (raw_path )
201+ yielded .add (path_str )
202202 finally :
203203 yielded .clear ()
204204
@@ -247,9 +247,9 @@ class PurePath:
247247 """
248248
249249 __slots__ = (
250- # The `_raw_path ` slot stores an unnormalized string path . This is set
250+ # The `_raw_paths ` slot stores unnormalized string paths . This is set
251251 # in the `__init__()` method.
252- '_raw_path ' ,
252+ '_raw_paths ' ,
253253
254254 # The `_drv`, `_root` and `_tail_cached` slots store parsed and
255255 # normalized parts of the path. They are set when any of the `drive`,
@@ -306,10 +306,11 @@ def __init__(self, *args):
306306 paths = []
307307 for arg in args :
308308 if isinstance (arg , PurePath ):
309- path = arg ._raw_path
310309 if arg ._flavour is ntpath and self ._flavour is posixpath :
311310 # GH-103631: Convert separators for backwards compatibility.
312- path = path .replace ('\\ ' , '/' )
311+ paths .extend (path .replace ('\\ ' , '/' ) for path in arg ._raw_paths )
312+ else :
313+ paths .extend (arg ._raw_paths )
313314 else :
314315 try :
315316 path = os .fspath (arg )
@@ -320,13 +321,8 @@ def __init__(self, *args):
320321 "argument should be a str or an os.PathLike "
321322 "object where __fspath__ returns a str, "
322323 f"not { type (path ).__name__ !r} " )
323- paths .append (path )
324- if len (paths ) == 0 :
325- self ._raw_path = ''
326- elif len (paths ) == 1 :
327- self ._raw_path = paths [0 ]
328- else :
329- self ._raw_path = self ._flavour .join (* paths )
324+ paths .append (path )
325+ self ._raw_paths = paths
330326
331327 def with_segments (self , * pathsegments ):
332328 """Construct a new path object from any number of path-like objects.
@@ -356,7 +352,14 @@ def _parse_path(cls, path):
356352 return drv , root , parsed
357353
358354 def _load_parts (self ):
359- drv , root , tail = self ._parse_path (self ._raw_path )
355+ paths = self ._raw_paths
356+ if len (paths ) == 0 :
357+ path = ''
358+ elif len (paths ) == 1 :
359+ path = paths [0 ]
360+ else :
361+ path = self ._flavour .join (* paths )
362+ drv , root , tail = self ._parse_path (path )
360363 self ._drv = drv
361364 self ._root = root
362365 self ._tail_cached = tail
@@ -687,10 +690,17 @@ def parents(self):
687690 def is_absolute (self ):
688691 """True if the path is absolute (has both a root and, if applicable,
689692 a drive)."""
690- # ntpath.isabs() is defective - see GH-44626 .
691693 if self ._flavour is ntpath :
694+ # ntpath.isabs() is defective - see GH-44626.
692695 return bool (self .drive and self .root )
693- return self ._flavour .isabs (self ._raw_path )
696+ elif self ._flavour is posixpath :
697+ # Optimization: work with raw paths on POSIX.
698+ for path in self ._raw_paths :
699+ if path .startswith ('/' ):
700+ return True
701+ return False
702+ else :
703+ return self ._flavour .isabs (str (self ))
694704
695705 def is_reserved (self ):
696706 """Return True if the path contains one of the special names reserved
0 commit comments