@@ -186,30 +186,6 @@ def casefold_parts(self, parts):
186186 def compile_pattern (self , pattern ):
187187 return re .compile (fnmatch .translate (pattern ), re .IGNORECASE ).fullmatch
188188
189- def resolve (self , path , strict = False ):
190- s = str (path )
191- if not s :
192- return path ._accessor .getcwd ()
193- previous_s = None
194- if _getfinalpathname is not None :
195- if strict :
196- return self ._ext_to_normal (_getfinalpathname (s ))
197- else :
198- tail_parts = [] # End of the path after the first one not found
199- while True :
200- try :
201- s = self ._ext_to_normal (_getfinalpathname (s ))
202- except FileNotFoundError :
203- previous_s = s
204- s , tail = os .path .split (s )
205- tail_parts .append (tail )
206- if previous_s == s :
207- return path
208- else :
209- return os .path .join (s , * reversed (tail_parts ))
210- # Means fallback on absolute
211- return None
212-
213189 def _split_extended_path (self , s , ext_prefix = ext_namespace_prefix ):
214190 prefix = ''
215191 if s .startswith (ext_prefix ):
@@ -220,10 +196,6 @@ def _split_extended_path(self, s, ext_prefix=ext_namespace_prefix):
220196 s = '\\ ' + s [3 :]
221197 return prefix , s
222198
223- def _ext_to_normal (self , s ):
224- # Turn back an extended path into a normal DOS-like path
225- return self ._split_extended_path (s )[1 ]
226-
227199 def is_reserved (self , parts ):
228200 # NOTE: the rules for reserved names seem somewhat complicated
229201 # (e.g. r"..\NUL" is reserved but not r"foo\NUL").
@@ -281,54 +253,6 @@ def casefold_parts(self, parts):
281253 def compile_pattern (self , pattern ):
282254 return re .compile (fnmatch .translate (pattern )).fullmatch
283255
284- def resolve (self , path , strict = False ):
285- sep = self .sep
286- accessor = path ._accessor
287- seen = {}
288- def _resolve (path , rest ):
289- if rest .startswith (sep ):
290- path = ''
291-
292- for name in rest .split (sep ):
293- if not name or name == '.' :
294- # current dir
295- continue
296- if name == '..' :
297- # parent dir
298- path , _ , _ = path .rpartition (sep )
299- continue
300- if path .endswith (sep ):
301- newpath = path + name
302- else :
303- newpath = path + sep + name
304- if newpath in seen :
305- # Already seen this path
306- path = seen [newpath ]
307- if path is not None :
308- # use cached value
309- continue
310- # The symlink is not resolved, so we must have a symlink loop.
311- raise RuntimeError ("Symlink loop from %r" % newpath )
312- # Resolve the symbolic link
313- try :
314- target = accessor .readlink (newpath )
315- except OSError as e :
316- if e .errno != EINVAL and strict :
317- raise
318- # Not a symlink, or non-strict mode. We just leave the path
319- # untouched.
320- path = newpath
321- else :
322- seen [newpath ] = None # not resolved symlink
323- path = _resolve (path , target )
324- seen [newpath ] = path # resolved symlink
325-
326- return path
327- # NOTE: according to POSIX, getcwd() cannot contain path components
328- # which are symlinks.
329- base = '' if path .is_absolute () else accessor .getcwd ()
330- return _resolve (base , str (path )) or sep
331-
332256 def is_reserved (self , parts ):
333257 return False
334258
@@ -424,6 +348,8 @@ def group(self, path):
424348
425349 expanduser = staticmethod (os .path .expanduser )
426350
351+ realpath = staticmethod (os .path .realpath )
352+
427353
428354_normal_accessor = _NormalAccessor ()
429355
@@ -1132,15 +1058,14 @@ def resolve(self, strict=False):
11321058 normalizing it (for example turning slashes into backslashes under
11331059 Windows).
11341060 """
1135- s = self ._flavour .resolve (self , strict = strict )
1136- if s is None :
1137- # No symlink resolution => for consistency, raise an error if
1138- # the path doesn't exist or is forbidden
1139- self .stat ()
1140- s = str (self .absolute ())
1141- # Now we have no symlinks in the path, it's safe to normalize it.
1142- normed = self ._flavour .pathmod .normpath (s )
1143- return self ._from_parts ((normed ,))
1061+ p = self ._from_parts ((self ._accessor .realpath (self ),))
1062+ try :
1063+ if S_ISLNK (self .lstat ().st_mode ):
1064+ raise RuntimeError ("Symlink loop from %r" % str (p ))
1065+ except OSError :
1066+ if strict :
1067+ raise
1068+ return p
11441069
11451070 def stat (self , * , follow_symlinks = True ):
11461071 """
0 commit comments