]> granicus.if.org Git - python/commitdiff
bpo-38355: Fix ntpath.realpath failing on sys.executable (GH-16551)
authorSteve Dower <steve.dower@python.org>
Thu, 3 Oct 2019 15:31:03 +0000 (08:31 -0700)
committerGitHub <noreply@github.com>
Thu, 3 Oct 2019 15:31:03 +0000 (08:31 -0700)
Lib/ntpath.py
Lib/test/test_ntpath.py
Misc/NEWS.d/next/Windows/2019-10-02-15-38-49.bpo-38355.n3AWX6.rst [new file with mode: 0644]

index 01f1f423c906cdd8858ae84d8ae8dec1412bf52c..d4ecff97c95286a91c3f3a3bf98d337967820709 100644 (file)
@@ -560,13 +560,6 @@ else:
         return path
 
     def _getfinalpathname_nonstrict(path):
-        # Fast path to get the final path name. If this succeeds, there
-        # is no need to go any further.
-        try:
-            return _getfinalpathname(path)
-        except OSError:
-            pass
-
         # These error codes indicate that we should stop resolving the path
         # and return the value we currently have.
         # 1: ERROR_INVALID_FUNCTION
@@ -579,8 +572,9 @@ else:
         # 67: ERROR_BAD_NET_NAME (implies remote server unavailable)
         # 87: ERROR_INVALID_PARAMETER
         # 123: ERROR_INVALID_NAME
+        # 1920: ERROR_CANT_ACCESS_FILE
         # 1921: ERROR_CANT_RESOLVE_FILENAME (implies unfollowable symlink)
-        allowed_winerror = 1, 2, 3, 5, 21, 32, 50, 67, 87, 123, 1921
+        allowed_winerror = 1, 2, 3, 5, 21, 32, 50, 67, 87, 123, 1920, 1921
 
         # Non-strict algorithm is to find as much of the target directory
         # as we can and join the rest.
@@ -615,9 +609,13 @@ else:
             unc_prefix = '\\\\?\\UNC\\'
             new_unc_prefix = '\\\\'
             cwd = os.getcwd()
-        did_not_exist = not exists(path)
         had_prefix = path.startswith(prefix)
-        path = _getfinalpathname_nonstrict(path)
+        try:
+            path = _getfinalpathname(path)
+            initial_winerror = 0
+        except OSError as ex:
+            initial_winerror = ex.winerror
+            path = _getfinalpathname_nonstrict(path)
         # The path returned by _getfinalpathname will always start with \\?\ -
         # strip off that prefix unless it was already provided on the original
         # path.
@@ -635,7 +633,7 @@ else:
             except OSError as ex:
                 # If the path does not exist and originally did not exist, then
                 # strip the prefix anyway.
-                if ex.winerror in {2, 3} and did_not_exist:
+                if ex.winerror == initial_winerror:
                     path = spath
         return path
 
index 2f0faf94726fd2742b2d8a256af67614242b5279..e0ec441985230ad4d69399577db8866394d08a37 100644 (file)
@@ -329,16 +329,14 @@ class TestNtpath(NtpathTestCase):
         self.addCleanup(support.unlink, ABSTFN + "c")
         self.addCleanup(support.unlink, ABSTFN + "a")
 
-        P = "\\\\?\\"
-
         os.symlink(ABSTFN, ABSTFN)
-        self.assertPathEqual(ntpath.realpath(ABSTFN), P + ABSTFN)
+        self.assertPathEqual(ntpath.realpath(ABSTFN), ABSTFN)
 
         # cycles are non-deterministic as to which path is returned, but
         # it will always be the fully resolved path of one member of the cycle
         os.symlink(ABSTFN + "1", ABSTFN + "2")
         os.symlink(ABSTFN + "2", ABSTFN + "1")
-        expected = (P + ABSTFN + "1", P + ABSTFN + "2")
+        expected = (ABSTFN + "1", ABSTFN + "2")
         self.assertPathIn(ntpath.realpath(ABSTFN + "1"), expected)
         self.assertPathIn(ntpath.realpath(ABSTFN + "2"), expected)
 
@@ -357,14 +355,14 @@ class TestNtpath(NtpathTestCase):
                           expected)
 
         os.symlink(ntpath.basename(ABSTFN) + "a\\b", ABSTFN + "a")
-        self.assertPathEqual(ntpath.realpath(ABSTFN + "a"), P + ABSTFN + "a")
+        self.assertPathEqual(ntpath.realpath(ABSTFN + "a"), ABSTFN + "a")
 
         os.symlink("..\\" + ntpath.basename(ntpath.dirname(ABSTFN))
                    + "\\" + ntpath.basename(ABSTFN) + "c", ABSTFN + "c")
-        self.assertPathEqual(ntpath.realpath(ABSTFN + "c"), P + ABSTFN + "c")
+        self.assertPathEqual(ntpath.realpath(ABSTFN + "c"), ABSTFN + "c")
 
         # Test using relative path as well.
-        self.assertPathEqual(ntpath.realpath(ntpath.basename(ABSTFN)), P + ABSTFN)
+        self.assertPathEqual(ntpath.realpath(ntpath.basename(ABSTFN)), ABSTFN)
 
     @support.skip_unless_symlink
     @unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname')
diff --git a/Misc/NEWS.d/next/Windows/2019-10-02-15-38-49.bpo-38355.n3AWX6.rst b/Misc/NEWS.d/next/Windows/2019-10-02-15-38-49.bpo-38355.n3AWX6.rst
new file mode 100644 (file)
index 0000000..56e0f56
--- /dev/null
@@ -0,0 +1 @@
+Fixes ``ntpath.realpath`` failing on ``sys.executable``.