@@ -967,18 +967,39 @@ async def _ls(self, path, detail=False, refresh=False, versions=False):
967967 return files
968968 return files if detail else sorted ([o ["name" ] for o in files ])
969969
970+ def _exists_in_cache (self , path , bucket , key , version_id ):
971+ fullpath = "/" .join ((bucket , key ))
972+
973+ try :
974+ entries = self ._ls_from_cache (fullpath )
975+ except FileNotFoundError :
976+ return False
977+
978+ if entries is None :
979+ return None
980+
981+ if not self .version_aware or version_id is None :
982+ return True
983+
984+ for entry in entries :
985+ if entry ["name" ] == fullpath and entry .get ("VersionId" ) == version_id :
986+ return True
987+
988+ # dircache doesn't support multiple versions, so we really can't tell if
989+ # the one we want exists.
990+ return None
991+
970992 async def _exists (self , path ):
971993 if path in ["" , "/" ]:
972994 # the root always exists, even if anon
973995 return True
974996 path = self ._strip_protocol (path )
975997 bucket , key , version_id = self .split_path (path )
976998 if key :
977- try :
978- if self ._ls_from_cache (path ):
979- return True
980- except FileNotFoundError :
981- return False
999+ exists_in_cache = self ._exists_in_cache (path , bucket , key , version_id )
1000+ if exists_in_cache is not None :
1001+ return exists_in_cache
1002+
9821003 try :
9831004 await self ._info (path , bucket , key , version_id = version_id )
9841005 return True
@@ -1216,6 +1237,8 @@ async def _open_file(range: int):
12161237 async def _info (self , path , bucket = None , key = None , refresh = False , version_id = None ):
12171238 path = self ._strip_protocol (path )
12181239 bucket , key , path_version_id = self .split_path (path )
1240+ fullpath = "/" .join ((bucket , key ))
1241+
12191242 if version_id is not None :
12201243 if not self .version_aware :
12211244 raise ValueError (
@@ -1226,15 +1249,15 @@ async def _info(self, path, bucket=None, key=None, refresh=False, version_id=Non
12261249 return {"name" : path , "size" : 0 , "type" : "directory" }
12271250 version_id = _coalesce_version_id (path_version_id , version_id )
12281251 if not refresh :
1229- out = self ._ls_from_cache (path )
1252+ out = self ._ls_from_cache (fullpath )
12301253 if out is not None :
12311254 if self .version_aware and version_id is not None :
12321255 # If cached info does not match requested version_id,
12331256 # fallback to calling head_object
12341257 out = [
12351258 o
12361259 for o in out
1237- if o ["name" ] == path and version_id == o .get ("VersionId" )
1260+ if o ["name" ] == fullpath and version_id == o .get ("VersionId" )
12381261 ]
12391262 if out :
12401263 return out [0 ]
0 commit comments