mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-28 10:44:36 +08:00
Update nturl2path from v3.14.2
This commit is contained in:
1 parent
2ac1b04914
commit
4f1d191ca9
2 files changed
+139
-27
No files matched your search
Vendored
+32
-27
@@ -3,7 +3,15 @@
|
||||
This module only exists to provide OS-specific code
|
||||
for urllib.requests, thus do not use directly.
|
||||
"""
|
||||
# Testing is done through test_urllib.
|
||||
# Testing is done through test_nturl2path.
|
||||
|
||||
import warnings
|
||||
|
||||
|
||||
warnings._deprecated(
|
||||
__name__,
|
||||
message=f"{warnings._DEPRECATED_MSG}; use 'urllib.request' instead",
|
||||
remove=(3, 19))
|
||||
|
||||
def url2pathname(url):
|
||||
"""OS-specific conversion from a relative URL of the 'file' scheme
|
||||
@@ -14,7 +22,7 @@ def url2pathname(url):
|
||||
# ///C:/foo/bar/spam.foo
|
||||
# become
|
||||
# C:\foo\bar\spam.foo
|
||||
import string, urllib.parse
|
||||
import urllib.parse
|
||||
if url[:3] == '///':
|
||||
# URL has an empty authority section, so the path begins on the third
|
||||
# character.
|
||||
@@ -25,19 +33,14 @@ def url2pathname(url):
|
||||
if url[:3] == '///':
|
||||
# Skip past extra slash before UNC drive in URL path.
|
||||
url = url[1:]
|
||||
# Windows itself uses ":" even in URLs.
|
||||
url = url.replace(':', '|')
|
||||
if not '|' in url:
|
||||
# No drive specifier, just convert slashes
|
||||
# make sure not to convert quoted slashes :-)
|
||||
return urllib.parse.unquote(url.replace('/', '\\'))
|
||||
comp = url.split('|')
|
||||
if len(comp) != 2 or comp[0][-1] not in string.ascii_letters:
|
||||
error = 'Bad URL: ' + url
|
||||
raise OSError(error)
|
||||
drive = comp[0][-1].upper()
|
||||
tail = urllib.parse.unquote(comp[1].replace('/', '\\'))
|
||||
return drive + ':' + tail
|
||||
else:
|
||||
if url[:1] == '/' and url[2:3] in (':', '|'):
|
||||
# Skip past extra slash before DOS drive in URL path.
|
||||
url = url[1:]
|
||||
if url[1:2] == '|':
|
||||
# Older URLs use a pipe after a drive letter
|
||||
url = url[:1] + ':' + url[2:]
|
||||
return urllib.parse.unquote(url.replace('/', '\\'))
|
||||
|
||||
def pathname2url(p):
|
||||
"""OS-specific conversion from a file system path to a relative URL
|
||||
@@ -46,6 +49,7 @@ def pathname2url(p):
|
||||
# C:\foo\bar\spam.foo
|
||||
# becomes
|
||||
# ///C:/foo/bar/spam.foo
|
||||
import ntpath
|
||||
import urllib.parse
|
||||
# First, clean up some special forms. We are going to sacrifice
|
||||
# the additional information anyway
|
||||
@@ -54,16 +58,17 @@ def pathname2url(p):
|
||||
p = p[4:]
|
||||
if p[:4].upper() == 'UNC/':
|
||||
p = '//' + p[4:]
|
||||
elif p[1:2] != ':':
|
||||
raise OSError('Bad path: ' + p)
|
||||
if not ':' in p:
|
||||
# No DOS drive specified, just quote the pathname
|
||||
return urllib.parse.quote(p)
|
||||
comp = p.split(':', maxsplit=2)
|
||||
if len(comp) != 2 or len(comp[0]) > 1:
|
||||
error = 'Bad path: ' + p
|
||||
raise OSError(error)
|
||||
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(comp[0].upper())
|
||||
tail = urllib.parse.quote(comp[1])
|
||||
return '///' + drive + ':' + tail
|
||||
tail = urllib.parse.quote(tail)
|
||||
return drive + root + tail
|
||||
Vendored
+107
@@ -0,0 +1,107 @@
|
||||
import unittest
|
||||
|
||||
from test.support import warnings_helper
|
||||
|
||||
|
||||
nturl2path = warnings_helper.import_deprecated("nturl2path")
|
||||
|
||||
|
||||
class NTURL2PathTest(unittest.TestCase):
|
||||
"""Test pathname2url() and url2pathname()"""
|
||||
|
||||
def test_basic(self):
|
||||
# Make sure simple tests pass
|
||||
expected_path = r"parts\of\a\path"
|
||||
expected_url = "parts/of/a/path"
|
||||
result = nturl2path.pathname2url(expected_path)
|
||||
self.assertEqual(expected_url, result,
|
||||
"pathname2url() failed; %s != %s" %
|
||||
(result, expected_url))
|
||||
result = nturl2path.url2pathname(expected_url)
|
||||
self.assertEqual(expected_path, result,
|
||||
"url2pathame() failed; %s != %s" %
|
||||
(result, expected_path))
|
||||
|
||||
def test_pathname2url(self):
|
||||
# Test special prefixes are correctly handled in pathname2url()
|
||||
fn = nturl2path.pathname2url
|
||||
self.assertEqual(fn('\\\\?\\C:\\dir'), '///C:/dir')
|
||||
self.assertEqual(fn('\\\\?\\unc\\server\\share\\dir'), '//server/share/dir')
|
||||
self.assertEqual(fn("C:"), '///C:')
|
||||
self.assertEqual(fn("C:\\"), '///C:/')
|
||||
self.assertEqual(fn('c:\\a\\b.c'), '///c:/a/b.c')
|
||||
self.assertEqual(fn('C:\\a\\b.c'), '///C:/a/b.c')
|
||||
self.assertEqual(fn('C:\\a\\b.c\\'), '///C:/a/b.c/')
|
||||
self.assertEqual(fn('C:\\a\\\\b.c'), '///C:/a//b.c')
|
||||
self.assertEqual(fn('C:\\a\\b%#c'), '///C:/a/b%25%23c')
|
||||
self.assertEqual(fn('C:\\a\\b\xe9'), '///C:/a/b%C3%A9')
|
||||
self.assertEqual(fn('C:\\foo\\bar\\spam.foo'), "///C:/foo/bar/spam.foo")
|
||||
# NTFS alternate data streams
|
||||
self.assertEqual(fn('C:\\foo:bar'), '///C:/foo%3Abar')
|
||||
self.assertEqual(fn('foo:bar'), 'foo%3Abar')
|
||||
# No drive letter
|
||||
self.assertEqual(fn("\\folder\\test\\"), '///folder/test/')
|
||||
self.assertEqual(fn("\\\\folder\\test\\"), '//folder/test/')
|
||||
self.assertEqual(fn("\\\\\\folder\\test\\"), '///folder/test/')
|
||||
self.assertEqual(fn('\\\\some\\share\\'), '//some/share/')
|
||||
self.assertEqual(fn('\\\\some\\share\\a\\b.c'), '//some/share/a/b.c')
|
||||
self.assertEqual(fn('\\\\some\\share\\a\\b%#c\xe9'), '//some/share/a/b%25%23c%C3%A9')
|
||||
# Alternate path separator
|
||||
self.assertEqual(fn('C:/a/b.c'), '///C:/a/b.c')
|
||||
self.assertEqual(fn('//some/share/a/b.c'), '//some/share/a/b.c')
|
||||
self.assertEqual(fn('//?/C:/dir'), '///C:/dir')
|
||||
self.assertEqual(fn('//?/unc/server/share/dir'), '//server/share/dir')
|
||||
# Round-tripping
|
||||
urls = ['///C:',
|
||||
'///folder/test/',
|
||||
'///C:/foo/bar/spam.foo']
|
||||
for url in urls:
|
||||
self.assertEqual(fn(nturl2path.url2pathname(url)), url)
|
||||
|
||||
def test_url2pathname(self):
|
||||
fn = nturl2path.url2pathname
|
||||
self.assertEqual(fn('/'), '\\')
|
||||
self.assertEqual(fn('/C:/'), 'C:\\')
|
||||
self.assertEqual(fn("///C|"), 'C:')
|
||||
self.assertEqual(fn("///C:"), 'C:')
|
||||
self.assertEqual(fn('///C:/'), 'C:\\')
|
||||
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\\')
|
||||
# DOS drive paths
|
||||
self.assertEqual(fn('c:/path/to/file'), 'c:\\path\\to\\file')
|
||||
self.assertEqual(fn('C:/path/to/file'), 'C:\\path\\to\\file')
|
||||
self.assertEqual(fn('C:/path/to/file/'), 'C:\\path\\to\\file\\')
|
||||
self.assertEqual(fn('C:/path/to//file'), 'C:\\path\\to\\\\file')
|
||||
self.assertEqual(fn('C|/path/to/file'), 'C:\\path\\to\\file')
|
||||
self.assertEqual(fn('/C|/path/to/file'), 'C:\\path\\to\\file')
|
||||
self.assertEqual(fn('///C|/path/to/file'), 'C:\\path\\to\\file')
|
||||
self.assertEqual(fn("///C|/foo/bar/spam.foo"), 'C:\\foo\\bar\\spam.foo')
|
||||
# Colons in URI
|
||||
self.assertEqual(fn('///\u00e8|/'), '\u00e8:\\')
|
||||
self.assertEqual(fn('//host/share/spam.txt:eggs'), '\\\\host\\share\\spam.txt:eggs')
|
||||
self.assertEqual(fn('///c:/spam.txt:eggs'), 'c:\\spam.txt:eggs')
|
||||
# UNC paths
|
||||
self.assertEqual(fn('//server/path/to/file'), '\\\\server\\path\\to\\file')
|
||||
self.assertEqual(fn('////server/path/to/file'), '\\\\server\\path\\to\\file')
|
||||
self.assertEqual(fn('/////server/path/to/file'), '\\\\server\\path\\to\\file')
|
||||
# Localhost paths
|
||||
self.assertEqual(fn('//localhost/C:/path/to/file'), 'C:\\path\\to\\file')
|
||||
self.assertEqual(fn('//localhost/C|/path/to/file'), 'C:\\path\\to\\file')
|
||||
self.assertEqual(fn('//localhost/path/to/file'), '\\path\\to\\file')
|
||||
self.assertEqual(fn('//localhost//server/path/to/file'), '\\\\server\\path\\to\\file')
|
||||
# Percent-encoded forward slashes are preserved for backwards compatibility
|
||||
self.assertEqual(fn('C:/foo%2fbar'), 'C:\\foo/bar')
|
||||
self.assertEqual(fn('//server/share/foo%2fbar'), '\\\\server\\share\\foo/bar')
|
||||
# Round-tripping
|
||||
paths = ['C:',
|
||||
r'\C\test\\',
|
||||
r'C:\foo\bar\spam.foo']
|
||||
for path in paths:
|
||||
self.assertEqual(fn(nturl2path.pathname2url(path)), path)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
Reference in new issue
Block a user