aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Lib/posixpath.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/posixpath.py')
-rw-r--r--Lib/posixpath.py57
1 files changed, 33 insertions, 24 deletions
diff --git a/Lib/posixpath.py b/Lib/posixpath.py
index db72ded8826..d38f3bd5872 100644
--- a/Lib/posixpath.py
+++ b/Lib/posixpath.py
@@ -36,7 +36,7 @@ __all__ = ["normcase","isabs","join","splitdrive","splitroot","split","splitext"
"samefile","sameopenfile","samestat",
"curdir","pardir","sep","pathsep","defpath","altsep","extsep",
"devnull","realpath","supports_unicode_filenames","relpath",
- "commonpath", "isjunction","isdevdrive"]
+ "commonpath", "isjunction","isdevdrive","ALLOW_MISSING"]
def _get_sep(path):
@@ -402,10 +402,18 @@ symbolic links encountered in the path."""
curdir = '.'
pardir = '..'
getcwd = os.getcwd
- return _realpath(filename, strict, sep, curdir, pardir, getcwd)
+ if strict is ALLOW_MISSING:
+ ignored_error = FileNotFoundError
+ strict = True
+ elif strict:
+ ignored_error = ()
+ else:
+ ignored_error = OSError
+
+ lstat = os.lstat
+ readlink = os.readlink
+ maxlinks = None
-def _realpath(filename, strict=False, sep=sep, curdir=curdir, pardir=pardir,
- getcwd=os.getcwd, lstat=os.lstat, readlink=os.readlink, maxlinks=None):
# The stack of unresolved path parts. When popped, a special value of None
# indicates that a symlink target has been resolved, and that the original
# symlink path can be retrieved by popping again. The [::-1] slice is a
@@ -477,27 +485,28 @@ def _realpath(filename, strict=False, sep=sep, curdir=curdir, pardir=pardir,
path = newpath
continue
target = readlink(newpath)
- except OSError:
- if strict:
- raise
- path = newpath
+ except ignored_error:
+ pass
+ else:
+ # Resolve the symbolic link
+ if target.startswith(sep):
+ # Symlink target is absolute; reset resolved path.
+ path = sep
+ if maxlinks is None:
+ # Mark this symlink as seen but not fully resolved.
+ seen[newpath] = None
+ # Push the symlink path onto the stack, and signal its specialness
+ # by also pushing None. When these entries are popped, we'll
+ # record the fully-resolved symlink target in the 'seen' mapping.
+ rest.append(newpath)
+ rest.append(None)
+ # Push the unresolved symlink target parts onto the stack.
+ target_parts = target.split(sep)[::-1]
+ rest.extend(target_parts)
+ part_count += len(target_parts)
continue
- # Resolve the symbolic link
- if target.startswith(sep):
- # Symlink target is absolute; reset resolved path.
- path = sep
- if maxlinks is None:
- # Mark this symlink as seen but not fully resolved.
- seen[newpath] = None
- # Push the symlink path onto the stack, and signal its specialness
- # by also pushing None. When these entries are popped, we'll
- # record the fully-resolved symlink target in the 'seen' mapping.
- rest.append(newpath)
- rest.append(None)
- # Push the unresolved symlink target parts onto the stack.
- target_parts = target.split(sep)[::-1]
- rest.extend(target_parts)
- part_count += len(target_parts)
+ # An error occurred and was ignored.
+ path = newpath
return path