Skip to content

Convert static zip fixtures to proper fixtures derived from disk-based fixtures. #288

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Sep 19, 2023
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
6 changes: 2 additions & 4 deletions importlib_resources/tests/test_read.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,15 +58,13 @@ class ReadDiskTests(ReadTests, unittest.TestCase):

class ReadZipTests(ReadTests, util.ZipSetup, unittest.TestCase):
def test_read_submodule_resource(self):
submodule = import_module('ziptestdata.subdirectory')
submodule = import_module('data01.subdirectory')
result = resources.files(submodule).joinpath('binary.file').read_bytes()
self.assertEqual(result, b'\0\1\2\3')

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

Expand Down
101 changes: 31 additions & 70 deletions importlib_resources/tests/test_resource.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
import contextlib
import sys
import unittest
import importlib_resources as resources
import uuid
import pathlib

from . import data01
from . import zipdata01, zipdata02
from . import util
from importlib import import_module
from ._compat import import_helper, os_helper, unlink


class ResourceTests:
Expand Down Expand Up @@ -89,136 +85,89 @@ def test_package_has_no_reader_fallback(self):


class ResourceFromZipsTest01(util.ZipSetupBase, unittest.TestCase):
ZIP_MODULE = zipdata01 # type: ignore
ZIP_MODULE = 'data01'

def test_is_submodule_resource(self):
submodule = import_module('ziptestdata.subdirectory')
submodule = import_module('data01.subdirectory')
self.assertTrue(resources.files(submodule).joinpath('binary.file').is_file())

def test_read_submodule_resource_by_name(self):
self.assertTrue(
resources.files('ziptestdata.subdirectory')
.joinpath('binary.file')
.is_file()
resources.files('data01.subdirectory').joinpath('binary.file').is_file()
)

def test_submodule_contents(self):
submodule = import_module('ziptestdata.subdirectory')
submodule = import_module('data01.subdirectory')
self.assertEqual(
names(resources.files(submodule)), {'__init__.py', 'binary.file'}
)

def test_submodule_contents_by_name(self):
self.assertEqual(
names(resources.files('ziptestdata.subdirectory')),
names(resources.files('data01.subdirectory')),
{'__init__.py', 'binary.file'},
)

def test_as_file_directory(self):
with resources.as_file(resources.files('ziptestdata')) as data:
assert data.name == 'ziptestdata'
with resources.as_file(resources.files('data01')) as data:
assert data.name == 'data01'
assert data.is_dir()
assert data.joinpath('subdirectory').is_dir()
assert len(list(data.iterdir()))
assert not data.parent.exists()


class ResourceFromZipsTest02(util.ZipSetupBase, unittest.TestCase):
ZIP_MODULE = zipdata02 # type: ignore
ZIP_MODULE = 'data02'

def test_unrelated_contents(self):
"""
Test thata zip with two unrelated subpackages return
distinct resources. Ref python/importlib_resources#44.
"""
self.assertEqual(
names(resources.files('ziptestdata.one')),
names(resources.files('data02.one')),
{'__init__.py', 'resource1.txt'},
)
self.assertEqual(
names(resources.files('ziptestdata.two')),
names(resources.files('data02.two')),
{'__init__.py', 'resource2.txt'},
)


@contextlib.contextmanager
def zip_on_path(dir):
data_path = pathlib.Path(zipdata01.__file__)
source_zip_path = data_path.parent.joinpath('ziptestdata.zip')
zip_path = pathlib.Path(dir) / f'{uuid.uuid4()}.zip'
zip_path.write_bytes(source_zip_path.read_bytes())
sys.path.append(str(zip_path))
import_module('ziptestdata')

try:
yield
finally:
with contextlib.suppress(ValueError):
sys.path.remove(str(zip_path))

with contextlib.suppress(KeyError):
del sys.path_importer_cache[str(zip_path)]
del sys.modules['ziptestdata']

with contextlib.suppress(OSError):
unlink(zip_path)


class DeletingZipsTest(unittest.TestCase):
class DeletingZipsTest(util.ZipSetupBase, unittest.TestCase):
"""Having accessed resources in a zip file should not keep an open
reference to the zip.
"""

def setUp(self):
self.fixtures = contextlib.ExitStack()
self.addCleanup(self.fixtures.close)

modules = import_helper.modules_setup()
self.addCleanup(import_helper.modules_cleanup, *modules)

temp_dir = self.fixtures.enter_context(os_helper.temp_dir())
self.fixtures.enter_context(zip_on_path(temp_dir))

def test_iterdir_does_not_keep_open(self):
[item.name for item in resources.files('ziptestdata').iterdir()]
[item.name for item in resources.files('data01').iterdir()]

def test_is_file_does_not_keep_open(self):
resources.files('ziptestdata').joinpath('binary.file').is_file()
resources.files('data01').joinpath('binary.file').is_file()

def test_is_file_failure_does_not_keep_open(self):
resources.files('ziptestdata').joinpath('not-present').is_file()
resources.files('data01').joinpath('not-present').is_file()

