]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
GH-136874: `url2pathname()`: discard query and fragment components (#136875)
authorBarney Gale <barney.gale@gmail.com>
Mon, 21 Jul 2025 17:33:20 +0000 (18:33 +0100)
committerGitHub <noreply@github.com>
Mon, 21 Jul 2025 17:33:20 +0000 (17:33 +0000)
In `urllib.request.url2pathname()`, ignore any query or fragment components
in the given URL.

Doc/library/urllib.request.rst
Doc/whatsnew/3.14.rst
Lib/test/test_urllib.py
Lib/urllib/request.py
Misc/NEWS.d/next/Library/2025-07-20-16-02-00.gh-issue-136874.cLC3o1.rst [new file with mode: 0644]

index 1e716715fd9bedc0cd8c82639fab122d609ebdb6..e514b98fc5d553abc8f7746dc68aee9090742b9f 100644 (file)
@@ -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.
 
index 91f8ccc796794bbc842be0170e6bebcc8d9254c6..6bdf4aee709ad3a95c7dda931fc5de1d5498602e 100644 (file)
@@ -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.
 
index 1d889ae7cf458f73a836b7e374145007b4e8ed78..c30fb5e27eea8aeb5c0cb24f42317c108cd9ab29 100644 (file)
@@ -1526,6 +1526,14 @@ class Pathname_Tests(unittest.TestCase):
         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
index 41dc5d7b35dedb494a72321de166ab38d1c19ff8..c1c373d08815c1dad0660d6322183938f1752b55 100644 (file)
@@ -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 (file)
index 0000000..9a71eb8
--- /dev/null
@@ -0,0 +1 @@
+Discard URL query and fragment in :func:`urllib.request.url2pathname`.