mirror of
https://github.com/python/cpython.git
synced 2025-10-15 03:10:29 +00:00
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.
This commit is contained in:
parent
a13e94d84b
commit
cc813e10ff
4 changed files with 13 additions and 2 deletions
|
@ -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
|
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.
|
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
|
.. versionchanged:: 3.14
|
||||||
On Windows, ``:`` characters not following a drive letter are quoted. In
|
On Windows, ``:`` characters not following a drive letter are quoted. In
|
||||||
previous versions, :exc:`OSError` was raised if a colon character was
|
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
|
path. This does not accept a complete URL. This function uses
|
||||||
:func:`~urllib.parse.unquote` to decode *path*.
|
:func:`~urllib.parse.unquote` to decode *path*.
|
||||||
|
|
||||||
|
.. versionchanged:: 3.14
|
||||||
|
Windows drive letters are no longer converted to uppercase.
|
||||||
|
|
||||||
|
|
||||||
.. function:: getproxies()
|
.. function:: getproxies()
|
||||||
|
|
||||||
This helper function returns a dictionary of scheme to proxy server URL
|
This helper function returns a dictionary of scheme to proxy server URL
|
||||||
|
|
|
@ -35,7 +35,7 @@ def url2pathname(url):
|
||||||
if len(comp) != 2 or comp[0][-1] not in string.ascii_letters:
|
if len(comp) != 2 or comp[0][-1] not in string.ascii_letters:
|
||||||
error = 'Bad URL: ' + url
|
error = 'Bad URL: ' + url
|
||||||
raise OSError(error)
|
raise OSError(error)
|
||||||
drive = comp[0][-1].upper()
|
drive = comp[0][-1]
|
||||||
tail = urllib.parse.unquote(comp[1].replace('/', '\\'))
|
tail = urllib.parse.unquote(comp[1].replace('/', '\\'))
|
||||||
return drive + ':' + tail
|
return drive + ':' + tail
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ def pathname2url(p):
|
||||||
# DOS drive specified. Add three slashes to the start, producing
|
# DOS drive specified. Add three slashes to the start, producing
|
||||||
# an authority section with a zero-length authority, and a path
|
# an authority section with a zero-length authority, and a path
|
||||||
# section starting with a single slash.
|
# section starting with a single slash.
|
||||||
drive = f'///{drive.upper()}'
|
drive = f'///{drive}'
|
||||||
|
|
||||||
drive = urllib.parse.quote(drive, safe='/:')
|
drive = urllib.parse.quote(drive, safe='/:')
|
||||||
tail = urllib.parse.quote(tail)
|
tail = urllib.parse.quote(tail)
|
||||||
|
|
|
@ -1423,6 +1423,7 @@ class Pathname_Tests(unittest.TestCase):
|
||||||
self.assertEqual(fn('\\\\?\\unc\\server\\share\\dir'), '//server/share/dir')
|
self.assertEqual(fn('\\\\?\\unc\\server\\share\\dir'), '//server/share/dir')
|
||||||
self.assertEqual(fn("C:"), '///C:')
|
self.assertEqual(fn("C:"), '///C:')
|
||||||
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/')
|
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\\')
|
||||||
self.assertEqual(fn("////C/test/"), '\\\\C\\test\\')
|
self.assertEqual(fn("////C/test/"), '\\\\C\\test\\')
|
||||||
# DOS drive paths
|
# 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\\')
|
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')
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
:func:`urllib.request.pathname2url` and :func:`~urllib.request.url2pathname`
|
||||||
|
no longer convert Windows drive letters to uppercase.
|
Loading…
Add table
Add a link
Reference in a new issue