https://github.com/python/cpython/commit/cc813e10ff190af38b8429d0d49fb9249493d504
commit: cc813e10ff190af38b8429d0d49fb9249493d504
branch: main
author: Barney Gale <[email protected]>
committer: barneygale <[email protected]>
date: 2024-11-23T10:41:39Z
summary:
GH-125866: Preserve Windows drive letter case in file URIs (#127138)
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.
files:
A Misc/NEWS.d/next/Library/2024-11-22-04-49-31.gh-issue-125866.TUtvPK.rst
M Doc/library/urllib.request.rst
M Lib/nturl2path.py
M Lib/test/test_urllib.py
diff --git a/Doc/library/urllib.request.rst b/Doc/library/urllib.request.rst
index e0831bf7e65ad2..a093a5083e037b 100644
--- a/Doc/library/urllib.request.rst
+++ b/Doc/library/urllib.request.rst
@@ -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
diff --git a/Lib/nturl2path.py b/Lib/nturl2path.py
index 66092e4821a0ec..01135d1b7683b2 100644
--- a/Lib/nturl2path.py
+++ b/Lib/nturl2path.py
@@ -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)
diff --git a/Lib/test/test_urllib.py b/Lib/test/test_urllib.py
index a204ef41c3ce90..22ef3c648e271d 100644
--- a/Lib/test/test_urllib.py
+++ b/Lib/test/test_urllib.py
@@ -1423,6 +1423,7 @@ def test_pathname2url_win(self):
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 @@ def test_url2pathname_win(self):
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
index 00000000000000..682e061747689b
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2024-11-22-04-49-31.gh-issue-125866.TUtvPK.rst
@@ -0,0 +1,2 @@
+:func:`urllib.request.pathname2url` and :func:`~urllib.request.url2pathname`
+no longer convert Windows drive letters to uppercase.
_______________________________________________
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]