[Python-checkins] bpo-38081: Add more non-fatal error codes for ntpath.realpath (GH-16156)

Steve Dower webhook-mailer at python.org
Mon Sep 16 10:25:15 EDT 2019


https://github.com/python/cpython/commit/89b8933bb537179f81003928786c5cc6183af591
commit: 89b8933bb537179f81003928786c5cc6183af591
branch: master
author: Steve Dower <steve.dower at python.org>
committer: GitHub <noreply at github.com>
date: 2019-09-16T15:25:11+01:00
summary:

bpo-38081: Add more non-fatal error codes for ntpath.realpath (GH-16156)

files:
M Lib/ntpath.py

diff --git a/Lib/ntpath.py b/Lib/ntpath.py
index 1b5e16f95f16..01f1f423c906 100644
--- a/Lib/ntpath.py
+++ b/Lib/ntpath.py
@@ -530,15 +530,28 @@ def _readlink_deep(path, seen=None):
         if seen is None:
             seen = set()
 
+        # These error codes indicate that we should stop reading links and
+        # return the path we currently have.
+        # 1: ERROR_INVALID_FUNCTION
+        # 2: ERROR_FILE_NOT_FOUND
+        # 3: ERROR_DIRECTORY_NOT_FOUND
+        # 5: ERROR_ACCESS_DENIED
+        # 21: ERROR_NOT_READY (implies drive with no media)
+        # 32: ERROR_SHARING_VIOLATION (probably an NTFS paging file)
+        # 50: ERROR_NOT_SUPPORTED (implies no support for reparse points)
+        # 67: ERROR_BAD_NET_NAME (implies remote server unavailable)
+        # 87: ERROR_INVALID_PARAMETER
+        # 4390: ERROR_NOT_A_REPARSE_POINT
+        # 4392: ERROR_INVALID_REPARSE_DATA
+        # 4393: ERROR_REPARSE_TAG_INVALID
+        allowed_winerror = 1, 2, 3, 5, 21, 32, 50, 67, 87, 4390, 4392, 4393
+
         while normcase(path) not in seen:
             seen.add(normcase(path))
             try:
                 path = _nt_readlink(path)
             except OSError as ex:
-                # Stop on incorrect function (1), file (2) or
-                # directory (3) not found, or paths that are
-                # not reparse points (4390)
-                if ex.winerror in (1, 2, 3, 4390):
+                if ex.winerror in allowed_winerror:
                     break
                 raise
             except ValueError:
@@ -554,9 +567,20 @@ def _getfinalpathname_nonstrict(path):
         except OSError:
             pass
 
-        # Allow file (2) or directory (3) not found, incorrect parameter (87),
-        # invalid syntax (123), and symlinks that cannot be followed (1921)
-        allowed_winerror = 2, 3, 87, 123, 1921
+        # These error codes indicate that we should stop resolving the path
+        # and return the value we currently have.
+        # 1: ERROR_INVALID_FUNCTION
+        # 2: ERROR_FILE_NOT_FOUND
+        # 3: ERROR_DIRECTORY_NOT_FOUND
+        # 5: ERROR_ACCESS_DENIED
+        # 21: ERROR_NOT_READY (implies drive with no media)
+        # 32: ERROR_SHARING_VIOLATION (probably an NTFS paging file)
+        # 50: ERROR_NOT_SUPPORTED
+        # 67: ERROR_BAD_NET_NAME (implies remote server unavailable)
+        # 87: ERROR_INVALID_PARAMETER
+        # 123: ERROR_INVALID_NAME
+        # 1921: ERROR_CANT_RESOLVE_FILENAME (implies unfollowable symlink)
+        allowed_winerror = 1, 2, 3, 5, 21, 32, 50, 67, 87, 123, 1921
 
         # Non-strict algorithm is to find as much of the target directory
         # as we can and join the rest.
@@ -571,6 +595,9 @@ def _getfinalpathname_nonstrict(path):
                 if ex.winerror not in allowed_winerror:
                     raise
                 path, name = split(path)
+                # TODO (bpo-38186): Request the real file name from the directory
+                # entry using FindFirstFileW. For now, we will return the path
+                # as best we have it
                 if path and not name:
                     return abspath(path + tail)
                 tail = join(name, tail) if tail else name



More information about the Python-checkins mailing list