Commit 30e507df authored by Barry Warsaw's avatar Barry Warsaw Committed by GitHub

bpo-33151: Handle submodule resources (GH-6268)

parent da1734c5
...@@ -267,11 +267,12 @@ class _ZipImportResourceReader(resources_abc.ResourceReader): ...@@ -267,11 +267,12 @@ class _ZipImportResourceReader(resources_abc.ResourceReader):
self.fullname = fullname self.fullname = fullname
def open_resource(self, resource): def open_resource(self, resource):
path = f'{self.fullname}/{resource}' fullname_as_path = self.fullname.replace('.', '/')
path = f'{fullname_as_path}/{resource}'
try: try:
return BytesIO(self.zipimporter.get_data(path)) return BytesIO(self.zipimporter.get_data(path))
except OSError: except OSError:
raise FileNotFoundError raise FileNotFoundError(path)
def resource_path(self, resource): def resource_path(self, resource):
# All resources are in the zip file, so there is no path to the file. # All resources are in the zip file, so there is no path to the file.
...@@ -282,7 +283,8 @@ class _ZipImportResourceReader(resources_abc.ResourceReader): ...@@ -282,7 +283,8 @@ class _ZipImportResourceReader(resources_abc.ResourceReader):
def is_resource(self, name): def is_resource(self, name):
# Maybe we could do better, but if we can get the data, it's a # Maybe we could do better, but if we can get the data, it's a
# resource. Otherwise it isn't. # resource. Otherwise it isn't.
path = f'{self.fullname}/{name}' fullname_as_path = self.fullname.replace('.', '/')
path = f'{fullname_as_path}/{name}'
try: try:
self.zipimporter.get_data(path) self.zipimporter.get_data(path)
except OSError: except OSError:
......
import unittest import unittest
from importlib import resources from importlib import import_module, resources
from . import data01 from . import data01
from . import util from . import util
...@@ -46,7 +46,16 @@ class ReadDiskTests(ReadTests, unittest.TestCase): ...@@ -46,7 +46,16 @@ class ReadDiskTests(ReadTests, unittest.TestCase):
class ReadZipTests(ReadTests, util.ZipSetup, unittest.TestCase): class ReadZipTests(ReadTests, util.ZipSetup, unittest.TestCase):
pass def test_read_submodule_resource(self):
submodule = import_module('ziptestdata.subdirectory')
result = resources.read_binary(
submodule, 'binary.file')
self.assertEqual(result, b'\0\1\2\3')
def test_read_submodule_resource_by_name(self):
result = resources.read_binary(
'ziptestdata.subdirectory', 'binary.file')
self.assertEqual(result, b'\0\1\2\3')
if __name__ == '__main__': if __name__ == '__main__':
......
...@@ -4,7 +4,7 @@ import unittest ...@@ -4,7 +4,7 @@ import unittest
from . import data01 from . import data01
from . import zipdata02 from . import zipdata02
from . import util from . import util
from importlib import resources from importlib import resources, import_module
class ResourceTests: class ResourceTests:
...@@ -109,6 +109,26 @@ class ResourceFromZipsTest(util.ZipSetupBase, unittest.TestCase): ...@@ -109,6 +109,26 @@ class ResourceFromZipsTest(util.ZipSetupBase, unittest.TestCase):
set(resources.contents('ziptestdata.two')), set(resources.contents('ziptestdata.two')),
{'__init__.py', 'resource2.txt'}) {'__init__.py', 'resource2.txt'})
def test_is_submodule_resource(self):
submodule = import_module('ziptestdata.subdirectory')
self.assertTrue(
resources.is_resource(submodule, 'binary.file'))
def test_read_submodule_resource_by_name(self):
self.assertTrue(
resources.is_resource('ziptestdata.subdirectory', 'binary.file'))
def test_submodule_contents(self):
submodule = import_module('ziptestdata.subdirectory')
self.assertEqual(
set(resources.contents(submodule)),
{'__init__.py', 'binary.file'})
def test_submodule_contents_by_name(self):
self.assertEqual(
set(resources.contents('ziptestdata.subdirectory')),
{'__init__.py', 'binary.file'})
class NamespaceTest(unittest.TestCase): class NamespaceTest(unittest.TestCase):
def test_namespaces_cant_have_resources(self): def test_namespaces_cant_have_resources(self):
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment