Skip to content

Commit bfc432d

Browse files
Merge pull request #16 from andrewfulton9/issue_15
Issue 15
2 parents 312aafe + 24295e7 commit bfc432d

File tree

9 files changed

+272
-214
lines changed

9 files changed

+272
-214
lines changed

upath/core.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ def __new__(cls, *args, **kwargs):
1616
for key in ["scheme", "netloc"]:
1717
val = kwargs.get(key)
1818
if val:
19-
parsed_url._replace(**{key: val})
19+
parsed_url = parsed_url._replace(**{key: val})
2020
# treat as local filesystem, return PosixPath or WindowsPath
2121
impls = list(registry) + list(known_implementations.keys())
2222
if not parsed_url.scheme or parsed_url.scheme not in impls:

upath/implementations/memory.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,13 @@
44
class _MemoryAccessor(_FSSpecAccessor):
55
def __init__(self, *args, **kwargs):
66
super().__init__(*args, **kwargs)
7+
self._fs.root_marker = ""
8+
9+
def _format_path(self, s):
10+
"""If the filesystem backend doesn't have a root_marker, strip the
11+
leading slash of a path
12+
"""
13+
return s
714

815

916
class MemoryPath(UniversalPath):

upath/tests/cases.py

Lines changed: 227 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
1+
from pathlib import Path
2+
3+
import pytest
4+
5+
from upath import UPath
6+
7+
8+
class BaseTests:
9+
def test_cwd(self):
10+
with pytest.raises(NotImplementedError):
11+
self.path.cwd()
12+
13+
def test_home(self):
14+
with pytest.raises(NotImplementedError):
15+
self.path.home()
16+
17+
def test_stat(self):
18+
stat = self.path.stat()
19+
assert stat
20+
21+
def test_chmod(self):
22+
with pytest.raises(NotImplementedError):
23+
self.path.joinpath("file1.txt").chmod(777)
24+
25+
@pytest.mark.parametrize(
26+
"url, expected", [("file1.txt", True), ("fakefile.txt", False)]
27+
)
28+
def test_exists(self, url, expected):
29+
print(self.path)
30+
path = self.path.joinpath(url)
31+
assert path.exists() == expected
32+
33+
def test_expanduser(self):
34+
with pytest.raises(NotImplementedError):
35+
self.path.expanduser()
36+
37+
def test_glob(self, pathlib_base):
38+
mock_glob = list(self.path.glob("**.txt"))
39+
path_glob = list(pathlib_base.glob("**/*.txt"))
40+
41+
assert len(mock_glob) == len(path_glob)
42+
assert all(
43+
map(
44+
lambda m: m.path
45+
in [str(p).replace("\\", "/") for p in path_glob],
46+
mock_glob,
47+
)
48+
)
49+
50+
def test_group(self):
51+
with pytest.raises(NotImplementedError):
52+
self.path.group()
53+
54+
def test_is_dir(self):
55+
assert self.path.is_dir()
56+
57+
path = self.path.joinpath("file1.txt")
58+
assert not path.is_dir()
59+
60+
def test_is_file(self):
61+
path = self.path.joinpath("file1.txt")
62+
assert path.is_file()
63+
assert not self.path.is_file()
64+
65+
def test_is_mount(self):
66+
with pytest.raises(NotImplementedError):
67+
self.path.is_mount()
68+
69+
def test_is_symlink(self):
70+
with pytest.raises(NotImplementedError):
71+
self.path.is_symlink()
72+
73+
def test_is_socket(self):
74+
with pytest.raises(NotImplementedError):
75+
self.path.is_socket()
76+
77+
def test_is_fifo(self):
78+
with pytest.raises(NotImplementedError):
79+
self.path.is_fifo()
80+
81+
def test_is_block_device(self):
82+
with pytest.raises(NotImplementedError):
83+
self.path.is_block_device()
84+
85+
def test_is_char_device(self):
86+
with pytest.raises(NotImplementedError):
87+
self.path.is_char_device()
88+
89+
def test_iterdir(self, local_testdir):
90+
pl_path = Path(local_testdir)
91+
92+
up_iter = list(self.path.iterdir())
93+
pl_iter = list(pl_path.iterdir())
94+
95+
assert len(up_iter) == len(pl_iter)
96+
pnames = [p.name for p in pl_iter]
97+
assert all(map(lambda x: x.name in pnames, up_iter))
98+
99+
def test_lchmod(self):
100+
with pytest.raises(NotImplementedError):
101+
self.path.lchmod(mode=77)
102+
103+
def test_lstat(self):
104+
with pytest.raises(NotImplementedError):
105+
self.path.lstat()
106+
107+
def test_mkdir(self):
108+
new_dir = self.path.joinpath("new_dir")
109+
new_dir.mkdir()
110+
assert new_dir.exists()
111+
112+
def test_open(self):
113+
pass
114+
115+
def test_owner(self):
116+
with pytest.raises(NotImplementedError):
117+
self.path.owner()
118+
119+
def test_read_bytes(self, pathlib_base):
120+
mock = self.path.joinpath("file2.txt")
121+
pl = pathlib_base.joinpath("file2.txt")
122+
assert mock.read_bytes() == pl.read_bytes()
123+
124+
def test_read_text(self, local_testdir):
125+
upath = self.path.joinpath("file1.txt")
126+
assert (
127+
upath.read_text()
128+
== Path(local_testdir).joinpath("file1.txt").read_text()
129+
)
130+
131+
def test_readlink(self):
132+
with pytest.raises(NotImplementedError):
133+
self.path.readlink()
134+
135+
@pytest.mark.xfail
136+
def test_rename(self):
137+
# need to impliment
138+
raise False
139+
140+
def test_replace(self):
141+
pass
142+
143+
def test_resolve(self):
144+
pass
145+
146+
def test_rglob(self):
147+
pass
148+
149+
def test_samefile(self):
150+
pass
151+
152+
def test_symlink_to(self):
153+
pass
154+
155+
def test_touch_unlink(self):
156+
path = self.path.joinpath("test_touch.txt")
157+
path.touch()
158+
assert path.exists()
159+
path.unlink()
160+
assert not path.exists()
161+
162+
# should raise FileNotFoundError since file is missing
163+
with pytest.raises(FileNotFoundError):
164+
path.unlink()
165+
166+
# file doesn't exists, but missing_ok is True
167+
path.unlink(missing_ok=True)
168+
169+
def test_link_to(self):
170+
pass
171+
172+
def test_write_bytes(self, pathlib_base):
173+
fn = "test_write_bytes.txt"
174+
s = b"hello_world"
175+
path = self.path.joinpath(fn)
176+
path.write_bytes(s)
177+
assert path.read_bytes() == s
178+
179+
def test_write_text(self, pathlib_base):
180+
fn = "test_write_text.txt"
181+
s = "hello_world"
182+
path = self.path.joinpath(fn)
183+
path.write_text(s)
184+
assert path.read_text() == s
185+
186+
def prepare_file_system(self):
187+
self.make_top_folder()
188+
self.make_test_files()
189+
190+
def make_top_folder(self):
191+
self.path.mkdir(parents=True, exist_ok=True)
192+
193+
def make_test_files(self):
194+
folder1 = self.path.joinpath("folder1")
195+
folder1.mkdir(exist_ok=True)
196+
folder1_files = ["file1.txt", "file2.txt"]
197+
for f in folder1_files:
198+
p = folder1.joinpath(f)
199+
p.touch()
200+
p.write_text(f)
201+
202+
file1 = self.path.joinpath("file1.txt")
203+
file1.touch()
204+
file1.write_text("hello world")
205+
file2 = self.path.joinpath("file2.txt")
206+
file2.touch()
207+
file2.write_bytes(b"hello world")
208+
209+
def test_fsspec_compat(self):
210+
fs = self.path.fs
211+
scheme = self.path._url.scheme
212+
content = b"a,b,c\n1,2,3\n4,5,6"
213+
214+
p1 = f"{scheme}:///tmp/output1.csv"
215+
upath1 = UPath(p1)
216+
upath1.write_bytes(content)
217+
with fs.open(p1) as f:
218+
assert f.read() == content
219+
upath1.unlink()
220+
221+
# write with fsspec, read with upath
222+
p2 = f"{scheme}:///tmp/output2.csv"
223+
with fs.open(p2, "wb") as f:
224+
f.write(content)
225+
upath2 = UPath(p2)
226+
assert upath2.read_bytes() == content
227+
upath2.unlink()

