From 6067e1d2bebccc2e73dd729d25c98df7bc9e2d59 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Thu, 3 Oct 2019 08:49:56 -0700 Subject: [PATCH] bpo-38355: Fix ntpath.realpath failing on sys.executable (GH-16551) (cherry picked from commit a0e3d27e4e3cb5b67e325df080fb18b70c2910cf) Co-authored-by: Steve Dower --- Lib/ntpath.py | 20 +++++++++---------- Lib/test/test_ntpath.py | 12 +++++------ .../2019-10-02-15-38-49.bpo-38355.n3AWX6.rst | 1 + 3 files changed, 15 insertions(+), 18 deletions(-) create mode 100644 Misc/NEWS.d/next/Windows/2019-10-02-15-38-49.bpo-38355.n3AWX6.rst diff --git a/Lib/ntpath.py b/Lib/ntpath.py index 01f1f423c90..d4ecff97c95 100644 --- a/Lib/ntpath.py +++ b/Lib/ntpath.py @@ -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 diff --git a/Lib/test/test_ntpath.py b/Lib/test/test_ntpath.py index 2f0faf94726..e0ec4419852 100644 --- a/Lib/test/test_ntpath.py +++ b/Lib/test/test_ntpath.py @@ -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 index 00000000000..56e0f565055 --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2019-10-02-15-38-49.bpo-38355.n3AWX6.rst @@ -0,0 +1 @@ +Fixes ``ntpath.realpath`` failing on ``sys.executable``.