1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
|
import textwrap
import unittest
import warnings
import importlib
import contextlib
from importlib import resources
from importlib.resources.abc import Traversable
from . import util
@contextlib.contextmanager
def suppress_known_deprecation():
with warnings.catch_warnings(record=True) as ctx:
warnings.simplefilter('default', category=DeprecationWarning)
yield ctx
class FilesTests:
def test_read_bytes(self):
files = resources.files(self.data)
actual = files.joinpath('utf-8.file').read_bytes()
assert actual == b'Hello, UTF-8 world!\n'
def test_read_text(self):
files = resources.files(self.data)
actual = files.joinpath('utf-8.file').read_text(encoding='utf-8')
assert actual == 'Hello, UTF-8 world!\n'
def test_traversable(self):
assert isinstance(resources.files(self.data), Traversable)
def test_joinpath_with_multiple_args(self):
files = resources.files(self.data)
binfile = files.joinpath('subdirectory', 'binary.file')
self.assertTrue(binfile.is_file())
def test_old_parameter(self):
"""
Files used to take a 'package' parameter. Make sure anyone
passing by name is still supported.
"""
with suppress_known_deprecation():
resources.files(package=self.data)
class OpenDiskTests(FilesTests, util.DiskSetup, unittest.TestCase):
pass
class OpenZipTests(FilesTests, util.ZipSetup, unittest.TestCase):
pass
class OpenNamespaceTests(FilesTests, util.DiskSetup, unittest.TestCase):
MODULE = 'namespacedata01'
def test_non_paths_in_dunder_path(self):
"""
Non-path items in a namespace package's ``__path__`` are ignored.
As reported in python/importlib_resources#311, some tools
like Setuptools, when creating editable packages, will inject
non-paths into a namespace package's ``__path__``, a
sentinel like
``__editable__.sample_namespace-1.0.finder.__path_hook__``
to cause the ``PathEntryFinder`` to be called when searching
for packages. In that case, resources should still be loadable.
"""
import namespacedata01
namespacedata01.__path__.append(
'__editable__.sample_namespace-1.0.finder.__path_hook__'
)
resources.files(namespacedata01)
class OpenNamespaceZipTests(FilesTests, util.ZipSetup, unittest.TestCase):
ZIP_MODULE = 'namespacedata01'
class DirectSpec:
"""
Override behavior of ModuleSetup to write a full spec directly.
"""
MODULE = 'unused'
def load_fixture(self, name):
self.tree_on_path(self.spec)
class ModulesFiles:
spec = {
'mod.py': '',
'res.txt': 'resources are the best',
}
def test_module_resources(self):
"""
A module can have resources found adjacent to the module.
"""
import mod # type: ignore[import-not-found]
actual = resources.files(mod).joinpath('res.txt').read_text(encoding='utf-8')
assert actual == self.spec['res.txt']
class ModuleFilesDiskTests(DirectSpec, util.DiskSetup, ModulesFiles, unittest.TestCase):
pass
class ModuleFilesZipTests(DirectSpec, util.ZipSetup, ModulesFiles, unittest.TestCase):
pass
class ImplicitContextFiles:
set_val = textwrap.dedent(
"""
import importlib.resources as res
val = res.files().joinpath('res.txt').read_text(encoding='utf-8')
"""
)
spec = {
'somepkg': {
'__init__.py': set_val,
'submod.py': set_val,
'res.txt': 'resources are the best',
},
}
def test_implicit_files_package(self):
"""
Without any parameter, files() will infer the location as the caller.
"""
assert importlib.import_module('somepkg').val == 'resources are the best'
def test_implicit_files_submodule(self):
"""
Without any parameter, files() will infer the location as the caller.
"""
assert importlib.import_module('somepkg.submod').val == 'resources are the best'
class ImplicitContextFilesDiskTests(
DirectSpec, util.DiskSetup, ImplicitContextFiles, unittest.TestCase
):
pass
class ImplicitContextFilesZipTests(
DirectSpec, util.ZipSetup, ImplicitContextFiles, unittest.TestCase
):
pass
if __name__ == '__main__':
unittest.main()
|