Skip to content
Merged
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
5 changes: 4 additions & 1 deletion importlib_resources/readers.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,10 @@ def _candidate_paths(cls, path_str):
def _resolve_zip_path(path_str):
for match in reversed(list(re.finditer(r'[\\/]', path_str))):
with contextlib.suppress(
FileNotFoundError, IsADirectoryError, PermissionError
FileNotFoundError,
IsADirectoryError,
NotADirectoryError,
PermissionError,
):
inner = path_str[match.end() :].replace('\\', '/') + '/'
yield ZipPath(path_str[: match.start()], inner.lstrip('/'))
Expand Down
Binary file modified importlib_resources/tests/data01/subdirectory/binary.file
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

Expand Down
2 changes: 1 addition & 1 deletion importlib_resources/tests/test_contents.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ class ContentsZipTests(ContentsTests, util.ZipSetup, unittest.TestCase):
class ContentsNamespaceTests(ContentsTests, unittest.TestCase):
expected = {
# no __init__ because of namespace design
# no subdirectory as incidental difference in fixture
'binary.file',
'subdirectory',
'utf-16.file',
'utf-8.file',
}
Expand Down
4 changes: 4 additions & 0 deletions importlib_resources/tests/test_files.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ def setUp(self):
self.data = namespacedata01


class OpenNamespaceZipTests(FilesTests, util.ZipSetup, unittest.TestCase):
ZIP_MODULE = 'namespacedata01'


class SiteDir:
def setUp(self):
self.fixtures = contextlib.ExitStack()
Expand Down
6 changes: 5 additions & 1 deletion importlib_resources/tests/test_open.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def test_open_binary(self):
target = resources.files(self.data) / 'binary.file'
with target.open('rb') as fp:
result = fp.read()
self.assertEqual(result, b'\x00\x01\x02\x03')
self.assertEqual(result, bytes(range(4)))

def test_open_text_default_encoding(self):
target = resources.files(self.data) / 'utf-8.file'
Expand Down Expand Up @@ -81,5 +81,9 @@ class OpenZipTests(OpenTests, util.ZipSetup, unittest.TestCase):
pass


class OpenNamespaceZipTests(OpenTests, util.ZipSetup, unittest.TestCase):
ZIP_MODULE = 'namespacedata01'


if __name__ == '__main__':
unittest.main()
23 changes: 20 additions & 3 deletions importlib_resources/tests/test_read.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ def execute(self, package, path):
class ReadTests:
def test_read_bytes(self):
result = resources.files(self.data).joinpath('binary.file').read_bytes()
self.assertEqual(result, b'\0\1\2\3')
self.assertEqual(result, bytes(range(4)))

def test_read_text_default_encoding(self):
result = (
Expand Down Expand Up @@ -60,13 +60,13 @@ class ReadZipTests(ReadTests, util.ZipSetup, unittest.TestCase):
def test_read_submodule_resource(self):
submodule = import_module('data01.subdirectory')
result = resources.files(submodule).joinpath('binary.file').read_bytes()
self.assertEqual(result, b'\0\1\2\3')
self.assertEqual(result, bytes(range(4, 8)))

def test_read_submodule_resource_by_name(self):
result = (
resources.files('data01.subdirectory').joinpath('binary.file').read_bytes()
)
self.assertEqual(result, b'\0\1\2\3')
self.assertEqual(result, bytes(range(4, 8)))


class ReadNamespaceTests(ReadTests, unittest.TestCase):
Expand All @@ -76,5 +76,22 @@ def setUp(self):
self.data = namespacedata01


class ReadNamespaceZipTests(ReadTests, util.ZipSetup, unittest.TestCase):
ZIP_MODULE = 'namespacedata01'

def test_read_submodule_resource(self):
submodule = import_module('namespacedata01.subdirectory')
result = resources.files(submodule).joinpath('binary.file').read_bytes()
self.assertEqual(result, bytes(range(12, 16)))

def test_read_submodule_resource_by_name(self):
result = (
resources.files('namespacedata01.subdirectory')
.joinpath('binary.file')
.read_bytes()
)
self.assertEqual(result, bytes(range(12, 16)))


if __name__ == '__main__':
unittest.main()
12 changes: 7 additions & 5 deletions importlib_resources/tests/test_reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ def test_iterdir(self):
contents.remove('__pycache__')
except (KeyError, ValueError):
pass
self.assertEqual(contents, {'binary.file', 'utf-16.file', 'utf-8.file'})
self.assertEqual(
contents, {'subdirectory', 'binary.file', 'utf-16.file', 'utf-8.file'}
)

def test_iterdir_duplicate(self):
data01 = pathlib.Path(__file__).parent.joinpath('data01')
Expand Down Expand Up @@ -66,10 +68,10 @@ def test_join_path(self):
str(path.joinpath('binary.file'))[len(prefix) + 1 :],
os.path.join('namespacedata01', 'binary.file'),
)
self.assertEqual(
str(path.joinpath('subdirectory'))[len(prefix) + 1 :],
os.path.join('data01', 'subdirectory'),
)
sub = path.joinpath('subdirectory')
assert isinstance(sub, MultiplexedPath)
assert 'namespacedata01' in str(sub)
assert 'data01' in str(sub)
self.assertEqual(
str(path.joinpath('imaginary'))[len(prefix) + 1 :],
os.path.join('namespacedata01', 'imaginary'),
Expand Down
24 changes: 22 additions & 2 deletions importlib_resources/tests/test_resource.py
Original file line number Diff line number Diff line change
Expand Up @@ -186,15 +186,35 @@ def test_submodule_contents(self):
contents.remove('__pycache__')
except KeyError:
pass
self.assertEqual(contents, {'binary.file', 'utf-8.file', 'utf-16.file'})
self.assertEqual(
contents, {'subdirectory', 'binary.file', 'utf-8.file', 'utf-16.file'}
)

def test_submodule_contents_by_name(self):
contents = names(resources.files('namespacedata01'))
try:
contents.remove('__pycache__')
except KeyError:
pass
self.assertEqual(contents, {'binary.file', 'utf-8.file', 'utf-16.file'})
self.assertEqual(
contents, {'subdirectory', 'binary.file', 'utf-8.file', 'utf-16.file'}
)

def test_submodule_sub_contents(self):
contents = names(resources.files(import_module('namespacedata01.subdirectory')))
try:
contents.remove('__pycache__')
except KeyError:
pass
self.assertEqual(contents, {'binary.file'})

def test_submodule_sub_contents_by_name(self):
contents = names(resources.files('namespacedata01.subdirectory'))
try:
contents.remove('__pycache__')
except KeyError:
pass
self.assertEqual(contents, {'binary.file'})


class ResourceFromNamespaceDiskTests(ResourceFromNamespaceTests, unittest.TestCase):
Expand Down
1 change: 1 addition & 0 deletions newsfragments/293.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fixed NotADirectoryError when calling files on a subdirectory of a namespace package.