1"""Macintosh-specific module for conversion between pathnames and URLs. 2 3Do not import directly; use urllib instead.""" 4 5import urllib.parse 6import os 7 8__all__ = ["url2pathname","pathname2url"] 9 10def url2pathname(pathname): 11 """OS-specific conversion from a relative URL of the 'file' scheme 12 to a file system path; not recommended for general use.""" 13 # 14 # XXXX The .. handling should be fixed... 15 # 16 tp = urllib.parse.splittype(pathname)[0] 17 if tp and tp != 'file': 18 raise RuntimeError('Cannot convert non-local URL to pathname') 19 # Turn starting /// into /, an empty hostname means current host 20 if pathname[:3] == '///': 21 pathname = pathname[2:] 22 elif pathname[:2] == '//': 23 raise RuntimeError('Cannot convert non-local URL to pathname') 24 components = pathname.split('/') 25 # Remove . and embedded .. 26 i = 0 27 while i < len(components): 28 if components[i] == '.': 29 del components[i] 30 elif components[i] == '..' and i > 0 and \ 31 components[i-1] not in ('', '..'): 32 del components[i-1:i+1] 33 i = i-1 34 elif components[i] == '' and i > 0 and components[i-1] != '': 35 del components[i] 36 else: 37 i = i+1 38 if not components[0]: 39 # Absolute unix path, don't start with colon 40 rv = ':'.join(components[1:]) 41 else: 42 # relative unix path, start with colon. First replace 43 # leading .. by empty strings (giving ::file) 44 i = 0 45 while i < len(components) and components[i] == '..': 46 components[i] = '' 47 i = i + 1 48 rv = ':' + ':'.join(components) 49 # and finally unquote slashes and other funny characters 50 return urllib.parse.unquote(rv) 51 52def pathname2url(pathname): 53 """OS-specific conversion from a file system path to a relative URL 54 of the 'file' scheme; not recommended for general use.""" 55 if '/' in pathname: 56 raise RuntimeError("Cannot convert pathname containing slashes") 57 components = pathname.split(':') 58 # Remove empty first and/or last component 59 if components[0] == '': 60 del components[0] 61 if components[-1] == '': 62 del components[-1] 63 # Replace empty string ('::') by .. (will result in '/../' later) 64 for i in range(len(components)): 65 if components[i] == '': 66 components[i] = '..' 67 # Truncate names longer than 31 bytes 68 components = map(_pncomp2url, components) 69 70 if os.path.isabs(pathname): 71 return '/' + '/'.join(components) 72 else: 73 return '/'.join(components) 74 75def _pncomp2url(component): 76 # We want to quote slashes 77 return urllib.parse.quote(component[:31], safe='') 78