From 77821dde25060940f4cec7c13981393bd80c1fcb Mon Sep 17 00:00:00 2001 From: Barney Gale Date: Mon, 21 Jul 2025 18:33:20 +0100 Subject: [PATCH] GH-136874: `url2pathname()`: discard query and fragment components (GH-136875) In `urllib.request.url2pathname()`, ignore any query or fragment components in the given URL. (cherry picked from commit 80b2d60a51cfd824d025eb8b3ec500acce5c010c) Co-authored-by: Barney Gale --- Doc/library/urllib.request.rst | 3 +++ Doc/whatsnew/3.14.rst | 1 + Lib/test/test_urllib.py | 8 ++++++++ Lib/urllib/request.py | 10 +++++----- .../2025-07-20-16-02-00.gh-issue-136874.cLC3o1.rst | 1 + 5 files changed, 18 insertions(+), 5 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2025-07-20-16-02-00.gh-issue-136874.cLC3o1.rst diff --git a/Doc/library/urllib.request.rst b/Doc/library/urllib.request.rst index 58bd111b5cc374..016bc777fbb232 100644 --- a/Doc/library/urllib.request.rst +++ b/Doc/library/urllib.request.rst @@ -210,6 +210,9 @@ The :mod:`urllib.request` module defines the following functions: Windows a UNC path is returned (as before), and on other platforms a :exc:`~urllib.error.URLError` is raised. + .. versionchanged:: 3.14 + The URL query and fragment components are discarded if present. + .. versionchanged:: 3.14 The *require_scheme* and *resolve_host* parameters were added. diff --git a/Doc/whatsnew/3.14.rst b/Doc/whatsnew/3.14.rst index d58f7ecf02ce6b..630d011ffbbd1f 100644 --- a/Doc/whatsnew/3.14.rst +++ b/Doc/whatsnew/3.14.rst @@ -2192,6 +2192,7 @@ urllib - Discard URL authority if it matches the local hostname. - Discard URL authority if it resolves to a local IP address when the new *resolve_host* argument is set to true. + - Discard URL query and fragment components. - Raise :exc:`~urllib.error.URLError` if a URL authority isn't local, except on Windows where we return a UNC path as before. diff --git a/Lib/test/test_urllib.py b/Lib/test/test_urllib.py index 1d889ae7cf458f..c30fb5e27eea8a 100644 --- a/Lib/test/test_urllib.py +++ b/Lib/test/test_urllib.py @@ -1526,6 +1526,14 @@ def test_url2pathname(self): self.assertEqual(fn('////foo/bar'), f'{sep}{sep}foo{sep}bar') self.assertEqual(fn('data:blah'), 'data:blah') self.assertEqual(fn('data://blah'), f'data:{sep}{sep}blah') + self.assertEqual(fn('foo?bar'), 'foo') + self.assertEqual(fn('foo#bar'), 'foo') + self.assertEqual(fn('foo?bar=baz'), 'foo') + self.assertEqual(fn('foo?bar#baz'), 'foo') + self.assertEqual(fn('foo%3Fbar'), 'foo?bar') + self.assertEqual(fn('foo%23bar'), 'foo#bar') + self.assertEqual(fn('foo%3Fbar%3Dbaz'), 'foo?bar=baz') + self.assertEqual(fn('foo%3Fbar%23baz'), 'foo?bar#baz') def test_url2pathname_require_scheme(self): sep = os.path.sep diff --git a/Lib/urllib/request.py b/Lib/urllib/request.py index 41dc5d7b35dedb..c1c373d08815c1 100644 --- a/Lib/urllib/request.py +++ b/Lib/urllib/request.py @@ -1654,11 +1654,11 @@ def url2pathname(url, *, require_scheme=False, resolve_host=False): The URL authority may be resolved with gethostbyname() if *resolve_host* is set to true. """ - if require_scheme: - scheme, url = _splittype(url) - if scheme != 'file': - raise URLError("URL is missing a 'file:' scheme") - authority, url = _splithost(url) + if not require_scheme: + url = 'file:' + url + scheme, authority, url = urlsplit(url)[:3] # Discard query and fragment. + if scheme != 'file': + raise URLError("URL is missing a 'file:' scheme") if os.name == 'nt': if not _is_local_authority(authority, resolve_host): # e.g. file://server/share/file.txt diff --git a/Misc/NEWS.d/next/Library/2025-07-20-16-02-00.gh-issue-136874.cLC3o1.rst b/Misc/NEWS.d/next/Library/2025-07-20-16-02-00.gh-issue-136874.cLC3o1.rst new file mode 100644 index 00000000000000..9a71eb8ef1ac8d --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-07-20-16-02-00.gh-issue-136874.cLC3o1.rst @@ -0,0 +1 @@ +Discard URL query and fragment in :func:`urllib.request.url2pathname`. pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy