@@ -1182,6 +1182,8 @@ def _split_stack(self):
1182
1182
uppermost parent of the path (equivalent to path.parents[-1]), and
1183
1183
*parts* is a reversed list of parts following the anchor.
1184
1184
"""
1185
+ if not self ._tail :
1186
+ return self , []
1185
1187
return self ._from_parsed_parts (self .drive , self .root , []), self ._tail [::- 1 ]
1186
1188
1187
1189
def resolve (self , strict = False ):
@@ -1191,18 +1193,16 @@ def resolve(self, strict=False):
1191
1193
"""
1192
1194
if self ._resolving :
1193
1195
return self
1196
+ path , parts = self ._split_stack ()
1194
1197
try :
1195
- path = self .absolute ()
1198
+ path = path .absolute ()
1196
1199
except UnsupportedOperation :
1197
- path = self
1200
+ pass
1198
1201
1199
1202
# If the user has *not* overridden the `readlink()` method, then symlinks are unsupported
1200
1203
# and (in non-strict mode) we can improve performance by not calling `stat()`.
1201
1204
querying = strict or getattr (self .readlink , '_supported' , True )
1202
1205
link_count = 0
1203
- stat_cache = {}
1204
- target_cache = {}
1205
- path , parts = path ._split_stack ()
1206
1206
while parts :
1207
1207
part = parts .pop ()
1208
1208
if part == '..' :
@@ -1214,40 +1214,35 @@ def resolve(self, strict=False):
1214
1214
# Delete '..' segment and its predecessor
1215
1215
path = path .parent
1216
1216
continue
1217
- # Join the current part onto the path.
1218
- path_parent = path
1219
- path = path ._make_child_relpath (part )
1217
+ next_path = path ._make_child_relpath (part )
1220
1218
if querying and part != '..' :
1221
- path ._resolving = True
1219
+ next_path ._resolving = True
1222
1220
try :
1223
- st = stat_cache .get (path )
1224
- if st is None :
1225
- st = stat_cache [path ] = path .stat (follow_symlinks = False )
1221
+ st = next_path .stat (follow_symlinks = False )
1226
1222
if S_ISLNK (st .st_mode ):
1227
1223
# Like Linux and macOS, raise OSError(errno.ELOOP) if too many symlinks are
1228
1224
# encountered during resolution.
1229
1225
link_count += 1
1230
1226
if link_count >= _MAX_SYMLINKS :
1231
- raise OSError (ELOOP , "Too many symbolic links in path" , str (path ))
1232
- target = target_cache .get (path )
1233
- if target is None :
1234
- target = target_cache [path ] = path .readlink ()
1235
- target , target_parts = target ._split_stack ()
1227
+ raise OSError (ELOOP , "Too many symbolic links in path" , str (self ))
1228
+ target , target_parts = next_path .readlink ()._split_stack ()
1236
1229
# If the symlink target is absolute (like '/etc/hosts'), set the current
1237
- # path to its uppermost parent (like '/'). If not, the symlink target is
1238
- # relative to the symlink parent, which we recorded earlier.
1239
- path = target if target . root else path_parent
1230
+ # path to its uppermost parent (like '/').
1231
+ if target . root :
1232
+ path = target
1240
1233
# Add the symlink target's reversed tail parts (like ['hosts', 'etc']) to
1241
1234
# the stack of unresolved path parts.
1242
1235
parts .extend (target_parts )
1236
+ continue
1243
1237
elif parts and not S_ISDIR (st .st_mode ):
1244
- raise NotADirectoryError (ENOTDIR , "Not a directory" , str (path ))
1238
+ raise NotADirectoryError (ENOTDIR , "Not a directory" , str (self ))
1245
1239
except OSError :
1246
1240
if strict :
1247
1241
raise
1248
1242
else :
1249
1243
querying = False
1250
- path ._resolving = False
1244
+ next_path ._resolving = False
1245
+ path = next_path
1251
1246
return path
1252
1247
1253
1248
def symlink_to (self , target , target_is_directory = False ):
0 commit comments