@unittest.skip("Desired but not supported.")
def test_as_file_does_not_keep_open(self): # pragma: no cover
resources.as_file(resources.files('ziptestdata') / 'binary.file')
resources.as_file(resources.files('data01') / 'binary.file')

def test_entered_path_does_not_keep_open(self):
"""
Mimic what certifi does on import to make its bundle
available for the process duration.
"""
resources.as_file(resources.files('ziptestdata') / 'binary.file').__enter__()
resources.as_file(resources.files('data01') / 'binary.file').__enter__()

def test_read_binary_does_not_keep_open(self):
resources.files('ziptestdata').joinpath('binary.file').read_bytes()
resources.files('data01').joinpath('binary.file').read_bytes()

def test_read_text_does_not_keep_open(self):
resources.files('ziptestdata').joinpath('utf-8.file').read_text(
encoding='utf-8'
)

resources.files('data01').joinpath('utf-8.file').read_text(encoding='utf-8')

class ResourceFromNamespaceTest01(unittest.TestCase):
site_dir = str(pathlib.Path(__file__).parent)

@classmethod
def setUpClass(cls):
sys.path.append(cls.site_dir)

@classmethod
def tearDownClass(cls):
sys.path.remove(cls.site_dir)

class ResourceFromNamespaceTests:
def test_is_submodule_resource(self):
self.assertTrue(
resources.files(import_module('namespacedata01'))
Expand Down Expand Up @@ -248,5 +197,17 @@ def test_submodule_contents_by_name(self):
self.assertEqual(contents, {'binary.file', 'utf-8.file', 'utf-16.file'})


class ResourceFromNamespaceDiskTests(ResourceFromNamespaceTests, unittest.TestCase):
site_dir = str(pathlib.Path(__file__).parent)

@classmethod
def setUpClass(cls):
sys.path.append(cls.site_dir)

@classmethod
def tearDownClass(cls):
sys.path.remove(cls.site_dir)


if __name__ == '__main__':
unittest.main()
53 changes: 0 additions & 53 deletions importlib_resources/tests/update-zips.py

This file was deleted.

48 changes: 17 additions & 31 deletions importlib_resources/tests/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@
import sys
import types
import pathlib
import contextlib

from . import data01
from . import zipdata01
from ..abc import ResourceReader
from ._compat import import_helper
from ._compat import import_helper, os_helper
from . import zip as zip_


from importlib.machinery import ModuleSpec
Expand Down Expand Up @@ -141,39 +142,24 @@ def test_useless_loader(self):


class ZipSetupBase:
ZIP_MODULE = None

@classmethod
def setUpClass(cls):
data_path = pathlib.Path(cls.ZIP_MODULE.__file__)
data_dir = data_path.parent
cls._zip_path = str(data_dir / 'ziptestdata.zip')
sys.path.append(cls._zip_path)
cls.data = importlib.import_module('ziptestdata')

@classmethod
def tearDownClass(cls):
try:
sys.path.remove(cls._zip_path)
except ValueError:
pass

try:
del sys.path_importer_cache[cls._zip_path]
del sys.modules[cls.data.__name__]
except KeyError:
pass

try:
del cls.data
del cls._zip_path
except AttributeError:
pass
ZIP_MODULE = 'data01'

def setUp(self):
self.fixtures = contextlib.ExitStack()
self.addCleanup(self.fixtures.close)

modules = import_helper.modules_setup()
self.addCleanup(import_helper.modules_cleanup, *modules)

temp_dir = self.fixtures.enter_context(os_helper.temp_dir())
modules = pathlib.Path(temp_dir) / 'zipped modules.zip'
src_path = pathlib.Path(__file__).parent.joinpath(self.ZIP_MODULE)
self.fixtures.enter_context(
import_helper.DirsOnSysPath(str(zip_.make_zip_file(src_path, modules)))
)

self.data = importlib.import_module(self.ZIP_MODULE)


class ZipSetup(ZipSetupBase):
ZIP_MODULE = zipdata01 # type: ignore
pass
32 changes: 32 additions & 0 deletions importlib_resources/tests/zip.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
"""
Generate zip test data files.
"""

import contextlib
import os
import pathlib
import zipfile

import zipp


def make_zip_file(src, dst):
"""
Zip the files in src into a new zipfile at dst.
"""
with zipfile.ZipFile(dst, 'w') as zf:
for src_path, rel in walk(src):
dst_name = src.name / pathlib.PurePosixPath(rel.as_posix())
zf.write(src_path, dst_name)
zipp.CompleteDirs.inject(zf)
return dst


def walk(datapath):
for dirpath, dirnames, filenames in os.walk(datapath):
with contextlib.suppress(ValueError):
dirnames.remove('__pycache__')
for filename in filenames:
res = pathlib.Path(dirpath) / filename
rel = res.relative_to(datapath)
yield res, rel
Empty file.
Binary file removed importlib_resources/tests/zipdata01/ziptestdata.zip
Binary file not shown.
Empty file.
Binary file removed importlib_resources/tests/zipdata02/ziptestdata.zip
Binary file not shown.
1 change: 1 addition & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ testing =
pytest-ruff

# local
zipp >= 3.17

docs =
# upstream
Expand Down