From df0b37f6919851c1931d3bcb7ee1bee0255e59e7 Mon Sep 17 00:00:00 2001 From: Nineteendo Date: Sun, 2 Jun 2024 13:46:02 +0200 Subject: [PATCH 01/12] `ntpath.abspath()` always return absolute path --- Lib/ntpath.py | 48 +++++++++++++++++++++++++---------------- Lib/test/test_ntpath.py | 3 +++ 2 files changed, 33 insertions(+), 18 deletions(-) diff --git a/Lib/ntpath.py b/Lib/ntpath.py index 83e2d3b865757c..2836cbd6314d67 100644 --- a/Lib/ntpath.py +++ b/Lib/ntpath.py @@ -554,28 +554,21 @@ def normpath(path): return prefix + sep.join(comps) -def _abspath_fallback(path): - """Return the absolute version of a path as a fallback function in case - `nt._getfullpathname` is not available or raises OSError. See bpo-31047 for - more. - - """ - - path = os.fspath(path) - if not isabs(path): - if isinstance(path, bytes): - cwd = os.getcwdb() - else: - cwd = os.getcwd() - path = join(cwd, path) - return normpath(path) - # Return an absolute path. try: from nt import _getfullpathname except ImportError: # not running on Windows - mock up something sensible - abspath = _abspath_fallback + def abspath(path): + """Return the absolute version of a path.""" + path = os.fspath(path) + if not isabs(path): + if isinstance(path, bytes): + cwd = os.getcwdb() + else: + cwd = os.getcwd() + path = join(cwd, path) + return normpath(path) else: # use native Windows method on Windows def abspath(path): @@ -583,7 +576,26 @@ def abspath(path): try: return _getfullpathname(normpath(path)) except (OSError, ValueError): - return _abspath_fallback(path) + # See gh-75230, handle outside for cleaner traceback + pass + path = os.fspath(path) + if not isabs(path): + if isinstance(path, bytes): + sep = b'/' + cwd = os.getcwdb() + else: + sep = '/' + cwd = os.getcwd() + drive, root, path = splitroot(path) + if drive and drive != splitroot(cwd)[0]: + try: + path = join(_getfullpathname(drive), path) + except (OSError, ValueError): + # Invalid drive \x00: on Windows; assume root directory + path = drive + sep + path + else: + path = join(cwd, root + path) + return normpath(path) try: from nt import _findfirstfile, _getfinalpathname, readlink as _nt_readlink diff --git a/Lib/test/test_ntpath.py b/Lib/test/test_ntpath.py index 64cbfaaaaa0690..0ad11d1ccc7c7d 100644 --- a/Lib/test/test_ntpath.py +++ b/Lib/test/test_ntpath.py @@ -806,6 +806,9 @@ def test_abspath(self): tester('ntpath.abspath("C:\\spam. . .")', "C:\\spam") tester('ntpath.abspath("C:/nul")', "\\\\.\\nul") tester('ntpath.abspath("C:\\nul")', "\\\\.\\nul") + self.assertTrue(ntpath.isabs(ntpath.abspath("C:spam"))) + self.assertTrue(ntpath.isabs(ntpath.abspath("C:\x00"))) + self.assertTrue(ntpath.isabs(ntpath.abspath("\x00:spam"))) tester('ntpath.abspath("//..")', "\\\\") tester('ntpath.abspath("//../")', "\\\\..\\") tester('ntpath.abspath("//../..")', "\\\\..\\") From 53b3e41702d1ae94a923c8dd3989013cd6462d7e Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Sun, 2 Jun 2024 11:48:21 +0000 Subject: [PATCH 02/12] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20b?= =?UTF-8?q?lurb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../2024-06-02-11-48-19.gh-issue-119826.N1obGa.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-06-02-11-48-19.gh-issue-119826.N1obGa.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-06-02-11-48-19.gh-issue-119826.N1obGa.rst b/Misc/NEWS.d/next/Core and Builtins/2024-06-02-11-48-19.gh-issue-119826.N1obGa.rst new file mode 100644 index 00000000000000..6901e7475dd082 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2024-06-02-11-48-19.gh-issue-119826.N1obGa.rst @@ -0,0 +1 @@ +Always return an absolute path for :func:`os.path.abspath` on Windows. From 4a26721809d2f4ec5a15db55f105281133c00f7f Mon Sep 17 00:00:00 2001 From: Nice Zombies Date: Sun, 2 Jun 2024 14:27:19 +0200 Subject: [PATCH 03/12] Update Lib/ntpath.py Co-authored-by: Eryk Sun --- Lib/ntpath.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/ntpath.py b/Lib/ntpath.py index 2836cbd6314d67..9e54b97749c291 100644 --- a/Lib/ntpath.py +++ b/Lib/ntpath.py @@ -581,7 +581,7 @@ def abspath(path): path = os.fspath(path) if not isabs(path): if isinstance(path, bytes): - sep = b'/' + sep = b'\\' cwd = os.getcwdb() else: sep = '/' From d2b45fe8fad57d979a6650787765f416d8e300a1 Mon Sep 17 00:00:00 2001 From: Nice Zombies Date: Sun, 2 Jun 2024 14:27:24 +0200 Subject: [PATCH 04/12] Update Lib/ntpath.py Co-authored-by: Eryk Sun --- Lib/ntpath.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/ntpath.py b/Lib/ntpath.py index 9e54b97749c291..93bcad5c47f63a 100644 --- a/Lib/ntpath.py +++ b/Lib/ntpath.py @@ -584,7 +584,7 @@ def abspath(path): sep = b'\\' cwd = os.getcwdb() else: - sep = '/' + sep = '\\' cwd = os.getcwd() drive, root, path = splitroot(path) if drive and drive != splitroot(cwd)[0]: From 340cc07452ce7a6b89a886bec0362231d27ae7e5 Mon Sep 17 00:00:00 2001 From: Nice Zombies Date: Sun, 2 Jun 2024 23:14:10 +0200 Subject: [PATCH 05/12] Test for correct sep --- Lib/test/test_ntpath.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/test_ntpath.py b/Lib/test/test_ntpath.py index 0ad11d1ccc7c7d..48fff2bba24209 100644 --- a/Lib/test/test_ntpath.py +++ b/Lib/test/test_ntpath.py @@ -808,7 +808,7 @@ def test_abspath(self): tester('ntpath.abspath("C:\\nul")', "\\\\.\\nul") self.assertTrue(ntpath.isabs(ntpath.abspath("C:spam"))) self.assertTrue(ntpath.isabs(ntpath.abspath("C:\x00"))) - self.assertTrue(ntpath.isabs(ntpath.abspath("\x00:spam"))) + self.assertEqual(ntpath.abspath("\x00:spam"), "\x00:\\spam") tester('ntpath.abspath("//..")', "\\\\") tester('ntpath.abspath("//../")', "\\\\..\\") tester('ntpath.abspath("//../..")', "\\\\..\\") From abdb8d8b60d903e9f0065a09ca15ddbca1421bab Mon Sep 17 00:00:00 2001 From: Nineteendo Date: Sun, 2 Jun 2024 23:22:31 +0200 Subject: [PATCH 06/12] Revert "Test for correct sep" This reverts commit 340cc07452ce7a6b89a886bec0362231d27ae7e5. --- Lib/test/test_ntpath.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/test_ntpath.py b/Lib/test/test_ntpath.py index 48fff2bba24209..0ad11d1ccc7c7d 100644 --- a/Lib/test/test_ntpath.py +++ b/Lib/test/test_ntpath.py @@ -808,7 +808,7 @@ def test_abspath(self): tester('ntpath.abspath("C:\\nul")', "\\\\.\\nul") self.assertTrue(ntpath.isabs(ntpath.abspath("C:spam"))) self.assertTrue(ntpath.isabs(ntpath.abspath("C:\x00"))) - self.assertEqual(ntpath.abspath("\x00:spam"), "\x00:\\spam") + self.assertTrue(ntpath.isabs(ntpath.abspath("\x00:spam"))) tester('ntpath.abspath("//..")', "\\\\") tester('ntpath.abspath("//../")', "\\\\..\\") tester('ntpath.abspath("//../..")', "\\\\..\\") From f46b0cc1eaedaad3e9e15d2da43cc712886b75b0 Mon Sep 17 00:00:00 2001 From: Nineteendo Date: Sun, 2 Jun 2024 23:26:47 +0200 Subject: [PATCH 07/12] Revert "Revert "Test for correct sep"" This reverts commit abdb8d8b60d903e9f0065a09ca15ddbca1421bab. --- Lib/test/test_ntpath.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/test_ntpath.py b/Lib/test/test_ntpath.py index 0ad11d1ccc7c7d..48fff2bba24209 100644 --- a/Lib/test/test_ntpath.py +++ b/Lib/test/test_ntpath.py @@ -808,7 +808,7 @@ def test_abspath(self): tester('ntpath.abspath("C:\\nul")', "\\\\.\\nul") self.assertTrue(ntpath.isabs(ntpath.abspath("C:spam"))) self.assertTrue(ntpath.isabs(ntpath.abspath("C:\x00"))) - self.assertTrue(ntpath.isabs(ntpath.abspath("\x00:spam"))) + self.assertEqual(ntpath.abspath("\x00:spam"), "\x00:\\spam") tester('ntpath.abspath("//..")', "\\\\") tester('ntpath.abspath("//../")', "\\\\..\\") tester('ntpath.abspath("//../..")', "\\\\..\\") From 6790a15c2e999db28674463138dec7f1a9607c7a Mon Sep 17 00:00:00 2001 From: Nice Zombies Date: Sun, 2 Jun 2024 23:35:13 +0200 Subject: [PATCH 08/12] Stricter test --- Lib/test/test_ntpath.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/test_ntpath.py b/Lib/test/test_ntpath.py index 48fff2bba24209..cc035f68bbb68d 100644 --- a/Lib/test/test_ntpath.py +++ b/Lib/test/test_ntpath.py @@ -807,7 +807,7 @@ def test_abspath(self): tester('ntpath.abspath("C:/nul")', "\\\\.\\nul") tester('ntpath.abspath("C:\\nul")', "\\\\.\\nul") self.assertTrue(ntpath.isabs(ntpath.abspath("C:spam"))) - self.assertTrue(ntpath.isabs(ntpath.abspath("C:\x00"))) + self.assertEqual(ntpath.abspath("C:\x00"), ntpath.join(ntpath.abspath("C:"), "spam")) self.assertEqual(ntpath.abspath("\x00:spam"), "\x00:\\spam") tester('ntpath.abspath("//..")', "\\\\") tester('ntpath.abspath("//../")', "\\\\..\\") From 68bb224e24d56385941df0829186edbc1619ddf5 Mon Sep 17 00:00:00 2001 From: Nice Zombies Date: Sun, 2 Jun 2024 23:35:53 +0200 Subject: [PATCH 09/12] Fix test --- Lib/test/test_ntpath.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/test_ntpath.py b/Lib/test/test_ntpath.py index cc035f68bbb68d..4f59184dfcfdc7 100644 --- a/Lib/test/test_ntpath.py +++ b/Lib/test/test_ntpath.py @@ -807,7 +807,7 @@ def test_abspath(self): tester('ntpath.abspath("C:/nul")', "\\\\.\\nul") tester('ntpath.abspath("C:\\nul")', "\\\\.\\nul") self.assertTrue(ntpath.isabs(ntpath.abspath("C:spam"))) - self.assertEqual(ntpath.abspath("C:\x00"), ntpath.join(ntpath.abspath("C:"), "spam")) + self.assertEqual(ntpath.abspath("C:\x00"), ntpath.join(ntpath.abspath("C:"), "\x00")) self.assertEqual(ntpath.abspath("\x00:spam"), "\x00:\\spam") tester('ntpath.abspath("//..")', "\\\\") tester('ntpath.abspath("//../")', "\\\\..\\") From bcc160e8089a86ac7be20e52338e53281542685f Mon Sep 17 00:00:00 2001 From: Nice Zombies Date: Mon, 3 Jun 2024 08:34:37 +0200 Subject: [PATCH 10/12] Update Lib/ntpath.py Co-authored-by: Eryk Sun --- Lib/ntpath.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Lib/ntpath.py b/Lib/ntpath.py index 93bcad5c47f63a..f7f505f07b7592 100644 --- a/Lib/ntpath.py +++ b/Lib/ntpath.py @@ -580,21 +580,21 @@ def abspath(path): pass path = os.fspath(path) if not isabs(path): - if isinstance(path, bytes): + if is_bytes := isinstance(path, bytes): sep = b'\\' - cwd = os.getcwdb() else: sep = '\\' - cwd = os.getcwd() drive, root, path = splitroot(path) - if drive and drive != splitroot(cwd)[0]: + # Either drive or root can be nonempty, but not both. + if drive or root: try: - path = join(_getfullpathname(drive), path) + path = join(_getfullpathname(drive + root), path) except (OSError, ValueError): - # Invalid drive \x00: on Windows; assume root directory + # Drive "\0:" cannot exist; use the root directory. path = drive + sep + path else: - path = join(cwd, root + path) + cwd = os.getcwdb() if is_bytes else os.getcwd() + path = join(cwd, path) return normpath(path) try: From b769371ea591f08c8537016c600691d9ba6c2fb2 Mon Sep 17 00:00:00 2001 From: Nineteendo Date: Mon, 3 Jun 2024 08:39:13 +0200 Subject: [PATCH 11/12] Store reference to function --- Lib/ntpath.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Lib/ntpath.py b/Lib/ntpath.py index f7f505f07b7592..125eaf05c872e3 100644 --- a/Lib/ntpath.py +++ b/Lib/ntpath.py @@ -580,10 +580,12 @@ def abspath(path): pass path = os.fspath(path) if not isabs(path): - if is_bytes := isinstance(path, bytes): + if isinstance(path, bytes): sep = b'\\' + getcwd = os.getcwdb else: sep = '\\' + getcwd = os.getcwd drive, root, path = splitroot(path) # Either drive or root can be nonempty, but not both. if drive or root: @@ -593,8 +595,7 @@ def abspath(path): # Drive "\0:" cannot exist; use the root directory. path = drive + sep + path else: - cwd = os.getcwdb() if is_bytes else os.getcwd() - path = join(cwd, path) + path = join(getcwd(), path) return normpath(path) try: From 9581f8345f856eeb1a404176a64661797338cbed Mon Sep 17 00:00:00 2001 From: Nice Zombies Date: Wed, 19 Jun 2024 13:23:01 +0200 Subject: [PATCH 12/12] Rename 2024-06-02-11-48-19.gh-issue-119826.N1obGa.rst to 2024-06-02-11-48-19.gh-issue-119826.N1obGa.rst --- .../2024-06-02-11-48-19.gh-issue-119826.N1obGa.rst | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Misc/NEWS.d/next/{Core and Builtins => Library}/2024-06-02-11-48-19.gh-issue-119826.N1obGa.rst (100%) diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-06-02-11-48-19.gh-issue-119826.N1obGa.rst b/Misc/NEWS.d/next/Library/2024-06-02-11-48-19.gh-issue-119826.N1obGa.rst similarity index 100% rename from Misc/NEWS.d/next/Core and Builtins/2024-06-02-11-48-19.gh-issue-119826.N1obGa.rst rename to Misc/NEWS.d/next/Library/2024-06-02-11-48-19.gh-issue-119826.N1obGa.rst