summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNice Zombies <nineteendo19d0@gmail.com>2024-11-21 14:43:36 (GMT)
committerGitHub <noreply@github.com>2024-11-21 14:43:36 (GMT)
commit60ec854bc297e04718fe13db3605d0465bf8badb (patch)
tree98e06da03433b3e10b0ad9ac181bded4cbd6ba48
parent0c5556fcb7315f26aa4b192e341cb2a72bb78f41 (diff)
downloadcpython-60ec854bc297e04718fe13db3605d0465bf8badb.zip
cpython-60ec854bc297e04718fe13db3605d0465bf8badb.tar.gz
cpython-60ec854bc297e04718fe13db3605d0465bf8badb.tar.bz2
gh-126780: Fix `ntpath.normpath()` for drive-relative paths (GH-126801)
-rw-r--r--Lib/test/test_ntpath.py5
-rw-r--r--Lib/test/test_posixpath.py2
-rw-r--r--Misc/NEWS.d/next/Library/2024-11-13-19-15-18.gh-issue-126780.ZZqJvI.rst1
-rw-r--r--Python/fileutils.c51
4 files changed, 34 insertions, 25 deletions
diff --git a/Lib/test/test_ntpath.py b/Lib/test/test_ntpath.py
index 4f59184..6715071 100644
--- a/Lib/test/test_ntpath.py
+++ b/Lib/test/test_ntpath.py
@@ -347,13 +347,18 @@ class TestNtpath(NtpathTestCase):
tester("ntpath.normpath('..')", r'..')
tester("ntpath.normpath('.')", r'.')
+ tester("ntpath.normpath('c:.')", 'c:')
tester("ntpath.normpath('')", r'.')
tester("ntpath.normpath('/')", '\\')
tester("ntpath.normpath('c:/')", 'c:\\')
tester("ntpath.normpath('/../.././..')", '\\')
tester("ntpath.normpath('c:/../../..')", 'c:\\')
+ tester("ntpath.normpath('/./a/b')", r'\a\b')
+ tester("ntpath.normpath('c:/./a/b')", r'c:\a\b')
tester("ntpath.normpath('../.././..')", r'..\..\..')
tester("ntpath.normpath('K:../.././..')", r'K:..\..\..')
+ tester("ntpath.normpath('./a/b')", r'a\b')
+ tester("ntpath.normpath('c:./a/b')", r'c:a\b')
tester("ntpath.normpath('C:////a/b')", r'C:\a\b')
tester("ntpath.normpath('//machine/share//a/b')", r'\\machine\share\a\b')
diff --git a/Lib/test/test_posixpath.py b/Lib/test/test_posixpath.py
index b39255eb..43e4fbc 100644
--- a/Lib/test/test_posixpath.py
+++ b/Lib/test/test_posixpath.py
@@ -379,6 +379,7 @@ class PosixPathTest(unittest.TestCase):
("/.", "/"),
("/./", "/"),
("/.//.", "/"),
+ ("/./foo/bar", "/foo/bar"),
("/foo", "/foo"),
("/foo/bar", "/foo/bar"),
("//", "//"),
@@ -388,6 +389,7 @@ class PosixPathTest(unittest.TestCase):
("///..//./foo/.//bar", "/foo/bar"),
(".", "."),
(".//.", "."),
+ ("./foo/bar", "foo/bar"),
("..", ".."),
("../", ".."),
("../foo", "../foo"),
diff --git a/Misc/NEWS.d/next/Library/2024-11-13-19-15-18.gh-issue-126780.ZZqJvI.rst b/Misc/NEWS.d/next/Library/2024-11-13-19-15-18.gh-issue-126780.ZZqJvI.rst
new file mode 100644
index 0000000..93d45ca
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2024-11-13-19-15-18.gh-issue-126780.ZZqJvI.rst
@@ -0,0 +1 @@
+Fix :func:`os.path.normpath` for drive-relative paths on Windows.
diff --git a/Python/fileutils.c b/Python/fileutils.c
index c9ae1b3..9529b14 100644
--- a/Python/fileutils.c
+++ b/Python/fileutils.c
@@ -2506,37 +2506,38 @@ _Py_normpath_and_size(wchar_t *path, Py_ssize_t size, Py_ssize_t *normsize)
#endif
#define SEP_OR_END(x) (IS_SEP(x) || IS_END(x))
- if (p1[0] == L'.' && IS_SEP(&p1[1])) {
- // Skip leading '.\'
- path = &path[2];
- while (IS_SEP(path)) {
- path++;
- }
- p1 = p2 = minP2 = path;
- lastC = SEP;
- }
- else {
- Py_ssize_t drvsize, rootsize;
- _Py_skiproot(path, size, &drvsize, &rootsize);
- if (drvsize || rootsize) {
- // Skip past root and update minP2
- p1 = &path[drvsize + rootsize];
+ Py_ssize_t drvsize, rootsize;
+ _Py_skiproot(path, size, &drvsize, &rootsize);
+ if (drvsize || rootsize) {
+ // Skip past root and update minP2
+ p1 = &path[drvsize + rootsize];
#ifndef ALTSEP
- p2 = p1;
+ p2 = p1;
#else
- for (; p2 < p1; ++p2) {
- if (*p2 == ALTSEP) {
- *p2 = SEP;
- }
+ for (; p2 < p1; ++p2) {
+ if (*p2 == ALTSEP) {
+ *p2 = SEP;
}
+ }
#endif
- minP2 = p2 - 1;
- lastC = *minP2;
+ minP2 = p2 - 1;
+ lastC = *minP2;
#ifdef MS_WINDOWS
- if (lastC != SEP) {
- minP2++;
- }
+ if (lastC != SEP) {
+ minP2++;
+ }
+#endif
+ }
+ if (p1[0] == L'.' && SEP_OR_END(&p1[1])) {
+ // Skip leading '.\'
+ lastC = *++p1;
+#ifdef ALTSEP
+ if (lastC == ALTSEP) {
+ lastC = SEP;
+ }
#endif
+ while (IS_SEP(p1)) {
+ p1++;
}
}