@@ -44,7 +44,7 @@ def __init__(self, parsed_url: SplitResult | None, **kwargs: Any) -> None:
4444 self ._fs = cls (** url_kwargs )
4545
4646 def _format_path (self , path : UPath ) -> str :
47- return path .path
47+ return path ._path
4848
4949 def open (self , path , mode = "r" , * args , ** kwargs ):
5050 return self ._fs .open (self ._format_path (path ), mode , * args , ** kwargs )
@@ -206,6 +206,44 @@ def __new__(cls: type[PT], *args: str | PathLike, **kwargs: Any) -> PT:
206206 args_list , url = parsed_url , ** kwargs
207207 )
208208
209+ @property
210+ def protocol (self ) -> str :
211+ """The filesystem_spec protocol
212+
213+ For local paths protocol is either 'file' if the UPath instance
214+ is backed by fsspec or '' if it's backed by stdlib pathlib. For
215+ both `fsspec.get_filesystem_class` returns `LocalFileSystem`.
216+ """
217+ if self ._url is None :
218+ return ""
219+ return self ._url .scheme
220+
221+ @property
222+ def storage_options (self ) -> dict [str , Any ]:
223+ """The filesystem_spec storage options dictionary
224+
225+ Accessing `.storage_options` does not instantiate the
226+ corresponding fsspec filesystem class.
227+ """
228+ return {
229+ key : value
230+ for key , value in self ._kwargs .items ()
231+ if key not in {"scheme" , "netloc" , "url" }
232+ }
233+
234+ @property
235+ def fs (self ) -> AbstractFileSystem :
236+ """The filesystem_spec filesystem instance"""
237+ return self ._accessor ._fs
238+
239+ @property
240+ def path (self ) -> str :
241+ """The filesystem_spec path for use with a filesystem instance
242+
243+ Note: for some file systems this can be prefixed by the protocol.
244+ """
245+ return self ._path
246+
209247 def __getattr__ (self , item : str ) -> Any :
210248 if item == "_accessor" :
211249 # cache the _accessor attribute on first access
@@ -258,7 +296,7 @@ def _format_parsed_parts(
258296 return formatted
259297
260298 @property
261- def path (self ) -> str :
299+ def _path (self ) -> str :
262300 if self ._parts :
263301 join_parts = self ._parts [1 :] if self ._parts [0 ] == "/" else self ._parts
264302 path : str = self ._flavour .join (join_parts )
@@ -349,7 +387,7 @@ def rglob(self: PT, pattern: str) -> Generator[PT, None, None]:
349387
350388 def _sub_path (self , name ):
351389 # only want the path name with iterdir
352- sp = self .path
390+ sp = self ._path
353391 return re .sub (f"^({ sp } |{ sp [1 :]} )/" , "" , name )
354392
355393 def absolute (self : PT ) -> PT :
@@ -631,10 +669,6 @@ def __str__(self) -> str:
631669 )
632670 return self ._str
633671
634- @property
635- def fs (self ) -> AbstractFileSystem :
636- return self ._accessor ._fs
637-
638672 def __truediv__ (self : PT , key : str | PathLike ) -> PT :
639673 # Add `/` root if not present
640674 if len (self ._parts ) == 0 :
0 commit comments