Skip to content

Commit f4de726

Browse files
authored
Fix NotADirectoryError (#74)
* upath: use NotADirectoryError instead of custom NotDirectoryError * tests: add test raising NotADirectoryError * upath.implementations.http: fix listdir behavior
1 parent b3e6bdf commit f4de726

File tree

7 files changed

+45
-21
lines changed

7 files changed

+45
-21
lines changed

upath/core.py

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@
1212
)
1313
from fsspec.utils import stringify_path
1414

15-
from upath.errors import NotDirectoryError
16-
1715

1816
class _FSSpecAccessor:
1917
__slots__ = ("_fs",)
@@ -36,7 +34,17 @@ def stat(self, path, **kwargs):
3634
return self._fs.stat(self._format_path(path), **kwargs)
3735

3836
def listdir(self, path, **kwargs):
39-
return self._fs.listdir(self._format_path(path), **kwargs)
37+
p_fmt = self._format_path(path)
38+
contents = self._fs.listdir(p_fmt, **kwargs)
39+
if len(contents) == 0 and not self._fs.isdir(p_fmt):
40+
raise NotADirectoryError
41+
elif (
42+
len(contents) == 1
43+
and contents[0]["name"] == p_fmt
44+
and contents[0]["type"] == "file"
45+
):
46+
raise NotADirectoryError
47+
return contents
4048

4149
def glob(self, _path, path_pattern, **kwargs):
4250
return self._fs.glob(self._format_path(path_pattern), **kwargs)
@@ -326,10 +334,8 @@ def rmdir(self, recursive=True):
326334
"""Add warning if directory not empty
327335
assert is_dir?
328336
"""
329-
try:
330-
assert self.is_dir()
331-
except AssertionError:
332-
raise NotDirectoryError
337+
if not self.is_dir():
338+
raise NotADirectoryError
333339
self._accessor.rm(self, recursive=recursive)
334340

335341
def chmod(self, mode, *, follow_symlinks=True):

upath/errors.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,13 @@
1-
class NotDirectoryError(Exception):
2-
pass
1+
import warnings
2+
3+
4+
def __getattr__(name):
5+
if name == "NotDirectoryError":
6+
warnings.warn(
7+
"upath.errors.NotDirectoryError is deprecated. "
8+
"Use NotADirectoryError instead",
9+
DeprecationWarning,
10+
stacklevel=2,
11+
)
12+
return NotADirectoryError
13+
raise AttributeError(name)

upath/implementations/http.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,12 @@ def is_file(self):
2525
return False
2626

2727
def _path_type(self):
28-
info = self._accessor.info(self)
29-
if (
30-
info["type"] == "directory"
31-
or next(self.iterdir(), None) is not None
32-
):
28+
try:
29+
next(self.iterdir())
30+
except (StopIteration, NotADirectoryError):
31+
return "file"
32+
else:
3333
return "directory"
34-
return "file"
3534

3635
def _sub_path(self, name):
3736
"""

upath/tests/cases.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,3 +334,14 @@ def test_repr_after_with_name(self):
334334
def test_repr_after_with_suffix(self):
335335
p = self.path.joinpath("file.txt").with_suffix(".zip")
336336
assert "file.zip" in repr(p)
337+
338+
def test_rmdir_no_dir(self):
339+
p = self.path.joinpath("file1.txt")
340+
with pytest.raises(NotADirectoryError):
341+
p.rmdir()
342+
343+
def test_iterdir_no_dir(self):
344+
p = self.path.joinpath("file1.txt")
345+
assert p.is_file()
346+
with pytest.raises(NotADirectoryError):
347+
_ = list(p.iterdir())

upath/tests/implementations/test_azure.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import pytest
22
from upath import UPath
3-
from upath.errors import NotDirectoryError
43
from upath.implementations.cloud import AzurePath
54

65
from ..cases import BaseTests
@@ -36,5 +35,5 @@ def test_rmdir(self):
3635
new_dir.rmdir()
3736
assert not new_dir.exists()
3837

39-
with pytest.raises(NotDirectoryError):
38+
with pytest.raises(NotADirectoryError):
4039
(self.path / "a" / "file.txt").rmdir()

upath/tests/implementations/test_gcs.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
from upath import UPath
44
from upath.implementations.cloud import GCSPath
5-
from upath.errors import NotDirectoryError
65
from ..cases import BaseTests
76
from ..utils import skip_on_windows
87

@@ -28,5 +27,5 @@ def test_rmdir(self):
2827
mock_dir.fs.invalidate_cache()
2928
mock_dir.rmdir()
3029
assert not mock_dir.exists()
31-
with pytest.raises(NotDirectoryError):
30+
with pytest.raises(NotADirectoryError):
3231
self.path.joinpath("file1.txt").rmdir()

upath/tests/implementations/test_s3.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import pytest # noqa: F401
44

55
from upath import UPath
6-
from upath.errors import NotDirectoryError
76
from upath.implementations.cloud import S3Path
87
from ..cases import BaseTests
98

@@ -31,7 +30,7 @@ def test_rmdir(self):
3130
mock_dir.joinpath("test.txt").touch()
3231
mock_dir.rmdir()
3332
assert not mock_dir.exists()
34-
with pytest.raises(NotDirectoryError):
33+
with pytest.raises(NotADirectoryError):
3534
self.path.joinpath("file1.txt").rmdir()
3635

3736
def test_relative_to(self):

0 commit comments

Comments
 (0)