11import pathlib
22import re
33import sys
4+ from typing import Sequence
45from typing import Union
56import urllib
67from urllib .parse import ParseResult
@@ -501,7 +502,11 @@ def with_suffix(self, suffix):
501502 else :
502503 name = name [: - len (old_suffix )] + suffix
503504 return self ._from_parsed_parts (
504- self ._drv , self ._root , self ._parts [:- 1 ] + [name ], url = self ._url
505+ self ._drv ,
506+ self ._root ,
507+ self ._parts [:- 1 ] + [name ],
508+ url = self ._url ,
509+ ** self ._kwargs ,
505510 )
506511
507512 def with_name (self , name ):
@@ -518,5 +523,62 @@ def with_name(self, name):
518523 ):
519524 raise ValueError ("Invalid name %r" % (name ))
520525 return self ._from_parsed_parts (
521- self ._drv , self ._root , self ._parts [:- 1 ] + [name ], url = self ._url
526+ self ._drv ,
527+ self ._root ,
528+ self ._parts [:- 1 ] + [name ],
529+ url = self ._url ,
530+ ** self ._kwargs ,
522531 )
532+
533+ @property
534+ def parents (self ):
535+ """A sequence of this upath's logical parents."""
536+ return _UPathParents (self )
537+
538+
539+ class _UPathParents (Sequence ):
540+ """This object provides sequence-like access to the logical ancestors
541+ of a path. Don't try to construct it yourself."""
542+
543+ __slots__ = (
544+ "_pathcls" ,
545+ "_drv" ,
546+ "_root" ,
547+ "_parts" ,
548+ "_url" ,
549+ "_kwargs" ,
550+ )
551+
552+ def __init__ (self , path ):
553+ # We don't store the instance to avoid reference cycles
554+ self ._pathcls = type (path )
555+ self ._drv = path ._drv
556+ self ._root = path ._root
557+ self ._parts = path ._parts
558+ self ._url = path ._url
559+ self ._kwargs = path ._kwargs
560+
561+ def __len__ (self ):
562+ if self ._drv or self ._root :
563+ return len (self ._parts ) - 1
564+ else :
565+ return len (self ._parts )
566+
567+ def __getitem__ (self , idx ):
568+ if isinstance (idx , slice ):
569+ return tuple (self [i ] for i in range (* idx .indices (len (self ))))
570+
571+ if idx >= len (self ) or idx < - len (self ):
572+ raise IndexError (idx )
573+ if idx < 0 :
574+ idx += len (self )
575+ return self ._pathcls ._from_parsed_parts (
576+ self ._drv ,
577+ self ._root ,
578+ self ._parts [: - idx - 1 ],
579+ url = self ._url ,
580+ ** self ._kwargs ,
581+ )
582+
583+ def __repr__ (self ):
584+ return "<{}.parents>" .format (self ._pathcls .__name__ )
0 commit comments