https://github.com/python/cpython/commit/48eb5c978e6a47e9597b6bde57be13688354f3c8
commit: 48eb5c978e6a47e9597b6bde57be13688354f3c8
branch: 3.13
author: Miss Islington (bot) <[email protected]>
committer: zooba <[email protected]>
date: 2024-11-21T15:10:12Z
summary:

gh-126780: Fix `ntpath.normpath()` for drive-relative paths (GH-126801)

(cherry picked from commit 60ec854bc297e04718fe13db3605d0465bf8badb)

Co-authored-by: Nice Zombies <[email protected]>

files:
A Misc/NEWS.d/next/Library/2024-11-13-19-15-18.gh-issue-126780.ZZqJvI.rst
M Lib/test/test_ntpath.py
M Lib/test/test_posixpath.py
M Python/fileutils.c

diff --git a/Lib/test/test_ntpath.py b/Lib/test/test_ntpath.py
index 64cbfaaaaa0690..b3bd803028065f 100644
--- a/Lib/test/test_ntpath.py
+++ b/Lib/test/test_ntpath.py
@@ -347,13 +347,18 @@ def test_normpath(self):
 
         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 b39255ebc79ac1..43e4fbc610e5f7 100644
--- a/Lib/test/test_posixpath.py
+++ b/Lib/test/test_posixpath.py
@@ -379,6 +379,7 @@ def test_expanduser_pwd2(self):
         ("/.", "/"),
         ("/./", "/"),
         ("/.//.", "/"),
+        ("/./foo/bar", "/foo/bar"),
         ("/foo", "/foo"),
         ("/foo/bar", "/foo/bar"),
         ("//", "//"),
@@ -388,6 +389,7 @@ def test_expanduser_pwd2(self):
         ("///..//./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 00000000000000..93d45caf5cad72
--- /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 c9ae1b3f54e167..9529b14d377c60 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++;
         }
     }
 

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]

Reply via email to