GH-127236: pathname2url(): generate RFC 1738 URL for absolute POSIX path (#127194)

When handed an absolute Windows path such as `C:\foo` or `//server/share`,
the `urllib.request.pathname2url()` function returns a URL with an
authority section, such as `///C:/foo` or `//server/share` (or before
GH-126205, `////server/share`). Only the `file:` prefix is omitted.

But when handed an absolute POSIX path such as `/etc/hosts`, or a Windows
path of the same form (rooted but lacking a drive), the function returns a
URL without an authority section, such as `/etc/hosts`.

This patch corrects the discrepancy by adding a `//` prefix before
drive-less, rooted paths when generating URLs.
This commit is contained in:
Barney Gale 2024-11-25 19:59:20 +00:00 committed by GitHub
parent a2ee899682
commit 5bb059fe60
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 33 additions and 20 deletions

View file

@ -55,13 +55,17 @@ def pathname2url(p):
p = p[4:]
if p[:4].upper() == 'UNC/':
p = '//' + p[4:]
drive, tail = ntpath.splitdrive(p)
if drive[1:] == ':':
# DOS drive specified. Add three slashes to the start, producing
# an authority section with a zero-length authority, and a path
# section starting with a single slash.
drive = f'///{drive}'
drive, root, tail = ntpath.splitroot(p)
if drive:
if drive[1:] == ':':
# DOS drive specified. Add three slashes to the start, producing
# an authority section with a zero-length authority, and a path
# section starting with a single slash.
drive = f'///{drive}'
drive = urllib.parse.quote(drive, safe='/:')
elif root:
# Add explicitly empty authority to path beginning with one slash.
root = f'//{root}'
drive = urllib.parse.quote(drive, safe='/:')
tail = urllib.parse.quote(tail)
return drive + tail
return drive + root + tail