Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions upath/implementations/local.py
Original file line number Diff line number Diff line change
Expand Up @@ -758,6 +758,16 @@ class PosixUPath(LocalPath, pathlib.PosixPath, UPath): # type: ignore[misc]
class WindowsUPath(LocalPath, pathlib.WindowsPath):
__slots__ = ()

def as_uri(self) -> str:
uri = super().as_uri()
# pathlib writes UNC paths as file://server/share/..., but fsspec
# reads the part after file:// as a path, so that URI would point
# at a local server/share/... directory. Keep the server in the
# path instead: file:////server/share/...
if uri.startswith("file://") and not uri.startswith("file:///"):
uri = "file:////" + uri[len("file://") :]
return uri

if os.name != "nt":

def __new__(
Expand Down
19 changes: 19 additions & 0 deletions upath/tests/pathlib/test_pathlib_310.py
Original file line number Diff line number Diff line change
Expand Up @@ -1231,6 +1231,25 @@ class PosixPathAsPureTest(PurePosixPathTest, unittest.TestCase):
class WindowsPathAsPureTest(PureWindowsPathTest, unittest.TestCase):
cls = WindowsUPath

def test_as_uri(self):
# UPath keeps the server of a UNC path in the URI path
# (file:////server/share) where pathlib uses file://server/share,
# because fsspec reads file://server/share as a relative path
P = self.cls
with self.assertRaises(ValueError):
P('/a/b').as_uri()
with self.assertRaises(ValueError):
P('c:a/b').as_uri()
self.assertEqual(P('c:/').as_uri(), 'file:///c:/')
self.assertEqual(P('c:/a/b.c').as_uri(), 'file:///c:/a/b.c')
self.assertEqual(P('c:/a/b%#c').as_uri(), 'file:///c:/a/b%25%23c')
self.assertEqual(P('c:/a/b\xe9').as_uri(), 'file:///c:/a/b%C3%A9')
self.assertEqual(P('//some/share/').as_uri(), 'file:////some/share/')
self.assertEqual(P('//some/share/a/b.c').as_uri(),
'file:////some/share/a/b.c')
self.assertEqual(P('//some/share/a/b%#c\xe9').as_uri(),
'file:////some/share/a/b%25%23c%C3%A9')

def test_owner(self):
P = self.cls
with self.assertRaises(NotImplementedError):
Expand Down
19 changes: 19 additions & 0 deletions upath/tests/pathlib/test_pathlib_311.py
Original file line number Diff line number Diff line change
Expand Up @@ -1233,6 +1233,25 @@ class PosixPathAsPureTest(PurePosixPathTest, unittest.TestCase):
class WindowsPathAsPureTest(PureWindowsPathTest, unittest.TestCase):
cls = WindowsUPath

def test_as_uri(self):
# UPath keeps the server of a UNC path in the URI path
# (file:////server/share) where pathlib uses file://server/share,
# because fsspec reads file://server/share as a relative path
P = self.cls
with self.assertRaises(ValueError):
P('/a/b').as_uri()
with self.assertRaises(ValueError):
P('c:a/b').as_uri()
self.assertEqual(P('c:/').as_uri(), 'file:///c:/')
self.assertEqual(P('c:/a/b.c').as_uri(), 'file:///c:/a/b.c')
self.assertEqual(P('c:/a/b%#c').as_uri(), 'file:///c:/a/b%25%23c')
self.assertEqual(P('c:/a/b\xe9').as_uri(), 'file:///c:/a/b%C3%A9')
self.assertEqual(P('//some/share/').as_uri(), 'file:////some/share/')
self.assertEqual(P('//some/share/a/b.c').as_uri(),
'file:////some/share/a/b.c')
self.assertEqual(P('//some/share/a/b%#c\xe9').as_uri(),
'file:////some/share/a/b%25%23c%C3%A9')

def test_owner(self):
P = self.cls
with self.assertRaises(NotImplementedError):
Expand Down
19 changes: 19 additions & 0 deletions upath/tests/pathlib/test_pathlib_312.py
Original file line number Diff line number Diff line change
Expand Up @@ -1541,6 +1541,25 @@ class PosixPathAsPureTest(PurePosixPathTest, unittest.TestCase):
class WindowsPathAsPureTest(PureWindowsPathTest, unittest.TestCase):
cls = WindowsUPath

def test_as_uri(self):
# UPath keeps the server of a UNC path in the URI path
# (file:////server/share) where pathlib uses file://server/share,
# because fsspec reads file://server/share as a relative path
P = self.cls
with self.assertRaises(ValueError):
P('/a/b').as_uri()
with self.assertRaises(ValueError):
P('c:a/b').as_uri()
self.assertEqual(P('c:/').as_uri(), 'file:///c:/')
self.assertEqual(P('c:/a/b.c').as_uri(), 'file:///c:/a/b.c')
self.assertEqual(P('c:/a/b%#c').as_uri(), 'file:///c:/a/b%25%23c')
self.assertEqual(P('c:/a/b\xe9').as_uri(), 'file:///c:/a/b%C3%A9')
self.assertEqual(P('//some/share/').as_uri(), 'file:////some/share/')
self.assertEqual(P('//some/share/a/b.c').as_uri(),
'file:////some/share/a/b.c')
self.assertEqual(P('//some/share/a/b%#c\xe9').as_uri(),
'file:////some/share/a/b%25%23c%C3%A9')

def test_owner(self):
P = self.cls
with self.assertRaises(NotImplementedError):
Expand Down
19 changes: 19 additions & 0 deletions upath/tests/pathlib/test_pathlib_39.py
Original file line number Diff line number Diff line change
Expand Up @@ -1192,6 +1192,25 @@ class PosixPathAsPureTest(PurePosixPathTest, unittest.TestCase):
class WindowsPathAsPureTest(PureWindowsPathTest, unittest.TestCase):
cls = WindowsUPath

def test_as_uri(self):
# UPath keeps the server of a UNC path in the URI path
# (file:////server/share) where pathlib uses file://server/share,
# because fsspec reads file://server/share as a relative path
P = self.cls
with self.assertRaises(ValueError):
P('/a/b').as_uri()
with self.assertRaises(ValueError):
P('c:a/b').as_uri()
self.assertEqual(P('c:/').as_uri(), 'file:///c:/')
self.assertEqual(P('c:/a/b.c').as_uri(), 'file:///c:/a/b.c')
self.assertEqual(P('c:/a/b%#c').as_uri(), 'file:///c:/a/b%25%23c')
self.assertEqual(P('c:/a/b\xe9').as_uri(), 'file:///c:/a/b%C3%A9')
self.assertEqual(P('//some/share/').as_uri(), 'file:////some/share/')
self.assertEqual(P('//some/share/a/b.c').as_uri(),
'file:////some/share/a/b.c')
self.assertEqual(P('//some/share/a/b%#c\xe9').as_uri(),
'file:////some/share/a/b%25%23c%C3%A9')

def test_owner(self):
P = self.cls
with self.assertRaises(NotImplementedError):
Expand Down
9 changes: 9 additions & 0 deletions upath/tests/test_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,15 @@ def test_windows_path(local_testdir):
assert isinstance(UPath(local_testdir), pathlib.WindowsPath)


@only_on_windows
def test_windows_unc_path_as_uri_round_trip():
# https://github.com/fsspec/universal_pathlib/issues/557
pth = UPath(r"\\server\share\file")
uri = pth.as_uri()
assert uri == "file:////server/share/file"
assert UPath(uri).path == "//server/share/file"


def test_UPath_untested_protocol_warning(clear_registry):
with warnings.catch_warnings(record=True) as w:
_ = UPath("mock:/")
Expand Down