Skip to content

Commit 80b2d60

Browse files
authored
GH-136874: url2pathname(): discard query and fragment components (#136875)
In `urllib.request.url2pathname()`, ignore any query or fragment components in the given URL.
1 parent 4b68289 commit 80b2d60

File tree

5 files changed

+18
-5
lines changed

5 files changed

+18
-5
lines changed

Doc/library/urllib.request.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,9 @@ The :mod:`urllib.request` module defines the following functions:
210210
Windows a UNC path is returned (as before), and on other platforms a
211211
:exc:`~urllib.error.URLError` is raised.
212212

213+
.. versionchanged:: 3.14
214+
The URL query and fragment components are discarded if present.
215+
213216
.. versionchanged:: 3.14
214217
The *require_scheme* and *resolve_host* parameters were added.
215218

Doc/whatsnew/3.14.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2192,6 +2192,7 @@ urllib
21922192
- Discard URL authority if it matches the local hostname.
21932193
- Discard URL authority if it resolves to a local IP address when the new
21942194
*resolve_host* argument is set to true.
2195+
- Discard URL query and fragment components.
21952196
- Raise :exc:`~urllib.error.URLError` if a URL authority isn't local,
21962197
except on Windows where we return a UNC path as before.
21972198

Lib/test/test_urllib.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1526,6 +1526,14 @@ def test_url2pathname(self):
15261526
self.assertEqual(fn('////foo/bar'), f'{sep}{sep}foo{sep}bar')
15271527
self.assertEqual(fn('data:blah'), 'data:blah')
15281528
self.assertEqual(fn('data://blah'), f'data:{sep}{sep}blah')
1529+
self.assertEqual(fn('foo?bar'), 'foo')
1530+
self.assertEqual(fn('foo#bar'), 'foo')
1531+
self.assertEqual(fn('foo?bar=baz'), 'foo')
1532+
self.assertEqual(fn('foo?bar#baz'), 'foo')
1533+
self.assertEqual(fn('foo%3Fbar'), 'foo?bar')
1534+
self.assertEqual(fn('foo%23bar'), 'foo#bar')
1535+
self.assertEqual(fn('foo%3Fbar%3Dbaz'), 'foo?bar=baz')
1536+
self.assertEqual(fn('foo%3Fbar%23baz'), 'foo?bar#baz')
15291537

15301538
def test_url2pathname_require_scheme(self):
15311539
sep = os.path.sep

Lib/urllib/request.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1654,11 +1654,11 @@ def url2pathname(url, *, require_scheme=False, resolve_host=False):
16541654
The URL authority may be resolved with gethostbyname() if
16551655
*resolve_host* is set to true.
16561656
"""
1657-
if require_scheme:
1658-
scheme, url = _splittype(url)
1659-
if scheme != 'file':
1660-
raise URLError("URL is missing a 'file:' scheme")
1661-
authority, url = _splithost(url)
1657+
if not require_scheme:
1658+
url = 'file:' + url
1659+
scheme, authority, url = urlsplit(url)[:3] # Discard query and fragment.
1660+
if scheme != 'file':
1661+
raise URLError("URL is missing a 'file:' scheme")
16621662
if os.name == 'nt':
16631663
if not _is_local_authority(authority, resolve_host):
16641664
# e.g. file://server/share/file.txt
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Discard URL query and fragment in :func:`urllib.request.url2pathname`.

0 commit comments

Comments
 (0)