upath/tests/conftest.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ def pytest_collection_modifyitems(config, items):
3434

3535
class DummyTestFS(LocalFileSystem):
3636
protocol = "mock"
37+
root_marker = "/"
3738

3839

3940
@pytest.fixture(scope="session")

upath/tests/implementations/test_hdfs.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@
44

55
from upath import UPath
66
from upath.implementations.hdfs import HDFSPath
7-
from upath.tests.test_core import TestUpath
7+
from upath.tests.cases import BaseTests
88

99

1010
@pytest.mark.hdfs
11-
class TestUPathHDFS(TestUpath):
11+
class TestUPathHDFS(BaseTests):
1212
@pytest.fixture(autouse=True)
1313
def path(self, local_testdir, hdfs):
1414
host, user, port = hdfs
@@ -21,3 +21,6 @@ def test_is_HDFSPath(self):
2121
def test_chmod(self):
2222
# todo
2323
pass
24+
25+
def test_fsspec_compat(self):
26+
pass

upath/tests/implementations/test_memory.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33

44
from upath import UPath
55
from upath.implementations.memory import MemoryPath
6-
from upath.tests.test_core import TestUpath
6+
from upath.tests.cases import BaseTests
77

88

9-
class TestMemoryPath(TestUpath):
9+
class TestMemoryPath(BaseTests):
1010
@pytest.fixture(autouse=True)
1111
def path(self, local_testdir):
1212
path = f"memory:/{local_testdir}"

