From 4ad7a4874ace3e1125c25a17b6fdbe2bb4c7f18c Mon Sep 17 00:00:00 2001 From: "Davide Brunato (brunato)" Date: Sun, 28 Apr 2024 08:30:26 +0200 Subject: [PATCH] Fix CI failing location tests and LocationPath.from_uri() - LocationPath.from_uri(): fix lowercase drive from urlsplit() and add a docstring. --- tests/test_locations.py | 81 +++++++++++++++++------------------------ xmlschema/locations.py | 13 ++++++- 2 files changed, 44 insertions(+), 50 deletions(-) diff --git a/tests/test_locations.py b/tests/test_locations.py index b8c8862e..bd9a8614 100644 --- a/tests/test_locations.py +++ b/tests/test_locations.py @@ -24,7 +24,7 @@ TEST_CASES_DIR = str(pathlib.Path(__file__).absolute().parent.joinpath('test_cases')) -DRIVE_REGEX = '(/[a-zA-Z]:|/)' if platform.system() == 'Windows' else '' +DRIVE_REGEX = '(/[a-zA-Z]:|)' if platform.system() == 'Windows' else '' XML_WITH_NAMESPACES = '\n' \ ' \n' \ @@ -206,6 +206,11 @@ def test_normalize_url_windows(self): normalize_url('file:///\\k:\\Dir A\\schema.xsd') self.assertIn("Invalid URI", str(ec.exception)) + # u + base_url = 'D:/a/xmlschema/xmlschema/tests/test_cases/examples/' + self.assertEqual(normalize_url('vehicles.xsd', base_url), + f'file:///{base_url}vehicles.xsd') + def test_normalize_url_unc_paths__issue_246(self): url = PureWindowsPath(r'\\host\share\file.xsd').as_uri() self.assertNotEqual(normalize_url(r'\\host\share\file.xsd'), @@ -332,57 +337,37 @@ def test_normalize_url_hash_character(self): self.assertRegex(url, f'{DRIVE_REGEX}/dir1/dir2/issue%20%23002/data.xml') def test_normalize_url_with_query_part(self): - with patch.object(os, 'name', 'nt'): - self.assertEqual(os.name, 'nt') - - url = "https://xmlschema.test/schema 2/test.xsd?name=2 id=3" - self.assertEqual( - normalize_url(url), - "https://xmlschema.test/schema%202/test.xsd?name=2%20id=3" - ) + url = "https://xmlschema.test/schema 2/test.xsd?name=2 id=3" + self.assertEqual( + normalize_url(url), + "https://xmlschema.test/schema%202/test.xsd?name=2%20id=3" + ) - url = "https://xmlschema.test/schema 2/test.xsd?name=2 id=3" - self.assertEqual( - normalize_url(url, method='html'), - "https://xmlschema.test/schema%202/test.xsd?name=2+id=3" - ) + url = "https://xmlschema.test/schema 2/test.xsd?name=2 id=3" + self.assertEqual( + normalize_url(url, method='html'), + "https://xmlschema.test/schema%202/test.xsd?name=2+id=3" + ) - url = "/path/schema 2/test.xsd?name=2 id=3" - self.assertEqual( - normalize_url(url), - "file:///path/schema%202/test.xsd" - ) + url = "/path/schema 2/test.xsd?name=2 id=3" + self.assertRegex( + normalize_url(url), + f'file://{DRIVE_REGEX}/path/schema%202/test.xsd' + ) - with patch.object(os, 'name', 'posix'): - self.assertEqual(os.name, 'posix') + self.assertRegex( + normalize_url('other.xsd?id=2', 'file:///home?name=2&id='), + f'file://{DRIVE_REGEX}/home/other.xsd' + ) + self.assertRegex( + normalize_url('other.xsd#element', 'file:///home#attribute'), + f'file://{DRIVE_REGEX}/home/other.xsd' + ) - url = "https://xmlschema.test/schema 2/test.xsd?name=2 id=3" - self.assertEqual( - normalize_url(url), - "https://xmlschema.test/schema%202/test.xsd?name=2%20id=3" - ) - - url = "https://xmlschema.test/schema 2/test.xsd?name=2 id=3" - self.assertEqual( - normalize_url(url, method='html'), - "https://xmlschema.test/schema%202/test.xsd?name=2+id=3" - ) - - url = "/path/schema 2/test.xsd?name=2 id=3" - self.assertEqual( - normalize_url(url), - "file:///path/schema%202/test.xsd" - ) - - self.check_url(normalize_url('other.xsd?id=2', 'file:///home?name=2&id='), - 'file:///home/other.xsd') - self.check_url(normalize_url('other.xsd#element', 'file:///home#attribute'), - 'file:///home/other.xsd') - - self.check_url(normalize_url('other.xsd?id=2', 'https://host/path?name=2&id='), - 'https://host/path/other.xsd?id=2') - self.check_url(normalize_url('other.xsd#element', 'https://host/path?name=2&id='), - 'https://host/path/other.xsd#element') + self.check_url(normalize_url('other.xsd?id=2', 'https://host/path?name=2&id='), + 'https://host/path/other.xsd?id=2') + self.check_url(normalize_url('other.xsd#element', 'https://host/path?name=2&id='), + 'https://host/path/other.xsd#element') def test_is_url_function(self): self.assertTrue(is_url(self.col_xsd_file)) diff --git a/xmlschema/locations.py b/xmlschema/locations.py index f3b40d22..769aac7b 100644 --- a/xmlschema/locations.py +++ b/xmlschema/locations.py @@ -47,6 +47,12 @@ def __new__(cls, *args: str) -> 'LocationPath': @classmethod def from_uri(cls, uri: str) -> 'LocationPath': + """ + Parse a URI and return a LocationPath. For non-local schemes like 'http', + 'https', etc. a LocationPosixPath is returned. For Windows related file + paths, like a path with a drive, a UNC path or a path containing a backslash, + a LocationWindowsPath is returned. + """ uri = uri.strip() if not uri: raise XMLSchemaValueError("Empty URI provided!") @@ -56,10 +62,13 @@ def from_uri(cls, uri: str) -> 'LocationPath': path = urlunsplit(('', parts.netloc, parts.path, '', '')) elif parts.scheme in DRIVE_LETTERS and len(parts.scheme) == 1: # uri is a Windows path with a drive, e.g. k:/Python/lib/file - path = urlunsplit((parts.scheme, parts.netloc, parts.path, '', '')) + + # urlsplit() converts the scheme to lowercase so use uri[0] + path = urlunsplit((uri[0], parts.netloc, parts.path, '', '')) + return LocationWindowsPath(unquote(path)) else: - return cls(unquote(parts.path)) + return LocationPosixPath(unquote(parts.path)) if parts.scheme == 'file': if path.startswith('/') and ntpath.splitdrive(path[1:])[0]: