@@ -29,7 +29,7 @@ def __init__(self, parsed_url: ParseResult, **kwargs):
2929 def _format_path (self , path : "UPath" ) -> str :
3030 return path .path
3131
32- def open (self , path , mode = 'r' , * args , ** kwargs ):
32+ def open (self , path , mode = "r" , * args , ** kwargs ):
3333 return self ._fs .open (self ._format_path (path ), mode , * args , ** kwargs )
3434
3535 def stat (self , path , ** kwargs ):
@@ -185,6 +185,9 @@ def parent(self):
185185 def stat (self ):
186186 return self ._accessor .stat (self )
187187
188+ def samefile (self , other_path ):
189+ raise NotImplementedError
190+
188191 def iterdir (self ):
189192 """Iterate over the files in this directory. Does not yield any
190193 result for the special paths '.' and '..'.
@@ -223,18 +226,36 @@ def relative_to(self, *other):
223226 output ._kwargs = self ._kwargs
224227 return output
225228
229+ def _scandir (self ):
230+ # provided in Python3.11 but not required in fsspec glob implementation
231+ raise NotImplementedError
232+
226233 def glob (self , pattern ):
227234 path_pattern = self .joinpath (pattern )
228235 for name in self ._accessor .glob (self , path_pattern ):
229236 name = self ._sub_path (name )
230237 name = name .split (self ._flavour .sep )
231238 yield self ._make_child (name )
232239
240+ def rglob (self , pattern ):
241+ path_pattern = self .joinpath ("**" , pattern )
242+ for name in self ._accessor .glob (self , path_pattern ):
243+ name = self ._sub_path (name )
244+ name = name .split (self ._flavour .sep )
245+ yield self ._make_child (name )
246+
233247 def _sub_path (self , name ):
234248 # only want the path name with iterdir
235249 sp = self .path
236250 return re .sub (f"^({ sp } |{ sp [1 :]} )/" , "" , name )
237251
252+ def absolute (self ):
253+ # fsspec paths are always absolute
254+ return self
255+
256+ def resolve (self , strict = False ):
257+ raise NotImplementedError
258+
238259 def exists (self ):
239260 """
240261 Whether this path exists.
@@ -290,6 +311,9 @@ def is_block_device(self):
290311 def is_char_device (self ):
291312 return False
292313
314+ def is_absolute (self ):
315+ return True
316+
293317 def unlink (self , missing_ok = False ):
294318 if not self .exists ():
295319 if not missing_ok :
@@ -308,13 +332,25 @@ def rmdir(self, recursive=True):
308332 raise NotDirectoryError
309333 self ._accessor .rm (self , recursive = recursive )
310334
311- def chmod (self , mod ):
335+ def chmod (self , mode , * , follow_symlinks = True ):
312336 raise NotImplementedError
313337
314338 def rename (self , target ):
315339 # can be implemented, but may be tricky
316340 raise NotImplementedError
317341
342+ def replace (self , target ):
343+ raise NotImplementedError
344+
345+ def symlink_to (self , target , target_is_directory = False ):
346+ raise NotImplementedError
347+
348+ def hardlink_to (self , target ):
349+ raise NotImplementedError
350+
351+ def link_to (self , target ):
352+ raise NotImplementedError
353+
318354 def cwd (self ):
319355 raise NotImplementedError
320356
@@ -342,6 +378,28 @@ def readlink(self):
342378 def touch (self , truncate = True , ** kwargs ):
343379 self ._accessor .touch (self , truncate = truncate , ** kwargs )
344380
381+ def mkdir (self , mode = 0o777 , parents = False , exist_ok = False ):
382+ """
383+ Create a new directory at this given path.
384+ """
385+ if parents :
386+ self ._accessor .mkdir (
387+ self ,
388+ create_parents = True ,
389+ exist_ok = exist_ok ,
390+ mode = mode ,
391+ )
392+ else :
393+ try :
394+ self ._accessor .mkdir (
395+ self ,
396+ create_parents = False ,
397+ mode = mode ,
398+ )
399+ except FileExistsError :
400+ if not exist_ok or not self .is_dir ():
401+ raise
402+
345403 @classmethod
346404 def _from_parts (cls , args , url = None , ** kwargs ):
347405 obj = object .__new__ (cls )
@@ -426,7 +484,7 @@ def with_suffix(self, suffix):
426484 f = self ._flavour
427485 if f .sep in suffix or f .altsep and f .altsep in suffix :
428486 raise ValueError ("Invalid suffix %r" % (suffix ,))
429- if suffix and not suffix .startswith ('.' ) or suffix == '.' :
487+ if suffix and not suffix .startswith ("." ) or suffix == "." :
430488 raise ValueError ("Invalid suffix %r" % (suffix ))
431489 name = self .name
432490 if not name :
@@ -435,17 +493,24 @@ def with_suffix(self, suffix):
435493 if not old_suffix :
436494 name = name + suffix
437495 else :
438- name = name [:- len (old_suffix )] + suffix
439- return self ._from_parsed_parts (self ._drv , self ._root ,
440- self ._parts [:- 1 ] + [name ], url = self ._url )
496+ name = name [: - len (old_suffix )] + suffix
497+ return self ._from_parsed_parts (
498+ self ._drv , self ._root , self ._parts [:- 1 ] + [name ], url = self ._url
499+ )
441500
442501 def with_name (self , name ):
443502 """Return a new path with the file name changed."""
444503 if not self .name :
445504 raise ValueError ("%r has an empty name" % (self ,))
446505 drv , root , parts = self ._flavour .parse_parts ((name ,))
447- if (not name or name [- 1 ] in [self ._flavour .sep , self ._flavour .altsep ]
448- or drv or root or len (parts ) != 1 ):
506+ if (
507+ not name
508+ or name [- 1 ] in [self ._flavour .sep , self ._flavour .altsep ]
509+ or drv
510+ or root
511+ or len (parts ) != 1
512+ ):
449513 raise ValueError ("Invalid name %r" % (name ))
450- return self ._from_parsed_parts (self ._drv , self ._root ,
451- self ._parts [:- 1 ] + [name ], url = self ._url )
514+ return self ._from_parsed_parts (
515+ self ._drv , self ._root , self ._parts [:- 1 ] + [name ], url = self ._url
516+ )
0 commit comments