[Python-checkins] bpo-38355: Fix ntpath.realpath failing on sys.executable (GH-16551)

Miss Islington (bot) webhook-mailer at python.org
Thu Oct 3 11:50:00 EDT 2019


https://github.com/python/cpython/commit/6067e1d2bebccc2e73dd729d25c98df7bc9e2d59
commit: 6067e1d2bebccc2e73dd729d25c98df7bc9e2d59
branch: 3.8
author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com>
committer: GitHub <noreply at github.com>
date: 2019年10月03日T08:49:56-07:00
summary:
bpo-38355: Fix ntpath.realpath failing on sys.executable (GH-16551)
(cherry picked from commit a0e3d27e4e3cb5b67e325df080fb18b70c2910cf)
Co-authored-by: Steve Dower <steve.dower at python.org>
files:
A Misc/NEWS.d/next/Windows/2019-10-02-15-38-49.bpo-38355.n3AWX6.rst
M Lib/ntpath.py
M Lib/test/test_ntpath.py
diff --git a/Lib/ntpath.py b/Lib/ntpath.py
index 01f1f423c906c..d4ecff97c9528 100644
--- a/Lib/ntpath.py
+++ b/Lib/ntpath.py
@@ -560,13 +560,6 @@ def _readlink_deep(path, seen=None):
 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 @@ def _getfinalpathname_nonstrict(path):
 # 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 @@ def realpath(path):
 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 @@ def realpath(path):
 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 2f0faf94726fd..e0ec441985230 100644
--- a/Lib/test/test_ntpath.py
+++ b/Lib/test/test_ntpath.py
@@ -329,16 +329,14 @@ def test_realpath_symlink_loops(self):
 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 @@ def test_realpath_symlink_loops(self):
 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 0000000000000..56e0f56505522
--- /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``.


More information about the Python-checkins mailing list

AltStyle によって変換されたページ (->オリジナル) /