codekingpro/portable-devtools
114k
1"""Convert a NT pathname to a file URL and vice versa.2 3This module only exists to provide OS-specific code4for urllib.requests, thus do not use directly.5"""6# Testing is done through test_nturl2path.7 8import warnings9 10 11warnings._deprecated(12 __name__,13 message=f"{warnings._DEPRECATED_MSG}; use 'urllib.request' instead",14 remove=(3, 19))15 16def url2pathname(url):17 """OS-specific conversion from a relative URL of the 'file' scheme18 to a file system path; not recommended for general use."""19 # e.g.20 # ///C|/foo/bar/spam.foo21 # and22 # ///C:/foo/bar/spam.foo23 # become24 # C:\foo\bar\spam.foo25 import urllib.parse26 if url[:3] == '///':27 # URL has an empty authority section, so the path begins on the third28 # character.29 url = url[2:]30 elif url[:12] == '//localhost/':31 # Skip past 'localhost' authority.32 url = url[11:]33 if url[:3] == '///':34 # Skip past extra slash before UNC drive in URL path.35 url = url[1:]36 else:37 if url[:1] == '/' and url[2:3] in (':', '|'):38 # Skip past extra slash before DOS drive in URL path.39 url = url[1:]40 if url[1:2] == '|':41 # Older URLs use a pipe after a drive letter42 url = url[:1] + ':' + url[2:]43 return urllib.parse.unquote(url.replace('/', '\\'))44 45def pathname2url(p):46 """OS-specific conversion from a file system path to a relative URL47 of the 'file' scheme; not recommended for general use."""48 # e.g.49 # C:\foo\bar\spam.foo50 # becomes51 # ///C:/foo/bar/spam.foo52 import ntpath53 import urllib.parse54 # First, clean up some special forms. We are going to sacrifice55 # the additional information anyway56 p = p.replace('\\', '/')57 if p[:4] == '//?/':58 p = p[4:]59 if p[:4].upper() == 'UNC/':60 p = '//' + p[4:]61 drive, root, tail = ntpath.splitroot(p)62 if drive:63 if drive[1:] == ':':64 # DOS drive specified. Add three slashes to the start, producing65 # an authority section with a zero-length authority, and a path66 # section starting with a single slash.67 drive = f'///{drive}'68 drive = urllib.parse.quote(drive, safe='/:')69 elif root:70 # Add explicitly empty authority to path beginning with one slash.71 root = f'//{root}'72 73 tail = urllib.parse.quote(tail)74 return drive + root + tail75 