summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Lib/nturl2path.py7
-rw-r--r--Lib/test/test_urllib.py10
-rw-r--r--Lib/urllib/request.py4
-rw-r--r--Misc/NEWS.d/next/Library/2024-11-12-21-43-12.gh-issue-126766.oi2KJ7.rst2
4 files changed, 14 insertions, 9 deletions
diff --git a/Lib/nturl2path.py b/Lib/nturl2path.py
index 9ecabff..255eb2f 100644
--- a/Lib/nturl2path.py
+++ b/Lib/nturl2path.py
@@ -19,10 +19,9 @@ def url2pathname(url):
url = url.replace(':', '|')
if not '|' in url:
# No drive specifier, just convert slashes
- if url[:4] == '////':
- # path is something like ////host/path/on/remote/host
- # convert this to \\host\path\on\remote\host
- # (notice halving of slashes at the start of the path)
+ if url[:3] == '///':
+ # URL has an empty authority section, so the path begins on the
+ # third character.
url = url[2:]
# make sure not to convert quoted slashes :-)
return urllib.parse.unquote(url.replace('/', '\\'))
diff --git a/Lib/test/test_urllib.py b/Lib/test/test_urllib.py
index 66e948f..2c53ce3 100644
--- a/Lib/test/test_urllib.py
+++ b/Lib/test/test_urllib.py
@@ -1549,7 +1549,7 @@ class Pathname_Tests(unittest.TestCase):
self.assertEqual(fn('//?/unc/server/share/dir'), '//server/share/dir')
# Round-tripping
urls = ['///C:',
- '///folder/test/',
+ '/folder/test/',
'///C:/foo/bar/spam.foo']
for url in urls:
self.assertEqual(fn(urllib.request.url2pathname(url)), url)
@@ -1573,7 +1573,7 @@ class Pathname_Tests(unittest.TestCase):
self.assertEqual(fn('/C|//'), 'C:\\\\')
self.assertEqual(fn('///C|/path'), 'C:\\path')
# No DOS drive
- self.assertEqual(fn("///C/test/"), '\\\\\\C\\test\\')
+ 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')
@@ -1597,7 +1597,7 @@ class Pathname_Tests(unittest.TestCase):
self.assertEqual(fn('//server/share/foo%2fbar'), '\\\\server\\share\\foo/bar')
# Round-tripping
paths = ['C:',
- r'\\\C\test\\',
+ r'\C\test\\',
r'C:\foo\bar\spam.foo']
for path in paths:
self.assertEqual(fn(urllib.request.pathname2url(path)), path)
@@ -1608,8 +1608,8 @@ class Pathname_Tests(unittest.TestCase):
fn = urllib.request.url2pathname
self.assertEqual(fn('/foo/bar'), '/foo/bar')
self.assertEqual(fn('//foo/bar'), '//foo/bar')
- self.assertEqual(fn('///foo/bar'), '///foo/bar')
- self.assertEqual(fn('////foo/bar'), '////foo/bar')
+ self.assertEqual(fn('///foo/bar'), '/foo/bar')
+ self.assertEqual(fn('////foo/bar'), '//foo/bar')
self.assertEqual(fn('//localhost/foo/bar'), '//localhost/foo/bar')
class Utility_Tests(unittest.TestCase):
diff --git a/Lib/urllib/request.py b/Lib/urllib/request.py
index bc35d8a..18a837d 100644
--- a/Lib/urllib/request.py
+++ b/Lib/urllib/request.py
@@ -1656,6 +1656,10 @@ else:
def url2pathname(pathname):
"""OS-specific conversion from a relative URL of the 'file' scheme
to a file system path; not recommended for general use."""
+ if pathname[:3] == '///':
+ # URL has an empty authority section, so the path begins on the
+ # third character.
+ pathname = pathname[2:]
return unquote(pathname)
def pathname2url(pathname):
diff --git a/Misc/NEWS.d/next/Library/2024-11-12-21-43-12.gh-issue-126766.oi2KJ7.rst b/Misc/NEWS.d/next/Library/2024-11-12-21-43-12.gh-issue-126766.oi2KJ7.rst
new file mode 100644
index 0000000..e393630
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2024-11-12-21-43-12.gh-issue-126766.oi2KJ7.rst
@@ -0,0 +1,2 @@
+Fix issue where :func:`urllib.request.url2pathname` failed to discard two
+leading slashes introducing an empty authority section.