Browse Source

Fix handling of network locations (#1467)

Jelmer Vernooij 3 months ago
parent
commit
da57468a38
2 changed files with 32 additions and 33 deletions
  1. 3 9
      dulwich/client.py
  2. 29 24
      tests/test_client.py

+ 3 - 9
dulwich/client.py

@@ -140,10 +140,6 @@ DEFAULT_REF_PREFIX = [b"HEAD", b"refs/"]
 ObjectID = bytes
 
 
-# url2pathname is lazily imported
-url2pathname = None
-
-
 logger = logging.getLogger(__name__)
 
 
@@ -2868,7 +2864,6 @@ def _win32_url_to_path(parsed) -> str:
 
     https://datatracker.ietf.org/doc/html/rfc8089
     """
-    assert sys.platform == "win32" or os.name == "nt"
     assert parsed.scheme == "file"
 
     _, netloc, path, _, _, _ = parsed
@@ -2886,10 +2881,9 @@ def _win32_url_to_path(parsed) -> str:
     else:
         raise NotImplementedError("Non-local file URLs are not supported")
 
-    global url2pathname
-    if url2pathname is None:
-        from urllib.request import url2pathname  # type: ignore
-    return url2pathname(netloc + path)  # type: ignore
+    from nturl2path import url2pathname
+
+    return url2pathname(netloc + path)
 
 
 def get_transport_and_path_from_url(

+ 29 - 24
tests/test_client.py

@@ -50,6 +50,7 @@ from dulwich.client import (
     TraditionalGitClient,
     _extract_symrefs_and_agent,
     _remote_error_from_stderr,
+    _win32_url_to_path,
     check_wants,
     default_urllib3_manager,
     get_credentials_from_store,
@@ -671,33 +672,37 @@ class TestGetTransportAndPathFromUrl(TestCase):
         self.assertIsInstance(c, LocalGitClient)
         self.assertEqual("/home/jelmer/foo", path)
 
+    def test_win32_url_to_path(self):
+        def check(url, expected):
+            parsed = urlparse(url)
+            self.assertEqual(_win32_url_to_path(parsed), expected)
+
+        check("file:C:/foo.bar/baz", "C:\\foo.bar\\baz")
+        check("file:/C:/foo.bar/baz", "C:\\foo.bar\\baz")
+        check("file://C:/foo.bar/baz", "C:\\foo.bar\\baz")
+        check("file:///C:/foo.bar/baz", "C:\\foo.bar\\baz")
+
     @patch("os.name", "nt")
     @patch("sys.platform", "win32")
     def test_file_win(self) -> None:
-        # `_win32_url_to_path` uses urllib.request.url2pathname, which is set to
-        # `ntutl2path.url2pathname`  when `os.name==nt`
-        from nturl2path import url2pathname
-
-        with patch("dulwich.client.url2pathname", url2pathname):
-            expected = "C:\\foo.bar\\baz"
-            for file_url in [
-                "file:C:/foo.bar/baz",
-                "file:/C:/foo.bar/baz",
-                "file://C:/foo.bar/baz",
-                "file://C://foo.bar//baz",
-                "file:///C:/foo.bar/baz",
-            ]:
-                c, path = get_transport_and_path(file_url)
-                self.assertIsInstance(c, LocalGitClient)
-                self.assertEqual(path, expected)
-
-            for remote_url in [
-                "file://host.example.com/C:/foo.bar/baz"
-                "file://host.example.com/C:/foo.bar/baz"
-                "file:////host.example/foo.bar/baz",
-            ]:
-                with self.assertRaises(NotImplementedError):
-                    c, path = get_transport_and_path(remote_url)
+        expected = "C:\\foo.bar\\baz"
+        for file_url in [
+            "file:C:/foo.bar/baz",
+            "file:/C:/foo.bar/baz",
+            "file://C:/foo.bar/baz",
+            "file:///C:/foo.bar/baz",
+        ]:
+            c, path = get_transport_and_path(file_url)
+            self.assertIsInstance(c, LocalGitClient)
+            self.assertEqual(path, expected)
+
+        for remote_url in [
+            "file://host.example.com/C:/foo.bar/baz"
+            "file://host.example.com/C:/foo.bar/baz"
+            "file:////host.example/foo.bar/baz",
+        ]:
+            with self.assertRaises(NotImplementedError):
+                c, path = get_transport_and_path(remote_url)
 
 
 class TestSSHVendor: