@@ -32,8 +32,10 @@ def complete(self, commit=True):
32
32
lpaths = [f .fn for f in self .files ]
33
33
if commit :
34
34
self .fs .put (lpaths , rpaths )
35
- # else remove?
35
+ self . files . clear ()
36
36
self .fs ._intrans = False
37
+ self .fs ._transaction = None
38
+ self .fs = None # break cycle
37
39
38
40
39
41
class CachingFileSystem (AbstractFileSystem ):
@@ -391,8 +393,11 @@ def close_and_update(self, f, close):
391
393
close ()
392
394
f .closed = True
393
395
396
+ def ls (self , path , detail = True ):
397
+ return self .fs .ls (path , detail )
398
+
394
399
def __getattribute__ (self , item ):
395
- if item in [
400
+ if item in {
396
401
"load_cache" ,
397
402
"_open" ,
398
403
"save_cache" ,
@@ -409,6 +414,11 @@ def __getattribute__(self, item):
409
414
"read_block" ,
410
415
"tail" ,
411
416
"head" ,
417
+ "info" ,
418
+ "ls" ,
419
+ "exists" ,
420
+ "isfile" ,
421
+ "isdir" ,
412
422
"_check_file" ,
413
423
"_check_cache" ,
414
424
"_mkcache" ,
@@ -428,9 +438,12 @@ def __getattribute__(self, item):
428
438
"cache_size" ,
429
439
"pipe_file" ,
430
440
"pipe" ,
441
+ "isdir" ,
442
+ "isfile" ,
443
+ "exists" ,
431
444
"start_transaction" ,
432
445
"end_transaction" ,
433
- ] :
446
+ } :
434
447
# all the methods defined in this class. Note `open` here, since
435
448
# it calls `_open`, but is actually in superclass
436
449
return lambda * args , ** kw : getattr (type (self ), item ).__get__ (self )(
@@ -756,6 +769,49 @@ def pipe_file(self, path, value=None, **kwargs):
756
769
else :
757
770
super ().pipe_file (path , value )
758
771
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
+
759
815
def pipe (self , path , value = None , ** kwargs ):
760
816
if isinstance (path , str ):
761
817
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):
836
892
if seek :
837
893
self .fh .seek (seek )
838
894
self .path = path
895
+ self .size = None
839
896
self .fs = fs
840
897
self .closed = False
841
898
self .autocommit = autocommit
@@ -855,6 +912,7 @@ def __exit__(self, exc_type, exc_val, exc_tb):
855
912
self .close ()
856
913
857
914
def close (self ):
915
+ self .size = self .fh .tell ()
858
916
if self .closed :
859
917
return
860
918
self .fh .close ()
@@ -868,15 +926,14 @@ def discard(self):
868
926
869
927
def commit (self ):
870
928
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
876
930
877
931
@property
878
932
def name (self ):
879
933
return self .fn
880
934
935
+ def __repr__ (self ) -> str :
936
+ return f"LocalTempFile: { self .path } "
937
+
881
938
def __getattr__ (self , item ):
882
939
return getattr (self .fh , item )
0 commit comments