upath/tests/implementations/test_s3.py

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,17 @@
55
from upath import UPath
66
from upath.errors import NotDirectoryError
77
from upath.implementations.s3 import S3Path
8-
from upath.tests.test_core import TestUpath
8+
from upath.tests.cases import BaseTests
99

1010

11-
class TestUPathS3(TestUpath):
11+
class TestUPathS3(BaseTests):
1212
@pytest.fixture(autouse=True)
1313
def path(self, local_testdir, s3):
1414
anon, s3so = s3
1515
path = f"s3:/{local_testdir}"
16-
print(path)
1716
self.path = UPath(path, anon=anon, **s3so)
17+
self.anon = anon
18+
self.s3so = s3so
1819

1920
def test_is_S3Path(self):
2021
assert isinstance(self.path, S3Path)
@@ -62,3 +63,23 @@ def test_glob(self, pathlib_base):
6263
assert all(
6364
map(lambda m: m.path in [str(p)[4:] for p in path_glob], mock_glob)
6465
)
66+
67+
def test_fsspec_compat(self):
68+
fs = self.path.fs
69+
scheme = self.path._url.scheme
70+
content = b"a,b,c\n1,2,3\n4,5,6"
71+
72+
p1 = f"{scheme}:///tmp/output1.csv"
73+
upath1 = UPath(p1, anon=self.anon, **self.s3so)
74+
upath1.write_bytes(content)
75+
with fs.open(p1) as f:
76+
assert f.read() == content
77+
upath1.unlink()
78+
79+
# write with fsspec, read with upath
80+
p2 = f"{scheme}:///tmp/output2.csv"
81+
with fs.open(p2, "wb") as f:
82+
f.write(content)
83+
upath2 = UPath(p2, anon=self.anon, **self.s3so)
84+
assert upath2.read_bytes() == content
85+
upath2.unlink()

0 commit comments

Comments
 (0)