@@ -32,8 +32,10 @@ def complete(self, commit=True):
3232 lpaths = [f .fn for f in self .files ]
3333 if commit :
3434 self .fs .put (lpaths , rpaths )
35- # else remove?
35+ self . files . clear ()
3636 self .fs ._intrans = False
37+ self .fs ._transaction = None
38+ self .fs = None # break cycle
3739
3840
3941class CachingFileSystem (AbstractFileSystem ):
@@ -391,8 +393,11 @@ def close_and_update(self, f, close):
391393 close ()
392394 f .closed = True
393395
396+ def ls (self , path , detail = True ):
397+ return self .fs .ls (path , detail )
398+
394399 def __getattribute__ (self , item ):
395- if item in [
400+ if item in {
396401 "load_cache" ,
397402 "_open" ,
398403 "save_cache" ,
@@ -409,6 +414,11 @@ def __getattribute__(self, item):
409414 "read_block" ,
410415 "tail" ,
411416 "head" ,
417+ "info" ,
418+ "ls" ,
419+ "exists" ,
420+ "isfile" ,
421+ "isdir" ,
412422 "_check_file" ,
413423 "_check_cache" ,
414424 "_mkcache" ,
@@ -428,9 +438,12 @@ def __getattribute__(self, item):
428438 "cache_size" ,
429439 "pipe_file" ,
430440 "pipe" ,
441+ "isdir" ,
442+ "isfile" ,
443+ "exists" ,
431444 "start_transaction" ,
432445 "end_transaction" ,
433- ] :
446+ } :
434447 # all the methods defined in this class. Note `open` here, since
435448 # it calls `_open`, but is actually in superclass
436449 return lambda * args , ** kw : getattr (type (self ), item ).__get__ (self )(
@@ -756,6 +769,49 @@ def pipe_file(self, path, value=None, **kwargs):
756769 else :
757770 super ().pipe_file (path , value )
758771
772+ def ls (self , path , detail = True , ** kwargs ):
773+ path = self ._strip_protocol (path )
774+ details = []
775+ try :
776+ details = self .fs .ls (
777+ path , detail = True , ** kwargs
778+ ).copy () # don't edit original!
779+ except FileNotFoundError as e :
780+ ex = e
781+ else :
782+ ex = None
783+ if self ._intrans :
784+ path1 = path .rstrip ("/" ) + "/"
785+ for f in self .transaction .files :
786+ if f .path == path :
787+ details .append (
788+ {"name" : path , "size" : f .size or f .tell (), "type" : "file" }
789+ )
790+ elif f .path .startswith (path1 ):
791+ if f .path .count ("/" ) == path1 .count ("/" ):
792+ details .append (
793+ {"name" : f .path , "size" : f .size or f .tell (), "type" : "file" }
794+ )
795+ else :
796+ dname = "/" .join (f .path .split ("/" )[: path1 .count ("/" ) + 1 ])
797+ details .append ({"name" : dname , "size" : 0 , "type" : "directory" })
798+ if ex is not None and not details :
799+ raise ex
800+ if detail :
801+ return details
802+ return sorted (_ ["name" ] for _ in details )
803+
804+ def info (self , path , ** kwargs ):
805+ path = self ._strip_protocol (path )
806+ if self ._intrans :
807+ f = [_ for _ in self .transaction .files if _ .path == path ]
808+ if f :
809+ return {"name" : path , "size" : f [0 ].size or f [0 ].tell (), "type" : "file" }
810+ f = any (_ .path .startswith (path + "/" ) for _ in self .transaction .files )
811+ if f :
812+ return {"name" : path , "size" : 0 , "type" : "directory" }
813+ return self .fs .info (path , ** kwargs )
814+
759815 def pipe (self , path , value = None , ** kwargs ):
760816 if isinstance (path , str ):
761817 self .pipe_file (self ._strip_protocol (path ), value , ** kwargs )
@@ -836,6 +892,7 @@ def __init__(self, fs, path, fn, mode="wb", autocommit=True, seek=0, **kwargs):
836892 if seek :
837893 self .fh .seek (seek )
838894 self .path = path
895+ self .size = None
839896 self .fs = fs
840897 self .closed = False
841898 self .autocommit = autocommit
@@ -855,6 +912,7 @@ def __exit__(self, exc_type, exc_val, exc_tb):
855912 self .close ()
856913
857914 def close (self ):
915+ self .size = self .fh .tell ()
858916 if self .closed :
859917 return
860918 self .fh .close ()
@@ -868,15 +926,14 @@ def discard(self):
868926
869927 def commit (self ):
870928 self .fs .put (self .fn , self .path , ** self .kwargs )
871- try :
872- os .remove (self .fn )
873- except (PermissionError , FileNotFoundError ):
874- # file path may be held by new version of the file on windows
875- pass
929+ # we do not delete local copy - it's still in the cache
876930
877931 @property
878932 def name (self ):
879933 return self .fn
880934
935+ def __repr__ (self ) -> str :
936+ return f"LocalTempFile: { self .path } "
937+
881938 def __getattr__ (self , item ):
882939 return getattr (self .fh , item )
0 commit comments