python (3.12.0)
1 import abc
2 import importlib
3 import io
4 import sys
5 import types
6 import pathlib
7
8 from . import data01
9 from . import zipdata01
10 from importlib.resources.abc import ResourceReader
11 from test.support import import_helper
12
13
14 from importlib.machinery import ModuleSpec
15
16
17 class ESC[4;38;5;81mReader(ESC[4;38;5;149mResourceReader):
18 def __init__(self, **kwargs):
19 vars(self).update(kwargs)
20
21 def get_resource_reader(self, package):
22 return self
23
24 def open_resource(self, path):
25 self._path = path
26 if isinstance(self.file, Exception):
27 raise self.file
28 return self.file
29
30 def resource_path(self, path_):
31 self._path = path_
32 if isinstance(self.path, Exception):
33 raise self.path
34 return self.path
35
36 def is_resource(self, path_):
37 self._path = path_
38 if isinstance(self.path, Exception):
39 raise self.path
40
41 def part(entry):
42 return entry.split('/')
43
44 return any(
45 len(parts) == 1 and parts[0] == path_ for parts in map(part, self._contents)
46 )
47
48 def contents(self):
49 if isinstance(self.path, Exception):
50 raise self.path
51 yield from self._contents
52
53
54 def create_package_from_loader(loader, is_package=True):
55 name = 'testingpackage'
56 module = types.ModuleType(name)
57 spec = ModuleSpec(name, loader, origin='does-not-exist', is_package=is_package)
58 module.__spec__ = spec
59 module.__loader__ = loader
60 return module
61
62
63 def create_package(file=None, path=None, is_package=True, contents=()):
64 return create_package_from_loader(
65 Reader(file=file, path=path, _contents=contents),
66 is_package,
67 )
68
69
70 class ESC[4;38;5;81mCommonTests(metaclass=ESC[4;38;5;149mabcESC[4;38;5;149m.ESC[4;38;5;149mABCMeta):
71 """
72 Tests shared by test_open, test_path, and test_read.
73 """
74
75 @abc.abstractmethod
76 def execute(self, package, path):
77 """
78 Call the pertinent legacy API function (e.g. open_text, path)
79 on package and path.
80 """
81
82 def test_package_name(self):
83 """
84 Passing in the package name should succeed.
85 """
86 self.execute(data01.__name__, 'utf-8.file')
87
88 def test_package_object(self):
89 """
90 Passing in the package itself should succeed.
91 """
92 self.execute(data01, 'utf-8.file')
93
94 def test_string_path(self):
95 """
96 Passing in a string for the path should succeed.
97 """
98 path = 'utf-8.file'
99 self.execute(data01, path)
100
101 def test_pathlib_path(self):
102 """
103 Passing in a pathlib.PurePath object for the path should succeed.
104 """
105 path = pathlib.PurePath('utf-8.file')
106 self.execute(data01, path)
107
108 def test_importing_module_as_side_effect(self):
109 """
110 The anchor package can already be imported.
111 """
112 del sys.modules[data01.__name__]
113 self.execute(data01.__name__, 'utf-8.file')
114
115 def test_missing_path(self):
116 """
117 Attempting to open or read or request the path for a
118 non-existent path should succeed if open_resource
119 can return a viable data stream.
120 """
121 bytes_data = io.BytesIO(b'Hello, world!')
122 package = create_package(file=bytes_data, path=FileNotFoundError())
123 self.execute(package, 'utf-8.file')
124 self.assertEqual(package.__loader__._path, 'utf-8.file')
125
126 def test_extant_path(self):
127 # Attempting to open or read or request the path when the
128 # path does exist should still succeed. Does not assert
129 # anything about the result.
130 bytes_data = io.BytesIO(b'Hello, world!')
131 # any path that exists
132 path = __file__
133 package = create_package(file=bytes_data, path=path)
134 self.execute(package, 'utf-8.file')
135 self.assertEqual(package.__loader__._path, 'utf-8.file')
136
137 def test_useless_loader(self):
138 package = create_package(file=FileNotFoundError(), path=FileNotFoundError())
139 with self.assertRaises(FileNotFoundError):
140 self.execute(package, 'utf-8.file')
141
142
143 class ESC[4;38;5;81mZipSetupBase:
144 ZIP_MODULE = None
145
146 @classmethod
147 def setUpClass(cls):
148 data_path = pathlib.Path(cls.ZIP_MODULE.__file__)
149 data_dir = data_path.parent
150 cls._zip_path = str(data_dir / 'ziptestdata.zip')
151 sys.path.append(cls._zip_path)
152 cls.data = importlib.import_module('ziptestdata')
153
154 @classmethod
155 def tearDownClass(cls):
156 try:
157 sys.path.remove(cls._zip_path)
158 except ValueError:
159 pass
160
161 try:
162 del sys.path_importer_cache[cls._zip_path]
163 del sys.modules[cls.data.__name__]
164 except KeyError:
165 pass
166
167 try:
168 del cls.data
169 del cls._zip_path
170 except AttributeError:
171 pass
172
173 def setUp(self):
174 modules = import_helper.modules_setup()
175 self.addCleanup(import_helper.modules_cleanup, *modules)
176
177
178 class ESC[4;38;5;81mZipSetup(ESC[4;38;5;149mZipSetupBase):
179 ZIP_MODULE = zipdata01 # type: ignore