2424from fs .info import Info
2525from fs import errors
2626from fs .mode import Mode
27+ from fs .subfs import SubFS
2728from fs .path import basename , dirname , forcedir , join , normpath , relpath
2829from fs .time import datetime_to_epoch
2930
@@ -336,8 +337,6 @@ def _get_object(self, path, key):
336337 )
337338 obj .load ()
338339 return obj
339- except Exception :
340- raise
341340 else :
342341 return obj
343342
@@ -410,6 +409,13 @@ def _info_from_object(self, obj, namespaces):
410409 }
411410 return info
412411
412+ def isdir (self , path ):
413+ _path = self .validatepath (path )
414+ try :
415+ return self ._getinfo (_path ).is_dir
416+ except errors .ResourceNotFound :
417+ return False
418+
413419 def getinfo (self , path , namespaces = None ):
414420 self .check ()
415421 namespaces = namespaces or ()
@@ -420,7 +426,11 @@ def getinfo(self, path, namespaces=None):
420426 dir_path = dirname (_path )
421427 if dir_path != '/' :
422428 _dir_key = self ._path_to_dir_key (dir_path )
423- self ._get_object (dir_path , _dir_key )
429+ with s3errors (path ):
430+ obj = self .s3 .Object (
431+ self ._bucket_name , _dir_key
432+ )
433+ obj .load ()
424434 except errors .ResourceNotFound :
425435 raise errors .ResourceNotFound (path )
426436
@@ -441,6 +451,28 @@ def getinfo(self, path, namespaces=None):
441451 info = self ._info_from_object (obj , namespaces )
442452 return Info (info )
443453
454+ def _getinfo (self , path , namespaces = None ):
455+ """Gets info without checking for parent dir."""
456+ namespaces = namespaces or ()
457+ _path = self .validatepath (path )
458+ _key = self ._path_to_key (_path )
459+ if _path == '/' :
460+ return Info ({
461+ "basic" :
462+ {
463+ "name" : "" ,
464+ "is_dir" : True
465+ },
466+ "details" :
467+ {
468+ "type" : int (ResourceType .directory )
469+ }
470+ })
471+
472+ obj = self ._get_object (path , _key )
473+ info = self ._info_from_object (obj , namespaces )
474+ return Info (info )
475+
444476 def listdir (self , path ):
445477 _path = self .validatepath (path )
446478 _s3_key = self ._path_to_dir_key (_path )
@@ -481,7 +513,7 @@ def makedir(self, path, permissions=None, recreate=False):
481513 raise errors .ResourceNotFound (path )
482514
483515 try :
484- self .getinfo (path )
516+ self ._getinfo (path )
485517 except errors .ResourceNotFound :
486518 pass
487519 else :
@@ -491,7 +523,7 @@ def makedir(self, path, permissions=None, recreate=False):
491523 raise errors .DirectoryExists (path )
492524 with s3errors (path ):
493525 self .s3 .Object (self ._bucket_name , _key ).put ()
494- return self . opendir ( path )
526+ return SubFS ( self , path )
495527
496528 def openbin (self , path , mode = "r" , buffering = - 1 , ** options ):
497529 _mode = Mode (mode )
@@ -514,7 +546,15 @@ def on_close_create(s3file):
514546 s3file .raw .close ()
515547
516548 try :
517- info = self .getinfo (path )
549+ dir_path = dirname (_path )
550+ if dir_path != '/' :
551+ _dir_key = self ._path_to_dir_key (dir_path )
552+ self ._get_object (dir_path , _dir_key )
553+ except errors .ResourceNotFound :
554+ raise errors .ResourceNotFound (path )
555+
556+ try :
557+ info = self ._getinfo (path )
518558 except errors .ResourceNotFound :
519559 pass
520560 else :
@@ -709,7 +749,7 @@ def setbytes(self, path, contents):
709749 if not self .isdir (dirname (path )):
710750 raise errors .ResourceNotFound (path )
711751 try :
712- info = self .getinfo (path )
752+ info = self ._getinfo (path )
713753 if info .is_dir :
714754 raise errors .FileExpected (path )
715755 except errors .ResourceNotFound :
@@ -729,7 +769,7 @@ def setbinfile(self, path, file):
729769 if not self .isdir (dirname (path )):
730770 raise errors .ResourceNotFound (path )
731771 try :
732- info = self .getinfo (path )
772+ info = self ._getinfo (path )
733773 if info .is_dir :
734774 raise errors .FileExpected (path )
735775 except errors .ResourceNotFound :
0 commit comments