nturl2path.py 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. """Convert a NT pathname to a file URL and vice versa.
  2. This module only exists to provide OS-specific code
  3. for urllib.requests, thus do not use directly.
  4. """
  5. # Testing is done through test_urllib.
  6. def url2pathname(url):
  7. """OS-specific conversion from a relative URL of the 'file' scheme
  8. to a file system path; not recommended for general use."""
  9. # e.g.
  10. # ///C|/foo/bar/spam.foo
  11. # and
  12. # ///C:/foo/bar/spam.foo
  13. # become
  14. # C:\foo\bar\spam.foo
  15. import string, urllib.parse
  16. # Windows itself uses ":" even in URLs.
  17. url = url.replace(':', '|')
  18. if not '|' in url:
  19. # No drive specifier, just convert slashes
  20. if url[:4] == '////':
  21. # path is something like ////host/path/on/remote/host
  22. # convert this to \\host\path\on\remote\host
  23. # (notice halving of slashes at the start of the path)
  24. url = url[2:]
  25. components = url.split('/')
  26. # make sure not to convert quoted slashes :-)
  27. return urllib.parse.unquote('\\'.join(components))
  28. comp = url.split('|')
  29. if len(comp) != 2 or comp[0][-1] not in string.ascii_letters:
  30. error = 'Bad URL: ' + url
  31. raise OSError(error)
  32. drive = comp[0][-1].upper()
  33. components = comp[1].split('/')
  34. path = drive + ':'
  35. for comp in components:
  36. if comp:
  37. path = path + '\\' + urllib.parse.unquote(comp)
  38. # Issue #11474 - handing url such as |c/|
  39. if path.endswith(':') and url.endswith('/'):
  40. path += '\\'
  41. return path
  42. def pathname2url(p):
  43. """OS-specific conversion from a file system path to a relative URL
  44. of the 'file' scheme; not recommended for general use."""
  45. # e.g.
  46. # C:\foo\bar\spam.foo
  47. # becomes
  48. # ///C:/foo/bar/spam.foo
  49. import urllib.parse
  50. if not ':' in p:
  51. # No drive specifier, just convert slashes and quote the name
  52. if p[:2] == '\\\\':
  53. # path is something like \\host\path\on\remote\host
  54. # convert this to ////host/path/on/remote/host
  55. # (notice doubling of slashes at the start of the path)
  56. p = '\\\\' + p
  57. components = p.split('\\')
  58. return urllib.parse.quote('/'.join(components))
  59. comp = p.split(':')
  60. if len(comp) != 2 or len(comp[0]) > 1:
  61. error = 'Bad path: ' + p
  62. raise OSError(error)
  63. drive = urllib.parse.quote(comp[0].upper())
  64. components = comp[1].split('\\')
  65. path = '///' + drive + ':'
  66. for comp in components:
  67. if comp:
  68. path = path + '/' + urllib.parse.quote(comp)
  69. return path