]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
GH-125866: Preserve Windows drive letter case in file URIs (#127138)
authorBarney Gale <barney.gale@gmail.com>
Sat, 23 Nov 2024 10:41:39 +0000 (10:41 +0000)
committerGitHub <noreply@github.com>
Sat, 23 Nov 2024 10:41:39 +0000 (10:41 +0000)
Stop converting Windows drive letters to uppercase in
`urllib.request.pathname2url()` and `url2pathname()`. This behaviour is
unnecessary and inconsistent with pathlib's file URI implementation.

Doc/library/urllib.request.rst
Lib/nturl2path.py
Lib/test/test_urllib.py
Misc/NEWS.d/next/Library/2024-11-22-04-49-31.gh-issue-125866.TUtvPK.rst [new file with mode: 0644]

index e0831bf7e65ad28f1da1dbfdda8f33862187ef1c..a093a5083e037b6611b5a0316a5f5ca3ce971c88 100644 (file)
@@ -152,6 +152,9 @@ The :mod:`urllib.request` module defines the following functions:
    the path component of a URL.  This does not produce a complete URL.  The return
    value will already be quoted using the :func:`~urllib.parse.quote` function.
 
+   .. versionchanged:: 3.14
+      Windows drive letters are no longer converted to uppercase.
+
    .. versionchanged:: 3.14
       On Windows, ``:`` characters not following a drive letter are quoted. In
       previous versions, :exc:`OSError` was raised if a colon character was
@@ -164,6 +167,10 @@ The :mod:`urllib.request` module defines the following functions:
    path.  This does not accept a complete URL.  This function uses
    :func:`~urllib.parse.unquote` to decode *path*.
 
+   .. versionchanged:: 3.14
+      Windows drive letters are no longer converted to uppercase.
+
+
 .. function:: getproxies()
 
    This helper function returns a dictionary of scheme to proxy server URL
index 66092e4821a0ec8eec6792c75d23514909a0545d..01135d1b7683b261ffccc10a98ed00576500ae7f 100644 (file)
@@ -35,7 +35,7 @@ def url2pathname(url):
     if len(comp) != 2 or comp[0][-1] not in string.ascii_letters:
         error = 'Bad URL: ' + url
         raise OSError(error)
-    drive = comp[0][-1].upper()
+    drive = comp[0][-1]
     tail = urllib.parse.unquote(comp[1].replace('/', '\\'))
     return drive + ':' + tail
 
@@ -60,7 +60,7 @@ def pathname2url(p):
         # DOS drive specified. Add three slashes to the start, producing
         # an authority section with a zero-length authority, and a path
         # section starting with a single slash.
-        drive = f'///{drive.upper()}'
+        drive = f'///{drive}'
 
     drive = urllib.parse.quote(drive, safe='/:')
     tail = urllib.parse.quote(tail)
index a204ef41c3ce90c5f902fb8ec539d688efdbf5a8..22ef3c648e271dcab5ad2ae4b6aeb45a6b12f9ec 100644 (file)
@@ -1423,6 +1423,7 @@ class Pathname_Tests(unittest.TestCase):
         self.assertEqual(fn('\\\\?\\unc\\server\\share\\dir'), '//server/share/dir')
         self.assertEqual(fn("C:"), '///C:')
         self.assertEqual(fn("C:\\"), '///C:/')
+        self.assertEqual(fn('c:\\a\\b.c'), '///c:/a/b.c')
         self.assertEqual(fn('C:\\a\\b.c'), '///C:/a/b.c')
         self.assertEqual(fn('C:\\a\\b.c\\'), '///C:/a/b.c/')
         self.assertEqual(fn('C:\\a\\\\b.c'), '///C:/a//b.c')
@@ -1480,6 +1481,7 @@ class Pathname_Tests(unittest.TestCase):
         self.assertEqual(fn("///C/test/"), '\\C\\test\\')
         self.assertEqual(fn("////C/test/"), '\\\\C\\test\\')
         # DOS drive paths
+        self.assertEqual(fn('c:/path/to/file'), 'c:\\path\\to\\file')
         self.assertEqual(fn('C:/path/to/file'), 'C:\\path\\to\\file')
         self.assertEqual(fn('C:/path/to/file/'), 'C:\\path\\to\\file\\')
         self.assertEqual(fn('C:/path/to//file'), 'C:\\path\\to\\\\file')
diff --git a/Misc/NEWS.d/next/Library/2024-11-22-04-49-31.gh-issue-125866.TUtvPK.rst b/Misc/NEWS.d/next/Library/2024-11-22-04-49-31.gh-issue-125866.TUtvPK.rst
new file mode 100644 (file)
index 0000000..682e061
--- /dev/null
@@ -0,0 +1,2 @@
+:func:`urllib.request.pathname2url` and :func:`~urllib.request.url2pathname`
+no longer convert Windows drive letters to uppercase.