1 | n/a | import io |
---|
2 | n/a | import marshal |
---|
3 | n/a | import os |
---|
4 | n/a | import sys |
---|
5 | n/a | from test import support |
---|
6 | n/a | import types |
---|
7 | n/a | import unittest |
---|
8 | n/a | from unittest import mock |
---|
9 | n/a | import warnings |
---|
10 | n/a | |
---|
11 | n/a | from . import util as test_util |
---|
12 | n/a | |
---|
13 | n/a | init = test_util.import_importlib('importlib') |
---|
14 | n/a | abc = test_util.import_importlib('importlib.abc') |
---|
15 | n/a | machinery = test_util.import_importlib('importlib.machinery') |
---|
16 | n/a | util = test_util.import_importlib('importlib.util') |
---|
17 | n/a | |
---|
18 | n/a | |
---|
19 | n/a | ##### Inheritance ############################################################## |
---|
20 | n/a | class InheritanceTests: |
---|
21 | n/a | |
---|
22 | n/a | """Test that the specified class is a subclass/superclass of the expected |
---|
23 | n/a | classes.""" |
---|
24 | n/a | |
---|
25 | n/a | subclasses = [] |
---|
26 | n/a | superclasses = [] |
---|
27 | n/a | |
---|
28 | n/a | def setUp(self): |
---|
29 | n/a | self.superclasses = [getattr(self.abc, class_name) |
---|
30 | n/a | for class_name in self.superclass_names] |
---|
31 | n/a | if hasattr(self, 'subclass_names'): |
---|
32 | n/a | # Because test.support.import_fresh_module() creates a new |
---|
33 | n/a | # importlib._bootstrap per module, inheritance checks fail when |
---|
34 | n/a | # checking across module boundaries (i.e. the _bootstrap in abc is |
---|
35 | n/a | # not the same as the one in machinery). That means stealing one of |
---|
36 | n/a | # the modules from the other to make sure the same instance is used. |
---|
37 | n/a | machinery = self.abc.machinery |
---|
38 | n/a | self.subclasses = [getattr(machinery, class_name) |
---|
39 | n/a | for class_name in self.subclass_names] |
---|
40 | n/a | assert self.subclasses or self.superclasses, self.__class__ |
---|
41 | n/a | self.__test = getattr(self.abc, self._NAME) |
---|
42 | n/a | |
---|
43 | n/a | def test_subclasses(self): |
---|
44 | n/a | # Test that the expected subclasses inherit. |
---|
45 | n/a | for subclass in self.subclasses: |
---|
46 | n/a | self.assertTrue(issubclass(subclass, self.__test), |
---|
47 | n/a | "{0} is not a subclass of {1}".format(subclass, self.__test)) |
---|
48 | n/a | |
---|
49 | n/a | def test_superclasses(self): |
---|
50 | n/a | # Test that the class inherits from the expected superclasses. |
---|
51 | n/a | for superclass in self.superclasses: |
---|
52 | n/a | self.assertTrue(issubclass(self.__test, superclass), |
---|
53 | n/a | "{0} is not a superclass of {1}".format(superclass, self.__test)) |
---|
54 | n/a | |
---|
55 | n/a | |
---|
56 | n/a | class MetaPathFinder(InheritanceTests): |
---|
57 | n/a | superclass_names = ['Finder'] |
---|
58 | n/a | subclass_names = ['BuiltinImporter', 'FrozenImporter', 'PathFinder', |
---|
59 | n/a | 'WindowsRegistryFinder'] |
---|
60 | n/a | |
---|
61 | n/a | |
---|
62 | n/a | (Frozen_MetaPathFinderInheritanceTests, |
---|
63 | n/a | Source_MetaPathFinderInheritanceTests |
---|
64 | n/a | ) = test_util.test_both(MetaPathFinder, abc=abc) |
---|
65 | n/a | |
---|
66 | n/a | |
---|
67 | n/a | class PathEntryFinder(InheritanceTests): |
---|
68 | n/a | superclass_names = ['Finder'] |
---|
69 | n/a | subclass_names = ['FileFinder'] |
---|
70 | n/a | |
---|
71 | n/a | |
---|
72 | n/a | (Frozen_PathEntryFinderInheritanceTests, |
---|
73 | n/a | Source_PathEntryFinderInheritanceTests |
---|
74 | n/a | ) = test_util.test_both(PathEntryFinder, abc=abc) |
---|
75 | n/a | |
---|
76 | n/a | |
---|
77 | n/a | class ResourceLoader(InheritanceTests): |
---|
78 | n/a | superclass_names = ['Loader'] |
---|
79 | n/a | |
---|
80 | n/a | |
---|
81 | n/a | (Frozen_ResourceLoaderInheritanceTests, |
---|
82 | n/a | Source_ResourceLoaderInheritanceTests |
---|
83 | n/a | ) = test_util.test_both(ResourceLoader, abc=abc) |
---|
84 | n/a | |
---|
85 | n/a | |
---|
86 | n/a | class InspectLoader(InheritanceTests): |
---|
87 | n/a | superclass_names = ['Loader'] |
---|
88 | n/a | subclass_names = ['BuiltinImporter', 'FrozenImporter', 'ExtensionFileLoader'] |
---|
89 | n/a | |
---|
90 | n/a | |
---|
91 | n/a | (Frozen_InspectLoaderInheritanceTests, |
---|
92 | n/a | Source_InspectLoaderInheritanceTests |
---|
93 | n/a | ) = test_util.test_both(InspectLoader, abc=abc) |
---|
94 | n/a | |
---|
95 | n/a | |
---|
96 | n/a | class ExecutionLoader(InheritanceTests): |
---|
97 | n/a | superclass_names = ['InspectLoader'] |
---|
98 | n/a | subclass_names = ['ExtensionFileLoader'] |
---|
99 | n/a | |
---|
100 | n/a | |
---|
101 | n/a | (Frozen_ExecutionLoaderInheritanceTests, |
---|
102 | n/a | Source_ExecutionLoaderInheritanceTests |
---|
103 | n/a | ) = test_util.test_both(ExecutionLoader, abc=abc) |
---|
104 | n/a | |
---|
105 | n/a | |
---|
106 | n/a | class FileLoader(InheritanceTests): |
---|
107 | n/a | superclass_names = ['ResourceLoader', 'ExecutionLoader'] |
---|
108 | n/a | subclass_names = ['SourceFileLoader', 'SourcelessFileLoader'] |
---|
109 | n/a | |
---|
110 | n/a | |
---|
111 | n/a | (Frozen_FileLoaderInheritanceTests, |
---|
112 | n/a | Source_FileLoaderInheritanceTests |
---|
113 | n/a | ) = test_util.test_both(FileLoader, abc=abc) |
---|
114 | n/a | |
---|
115 | n/a | |
---|
116 | n/a | class SourceLoader(InheritanceTests): |
---|
117 | n/a | superclass_names = ['ResourceLoader', 'ExecutionLoader'] |
---|
118 | n/a | subclass_names = ['SourceFileLoader'] |
---|
119 | n/a | |
---|
120 | n/a | |
---|
121 | n/a | (Frozen_SourceLoaderInheritanceTests, |
---|
122 | n/a | Source_SourceLoaderInheritanceTests |
---|
123 | n/a | ) = test_util.test_both(SourceLoader, abc=abc) |
---|
124 | n/a | |
---|
125 | n/a | |
---|
126 | n/a | ##### Default return values #################################################### |
---|
127 | n/a | |
---|
128 | n/a | def make_abc_subclasses(base_class, name=None, inst=False, **kwargs): |
---|
129 | n/a | if name is None: |
---|
130 | n/a | name = base_class.__name__ |
---|
131 | n/a | base = {kind: getattr(splitabc, name) |
---|
132 | n/a | for kind, splitabc in abc.items()} |
---|
133 | n/a | return {cls._KIND: cls() if inst else cls |
---|
134 | n/a | for cls in test_util.split_frozen(base_class, base, **kwargs)} |
---|
135 | n/a | |
---|
136 | n/a | |
---|
137 | n/a | class ABCTestHarness: |
---|
138 | n/a | |
---|
139 | n/a | @property |
---|
140 | n/a | def ins(self): |
---|
141 | n/a | # Lazily set ins on the class. |
---|
142 | n/a | cls = self.SPLIT[self._KIND] |
---|
143 | n/a | ins = cls() |
---|
144 | n/a | self.__class__.ins = ins |
---|
145 | n/a | return ins |
---|
146 | n/a | |
---|
147 | n/a | |
---|
148 | n/a | class MetaPathFinder: |
---|
149 | n/a | |
---|
150 | n/a | def find_module(self, fullname, path): |
---|
151 | n/a | return super().find_module(fullname, path) |
---|
152 | n/a | |
---|
153 | n/a | |
---|
154 | n/a | class MetaPathFinderDefaultsTests(ABCTestHarness): |
---|
155 | n/a | |
---|
156 | n/a | SPLIT = make_abc_subclasses(MetaPathFinder) |
---|
157 | n/a | |
---|
158 | n/a | def test_find_module(self): |
---|
159 | n/a | # Default should return None. |
---|
160 | n/a | self.assertIsNone(self.ins.find_module('something', None)) |
---|
161 | n/a | |
---|
162 | n/a | def test_invalidate_caches(self): |
---|
163 | n/a | # Calling the method is a no-op. |
---|
164 | n/a | self.ins.invalidate_caches() |
---|
165 | n/a | |
---|
166 | n/a | |
---|
167 | n/a | (Frozen_MPFDefaultTests, |
---|
168 | n/a | Source_MPFDefaultTests |
---|
169 | n/a | ) = test_util.test_both(MetaPathFinderDefaultsTests) |
---|
170 | n/a | |
---|
171 | n/a | |
---|
172 | n/a | class PathEntryFinder: |
---|
173 | n/a | |
---|
174 | n/a | def find_loader(self, fullname): |
---|
175 | n/a | return super().find_loader(fullname) |
---|
176 | n/a | |
---|
177 | n/a | |
---|
178 | n/a | class PathEntryFinderDefaultsTests(ABCTestHarness): |
---|
179 | n/a | |
---|
180 | n/a | SPLIT = make_abc_subclasses(PathEntryFinder) |
---|
181 | n/a | |
---|
182 | n/a | def test_find_loader(self): |
---|
183 | n/a | self.assertEqual((None, []), self.ins.find_loader('something')) |
---|
184 | n/a | |
---|
185 | n/a | def find_module(self): |
---|
186 | n/a | self.assertEqual(None, self.ins.find_module('something')) |
---|
187 | n/a | |
---|
188 | n/a | def test_invalidate_caches(self): |
---|
189 | n/a | # Should be a no-op. |
---|
190 | n/a | self.ins.invalidate_caches() |
---|
191 | n/a | |
---|
192 | n/a | |
---|
193 | n/a | (Frozen_PEFDefaultTests, |
---|
194 | n/a | Source_PEFDefaultTests |
---|
195 | n/a | ) = test_util.test_both(PathEntryFinderDefaultsTests) |
---|
196 | n/a | |
---|
197 | n/a | |
---|
198 | n/a | class Loader: |
---|
199 | n/a | |
---|
200 | n/a | def load_module(self, fullname): |
---|
201 | n/a | return super().load_module(fullname) |
---|
202 | n/a | |
---|
203 | n/a | |
---|
204 | n/a | class LoaderDefaultsTests(ABCTestHarness): |
---|
205 | n/a | |
---|
206 | n/a | SPLIT = make_abc_subclasses(Loader) |
---|
207 | n/a | |
---|
208 | n/a | def test_create_module(self): |
---|
209 | n/a | spec = 'a spec' |
---|
210 | n/a | self.assertIsNone(self.ins.create_module(spec)) |
---|
211 | n/a | |
---|
212 | n/a | def test_load_module(self): |
---|
213 | n/a | with self.assertRaises(ImportError): |
---|
214 | n/a | self.ins.load_module('something') |
---|
215 | n/a | |
---|
216 | n/a | def test_module_repr(self): |
---|
217 | n/a | mod = types.ModuleType('blah') |
---|
218 | n/a | with self.assertRaises(NotImplementedError): |
---|
219 | n/a | self.ins.module_repr(mod) |
---|
220 | n/a | original_repr = repr(mod) |
---|
221 | n/a | mod.__loader__ = self.ins |
---|
222 | n/a | # Should still return a proper repr. |
---|
223 | n/a | self.assertTrue(repr(mod)) |
---|
224 | n/a | |
---|
225 | n/a | |
---|
226 | n/a | (Frozen_LDefaultTests, |
---|
227 | n/a | SourceLDefaultTests |
---|
228 | n/a | ) = test_util.test_both(LoaderDefaultsTests) |
---|
229 | n/a | |
---|
230 | n/a | |
---|
231 | n/a | class ResourceLoader(Loader): |
---|
232 | n/a | |
---|
233 | n/a | def get_data(self, path): |
---|
234 | n/a | return super().get_data(path) |
---|
235 | n/a | |
---|
236 | n/a | |
---|
237 | n/a | class ResourceLoaderDefaultsTests(ABCTestHarness): |
---|
238 | n/a | |
---|
239 | n/a | SPLIT = make_abc_subclasses(ResourceLoader) |
---|
240 | n/a | |
---|
241 | n/a | def test_get_data(self): |
---|
242 | n/a | with self.assertRaises(IOError): |
---|
243 | n/a | self.ins.get_data('/some/path') |
---|
244 | n/a | |
---|
245 | n/a | |
---|
246 | n/a | (Frozen_RLDefaultTests, |
---|
247 | n/a | Source_RLDefaultTests |
---|
248 | n/a | ) = test_util.test_both(ResourceLoaderDefaultsTests) |
---|
249 | n/a | |
---|
250 | n/a | |
---|
251 | n/a | class InspectLoader(Loader): |
---|
252 | n/a | |
---|
253 | n/a | def is_package(self, fullname): |
---|
254 | n/a | return super().is_package(fullname) |
---|
255 | n/a | |
---|
256 | n/a | def get_source(self, fullname): |
---|
257 | n/a | return super().get_source(fullname) |
---|
258 | n/a | |
---|
259 | n/a | |
---|
260 | n/a | SPLIT_IL = make_abc_subclasses(InspectLoader) |
---|
261 | n/a | |
---|
262 | n/a | |
---|
263 | n/a | class InspectLoaderDefaultsTests(ABCTestHarness): |
---|
264 | n/a | |
---|
265 | n/a | SPLIT = SPLIT_IL |
---|
266 | n/a | |
---|
267 | n/a | def test_is_package(self): |
---|
268 | n/a | with self.assertRaises(ImportError): |
---|
269 | n/a | self.ins.is_package('blah') |
---|
270 | n/a | |
---|
271 | n/a | def test_get_source(self): |
---|
272 | n/a | with self.assertRaises(ImportError): |
---|
273 | n/a | self.ins.get_source('blah') |
---|
274 | n/a | |
---|
275 | n/a | |
---|
276 | n/a | (Frozen_ILDefaultTests, |
---|
277 | n/a | Source_ILDefaultTests |
---|
278 | n/a | ) = test_util.test_both(InspectLoaderDefaultsTests) |
---|
279 | n/a | |
---|
280 | n/a | |
---|
281 | n/a | class ExecutionLoader(InspectLoader): |
---|
282 | n/a | |
---|
283 | n/a | def get_filename(self, fullname): |
---|
284 | n/a | return super().get_filename(fullname) |
---|
285 | n/a | |
---|
286 | n/a | |
---|
287 | n/a | SPLIT_EL = make_abc_subclasses(ExecutionLoader) |
---|
288 | n/a | |
---|
289 | n/a | |
---|
290 | n/a | class ExecutionLoaderDefaultsTests(ABCTestHarness): |
---|
291 | n/a | |
---|
292 | n/a | SPLIT = SPLIT_EL |
---|
293 | n/a | |
---|
294 | n/a | def test_get_filename(self): |
---|
295 | n/a | with self.assertRaises(ImportError): |
---|
296 | n/a | self.ins.get_filename('blah') |
---|
297 | n/a | |
---|
298 | n/a | |
---|
299 | n/a | (Frozen_ELDefaultTests, |
---|
300 | n/a | Source_ELDefaultsTests |
---|
301 | n/a | ) = test_util.test_both(InspectLoaderDefaultsTests) |
---|
302 | n/a | |
---|
303 | n/a | |
---|
304 | n/a | ##### MetaPathFinder concrete methods ########################################## |
---|
305 | n/a | class MetaPathFinderFindModuleTests: |
---|
306 | n/a | |
---|
307 | n/a | @classmethod |
---|
308 | n/a | def finder(cls, spec): |
---|
309 | n/a | class MetaPathSpecFinder(cls.abc.MetaPathFinder): |
---|
310 | n/a | |
---|
311 | n/a | def find_spec(self, fullname, path, target=None): |
---|
312 | n/a | self.called_for = fullname, path |
---|
313 | n/a | return spec |
---|
314 | n/a | |
---|
315 | n/a | return MetaPathSpecFinder() |
---|
316 | n/a | |
---|
317 | n/a | def test_no_spec(self): |
---|
318 | n/a | finder = self.finder(None) |
---|
319 | n/a | path = ['a', 'b', 'c'] |
---|
320 | n/a | name = 'blah' |
---|
321 | n/a | found = finder.find_module(name, path) |
---|
322 | n/a | self.assertIsNone(found) |
---|
323 | n/a | self.assertEqual(name, finder.called_for[0]) |
---|
324 | n/a | self.assertEqual(path, finder.called_for[1]) |
---|
325 | n/a | |
---|
326 | n/a | def test_spec(self): |
---|
327 | n/a | loader = object() |
---|
328 | n/a | spec = self.util.spec_from_loader('blah', loader) |
---|
329 | n/a | finder = self.finder(spec) |
---|
330 | n/a | found = finder.find_module('blah', None) |
---|
331 | n/a | self.assertIs(found, spec.loader) |
---|
332 | n/a | |
---|
333 | n/a | |
---|
334 | n/a | (Frozen_MPFFindModuleTests, |
---|
335 | n/a | Source_MPFFindModuleTests |
---|
336 | n/a | ) = test_util.test_both(MetaPathFinderFindModuleTests, abc=abc, util=util) |
---|
337 | n/a | |
---|
338 | n/a | |
---|
339 | n/a | ##### PathEntryFinder concrete methods ######################################### |
---|
340 | n/a | class PathEntryFinderFindLoaderTests: |
---|
341 | n/a | |
---|
342 | n/a | @classmethod |
---|
343 | n/a | def finder(cls, spec): |
---|
344 | n/a | class PathEntrySpecFinder(cls.abc.PathEntryFinder): |
---|
345 | n/a | |
---|
346 | n/a | def find_spec(self, fullname, target=None): |
---|
347 | n/a | self.called_for = fullname |
---|
348 | n/a | return spec |
---|
349 | n/a | |
---|
350 | n/a | return PathEntrySpecFinder() |
---|
351 | n/a | |
---|
352 | n/a | def test_no_spec(self): |
---|
353 | n/a | finder = self.finder(None) |
---|
354 | n/a | name = 'blah' |
---|
355 | n/a | found = finder.find_loader(name) |
---|
356 | n/a | self.assertIsNone(found[0]) |
---|
357 | n/a | self.assertEqual([], found[1]) |
---|
358 | n/a | self.assertEqual(name, finder.called_for) |
---|
359 | n/a | |
---|
360 | n/a | def test_spec_with_loader(self): |
---|
361 | n/a | loader = object() |
---|
362 | n/a | spec = self.util.spec_from_loader('blah', loader) |
---|
363 | n/a | finder = self.finder(spec) |
---|
364 | n/a | found = finder.find_loader('blah') |
---|
365 | n/a | self.assertIs(found[0], spec.loader) |
---|
366 | n/a | |
---|
367 | n/a | def test_spec_with_portions(self): |
---|
368 | n/a | spec = self.machinery.ModuleSpec('blah', None) |
---|
369 | n/a | paths = ['a', 'b', 'c'] |
---|
370 | n/a | spec.submodule_search_locations = paths |
---|
371 | n/a | finder = self.finder(spec) |
---|
372 | n/a | found = finder.find_loader('blah') |
---|
373 | n/a | self.assertIsNone(found[0]) |
---|
374 | n/a | self.assertEqual(paths, found[1]) |
---|
375 | n/a | |
---|
376 | n/a | |
---|
377 | n/a | (Frozen_PEFFindLoaderTests, |
---|
378 | n/a | Source_PEFFindLoaderTests |
---|
379 | n/a | ) = test_util.test_both(PathEntryFinderFindLoaderTests, abc=abc, util=util, |
---|
380 | n/a | machinery=machinery) |
---|
381 | n/a | |
---|
382 | n/a | |
---|
383 | n/a | ##### Loader concrete methods ################################################## |
---|
384 | n/a | class LoaderLoadModuleTests: |
---|
385 | n/a | |
---|
386 | n/a | def loader(self): |
---|
387 | n/a | class SpecLoader(self.abc.Loader): |
---|
388 | n/a | found = None |
---|
389 | n/a | def exec_module(self, module): |
---|
390 | n/a | self.found = module |
---|
391 | n/a | |
---|
392 | n/a | def is_package(self, fullname): |
---|
393 | n/a | """Force some non-default module state to be set.""" |
---|
394 | n/a | return True |
---|
395 | n/a | |
---|
396 | n/a | return SpecLoader() |
---|
397 | n/a | |
---|
398 | n/a | def test_fresh(self): |
---|
399 | n/a | loader = self.loader() |
---|
400 | n/a | name = 'blah' |
---|
401 | n/a | with test_util.uncache(name): |
---|
402 | n/a | loader.load_module(name) |
---|
403 | n/a | module = loader.found |
---|
404 | n/a | self.assertIs(sys.modules[name], module) |
---|
405 | n/a | self.assertEqual(loader, module.__loader__) |
---|
406 | n/a | self.assertEqual(loader, module.__spec__.loader) |
---|
407 | n/a | self.assertEqual(name, module.__name__) |
---|
408 | n/a | self.assertEqual(name, module.__spec__.name) |
---|
409 | n/a | self.assertIsNotNone(module.__path__) |
---|
410 | n/a | self.assertIsNotNone(module.__path__, |
---|
411 | n/a | module.__spec__.submodule_search_locations) |
---|
412 | n/a | |
---|
413 | n/a | def test_reload(self): |
---|
414 | n/a | name = 'blah' |
---|
415 | n/a | loader = self.loader() |
---|
416 | n/a | module = types.ModuleType(name) |
---|
417 | n/a | module.__spec__ = self.util.spec_from_loader(name, loader) |
---|
418 | n/a | module.__loader__ = loader |
---|
419 | n/a | with test_util.uncache(name): |
---|
420 | n/a | sys.modules[name] = module |
---|
421 | n/a | loader.load_module(name) |
---|
422 | n/a | found = loader.found |
---|
423 | n/a | self.assertIs(found, sys.modules[name]) |
---|
424 | n/a | self.assertIs(module, sys.modules[name]) |
---|
425 | n/a | |
---|
426 | n/a | |
---|
427 | n/a | (Frozen_LoaderLoadModuleTests, |
---|
428 | n/a | Source_LoaderLoadModuleTests |
---|
429 | n/a | ) = test_util.test_both(LoaderLoadModuleTests, abc=abc, util=util) |
---|
430 | n/a | |
---|
431 | n/a | |
---|
432 | n/a | ##### InspectLoader concrete methods ########################################### |
---|
433 | n/a | class InspectLoaderSourceToCodeTests: |
---|
434 | n/a | |
---|
435 | n/a | def source_to_module(self, data, path=None): |
---|
436 | n/a | """Help with source_to_code() tests.""" |
---|
437 | n/a | module = types.ModuleType('blah') |
---|
438 | n/a | loader = self.InspectLoaderSubclass() |
---|
439 | n/a | if path is None: |
---|
440 | n/a | code = loader.source_to_code(data) |
---|
441 | n/a | else: |
---|
442 | n/a | code = loader.source_to_code(data, path) |
---|
443 | n/a | exec(code, module.__dict__) |
---|
444 | n/a | return module |
---|
445 | n/a | |
---|
446 | n/a | def test_source_to_code_source(self): |
---|
447 | n/a | # Since compile() can handle strings, so should source_to_code(). |
---|
448 | n/a | source = 'attr = 42' |
---|
449 | n/a | module = self.source_to_module(source) |
---|
450 | n/a | self.assertTrue(hasattr(module, 'attr')) |
---|
451 | n/a | self.assertEqual(module.attr, 42) |
---|
452 | n/a | |
---|
453 | n/a | def test_source_to_code_bytes(self): |
---|
454 | n/a | # Since compile() can handle bytes, so should source_to_code(). |
---|
455 | n/a | source = b'attr = 42' |
---|
456 | n/a | module = self.source_to_module(source) |
---|
457 | n/a | self.assertTrue(hasattr(module, 'attr')) |
---|
458 | n/a | self.assertEqual(module.attr, 42) |
---|
459 | n/a | |
---|
460 | n/a | def test_source_to_code_path(self): |
---|
461 | n/a | # Specifying a path should set it for the code object. |
---|
462 | n/a | path = 'path/to/somewhere' |
---|
463 | n/a | loader = self.InspectLoaderSubclass() |
---|
464 | n/a | code = loader.source_to_code('', path) |
---|
465 | n/a | self.assertEqual(code.co_filename, path) |
---|
466 | n/a | |
---|
467 | n/a | def test_source_to_code_no_path(self): |
---|
468 | n/a | # Not setting a path should still work and be set to <string> since that |
---|
469 | n/a | # is a pre-existing practice as a default to compile(). |
---|
470 | n/a | loader = self.InspectLoaderSubclass() |
---|
471 | n/a | code = loader.source_to_code('') |
---|
472 | n/a | self.assertEqual(code.co_filename, '<string>') |
---|
473 | n/a | |
---|
474 | n/a | |
---|
475 | n/a | (Frozen_ILSourceToCodeTests, |
---|
476 | n/a | Source_ILSourceToCodeTests |
---|
477 | n/a | ) = test_util.test_both(InspectLoaderSourceToCodeTests, |
---|
478 | n/a | InspectLoaderSubclass=SPLIT_IL) |
---|
479 | n/a | |
---|
480 | n/a | |
---|
481 | n/a | class InspectLoaderGetCodeTests: |
---|
482 | n/a | |
---|
483 | n/a | def test_get_code(self): |
---|
484 | n/a | # Test success. |
---|
485 | n/a | module = types.ModuleType('blah') |
---|
486 | n/a | with mock.patch.object(self.InspectLoaderSubclass, 'get_source') as mocked: |
---|
487 | n/a | mocked.return_value = 'attr = 42' |
---|
488 | n/a | loader = self.InspectLoaderSubclass() |
---|
489 | n/a | code = loader.get_code('blah') |
---|
490 | n/a | exec(code, module.__dict__) |
---|
491 | n/a | self.assertEqual(module.attr, 42) |
---|
492 | n/a | |
---|
493 | n/a | def test_get_code_source_is_None(self): |
---|
494 | n/a | # If get_source() is None then this should be None. |
---|
495 | n/a | with mock.patch.object(self.InspectLoaderSubclass, 'get_source') as mocked: |
---|
496 | n/a | mocked.return_value = None |
---|
497 | n/a | loader = self.InspectLoaderSubclass() |
---|
498 | n/a | code = loader.get_code('blah') |
---|
499 | n/a | self.assertIsNone(code) |
---|
500 | n/a | |
---|
501 | n/a | def test_get_code_source_not_found(self): |
---|
502 | n/a | # If there is no source then there is no code object. |
---|
503 | n/a | loader = self.InspectLoaderSubclass() |
---|
504 | n/a | with self.assertRaises(ImportError): |
---|
505 | n/a | loader.get_code('blah') |
---|
506 | n/a | |
---|
507 | n/a | |
---|
508 | n/a | (Frozen_ILGetCodeTests, |
---|
509 | n/a | Source_ILGetCodeTests |
---|
510 | n/a | ) = test_util.test_both(InspectLoaderGetCodeTests, |
---|
511 | n/a | InspectLoaderSubclass=SPLIT_IL) |
---|
512 | n/a | |
---|
513 | n/a | |
---|
514 | n/a | class InspectLoaderLoadModuleTests: |
---|
515 | n/a | |
---|
516 | n/a | """Test InspectLoader.load_module().""" |
---|
517 | n/a | |
---|
518 | n/a | module_name = 'blah' |
---|
519 | n/a | |
---|
520 | n/a | def setUp(self): |
---|
521 | n/a | support.unload(self.module_name) |
---|
522 | n/a | self.addCleanup(support.unload, self.module_name) |
---|
523 | n/a | |
---|
524 | n/a | def load(self, loader): |
---|
525 | n/a | spec = self.util.spec_from_loader(self.module_name, loader) |
---|
526 | n/a | with warnings.catch_warnings(): |
---|
527 | n/a | warnings.simplefilter('ignore', DeprecationWarning) |
---|
528 | n/a | return self.init._bootstrap._load_unlocked(spec) |
---|
529 | n/a | |
---|
530 | n/a | def mock_get_code(self): |
---|
531 | n/a | return mock.patch.object(self.InspectLoaderSubclass, 'get_code') |
---|
532 | n/a | |
---|
533 | n/a | def test_get_code_ImportError(self): |
---|
534 | n/a | # If get_code() raises ImportError, it should propagate. |
---|
535 | n/a | with self.mock_get_code() as mocked_get_code: |
---|
536 | n/a | mocked_get_code.side_effect = ImportError |
---|
537 | n/a | with self.assertRaises(ImportError): |
---|
538 | n/a | loader = self.InspectLoaderSubclass() |
---|
539 | n/a | self.load(loader) |
---|
540 | n/a | |
---|
541 | n/a | def test_get_code_None(self): |
---|
542 | n/a | # If get_code() returns None, raise ImportError. |
---|
543 | n/a | with self.mock_get_code() as mocked_get_code: |
---|
544 | n/a | mocked_get_code.return_value = None |
---|
545 | n/a | with self.assertRaises(ImportError): |
---|
546 | n/a | loader = self.InspectLoaderSubclass() |
---|
547 | n/a | self.load(loader) |
---|
548 | n/a | |
---|
549 | n/a | def test_module_returned(self): |
---|
550 | n/a | # The loaded module should be returned. |
---|
551 | n/a | code = compile('attr = 42', '<string>', 'exec') |
---|
552 | n/a | with self.mock_get_code() as mocked_get_code: |
---|
553 | n/a | mocked_get_code.return_value = code |
---|
554 | n/a | loader = self.InspectLoaderSubclass() |
---|
555 | n/a | module = self.load(loader) |
---|
556 | n/a | self.assertEqual(module, sys.modules[self.module_name]) |
---|
557 | n/a | |
---|
558 | n/a | |
---|
559 | n/a | (Frozen_ILLoadModuleTests, |
---|
560 | n/a | Source_ILLoadModuleTests |
---|
561 | n/a | ) = test_util.test_both(InspectLoaderLoadModuleTests, |
---|
562 | n/a | InspectLoaderSubclass=SPLIT_IL, |
---|
563 | n/a | init=init, |
---|
564 | n/a | util=util) |
---|
565 | n/a | |
---|
566 | n/a | |
---|
567 | n/a | ##### ExecutionLoader concrete methods ######################################### |
---|
568 | n/a | class ExecutionLoaderGetCodeTests: |
---|
569 | n/a | |
---|
570 | n/a | def mock_methods(self, *, get_source=False, get_filename=False): |
---|
571 | n/a | source_mock_context, filename_mock_context = None, None |
---|
572 | n/a | if get_source: |
---|
573 | n/a | source_mock_context = mock.patch.object(self.ExecutionLoaderSubclass, |
---|
574 | n/a | 'get_source') |
---|
575 | n/a | if get_filename: |
---|
576 | n/a | filename_mock_context = mock.patch.object(self.ExecutionLoaderSubclass, |
---|
577 | n/a | 'get_filename') |
---|
578 | n/a | return source_mock_context, filename_mock_context |
---|
579 | n/a | |
---|
580 | n/a | def test_get_code(self): |
---|
581 | n/a | path = 'blah.py' |
---|
582 | n/a | source_mock_context, filename_mock_context = self.mock_methods( |
---|
583 | n/a | get_source=True, get_filename=True) |
---|
584 | n/a | with source_mock_context as source_mock, filename_mock_context as name_mock: |
---|
585 | n/a | source_mock.return_value = 'attr = 42' |
---|
586 | n/a | name_mock.return_value = path |
---|
587 | n/a | loader = self.ExecutionLoaderSubclass() |
---|
588 | n/a | code = loader.get_code('blah') |
---|
589 | n/a | self.assertEqual(code.co_filename, path) |
---|
590 | n/a | module = types.ModuleType('blah') |
---|
591 | n/a | exec(code, module.__dict__) |
---|
592 | n/a | self.assertEqual(module.attr, 42) |
---|
593 | n/a | |
---|
594 | n/a | def test_get_code_source_is_None(self): |
---|
595 | n/a | # If get_source() is None then this should be None. |
---|
596 | n/a | source_mock_context, _ = self.mock_methods(get_source=True) |
---|
597 | n/a | with source_mock_context as mocked: |
---|
598 | n/a | mocked.return_value = None |
---|
599 | n/a | loader = self.ExecutionLoaderSubclass() |
---|
600 | n/a | code = loader.get_code('blah') |
---|
601 | n/a | self.assertIsNone(code) |
---|
602 | n/a | |
---|
603 | n/a | def test_get_code_source_not_found(self): |
---|
604 | n/a | # If there is no source then there is no code object. |
---|
605 | n/a | loader = self.ExecutionLoaderSubclass() |
---|
606 | n/a | with self.assertRaises(ImportError): |
---|
607 | n/a | loader.get_code('blah') |
---|
608 | n/a | |
---|
609 | n/a | def test_get_code_no_path(self): |
---|
610 | n/a | # If get_filename() raises ImportError then simply skip setting the path |
---|
611 | n/a | # on the code object. |
---|
612 | n/a | source_mock_context, filename_mock_context = self.mock_methods( |
---|
613 | n/a | get_source=True, get_filename=True) |
---|
614 | n/a | with source_mock_context as source_mock, filename_mock_context as name_mock: |
---|
615 | n/a | source_mock.return_value = 'attr = 42' |
---|
616 | n/a | name_mock.side_effect = ImportError |
---|
617 | n/a | loader = self.ExecutionLoaderSubclass() |
---|
618 | n/a | code = loader.get_code('blah') |
---|
619 | n/a | self.assertEqual(code.co_filename, '<string>') |
---|
620 | n/a | module = types.ModuleType('blah') |
---|
621 | n/a | exec(code, module.__dict__) |
---|
622 | n/a | self.assertEqual(module.attr, 42) |
---|
623 | n/a | |
---|
624 | n/a | |
---|
625 | n/a | (Frozen_ELGetCodeTests, |
---|
626 | n/a | Source_ELGetCodeTests |
---|
627 | n/a | ) = test_util.test_both(ExecutionLoaderGetCodeTests, |
---|
628 | n/a | ExecutionLoaderSubclass=SPLIT_EL) |
---|
629 | n/a | |
---|
630 | n/a | |
---|
631 | n/a | ##### SourceLoader concrete methods ############################################ |
---|
632 | n/a | class SourceOnlyLoader: |
---|
633 | n/a | |
---|
634 | n/a | # Globals that should be defined for all modules. |
---|
635 | n/a | source = (b"_ = '::'.join([__name__, __file__, __cached__, __package__, " |
---|
636 | n/a | b"repr(__loader__)])") |
---|
637 | n/a | |
---|
638 | n/a | def __init__(self, path): |
---|
639 | n/a | self.path = path |
---|
640 | n/a | |
---|
641 | n/a | def get_data(self, path): |
---|
642 | n/a | if path != self.path: |
---|
643 | n/a | raise IOError |
---|
644 | n/a | return self.source |
---|
645 | n/a | |
---|
646 | n/a | def get_filename(self, fullname): |
---|
647 | n/a | return self.path |
---|
648 | n/a | |
---|
649 | n/a | def module_repr(self, module): |
---|
650 | n/a | return '<module>' |
---|
651 | n/a | |
---|
652 | n/a | |
---|
653 | n/a | SPLIT_SOL = make_abc_subclasses(SourceOnlyLoader, 'SourceLoader') |
---|
654 | n/a | |
---|
655 | n/a | |
---|
656 | n/a | class SourceLoader(SourceOnlyLoader): |
---|
657 | n/a | |
---|
658 | n/a | source_mtime = 1 |
---|
659 | n/a | |
---|
660 | n/a | def __init__(self, path, magic=None): |
---|
661 | n/a | super().__init__(path) |
---|
662 | n/a | self.bytecode_path = self.util.cache_from_source(self.path) |
---|
663 | n/a | self.source_size = len(self.source) |
---|
664 | n/a | if magic is None: |
---|
665 | n/a | magic = self.util.MAGIC_NUMBER |
---|
666 | n/a | data = bytearray(magic) |
---|
667 | n/a | data.extend(self.init._w_long(self.source_mtime)) |
---|
668 | n/a | data.extend(self.init._w_long(self.source_size)) |
---|
669 | n/a | code_object = compile(self.source, self.path, 'exec', |
---|
670 | n/a | dont_inherit=True) |
---|
671 | n/a | data.extend(marshal.dumps(code_object)) |
---|
672 | n/a | self.bytecode = bytes(data) |
---|
673 | n/a | self.written = {} |
---|
674 | n/a | |
---|
675 | n/a | def get_data(self, path): |
---|
676 | n/a | if path == self.path: |
---|
677 | n/a | return super().get_data(path) |
---|
678 | n/a | elif path == self.bytecode_path: |
---|
679 | n/a | return self.bytecode |
---|
680 | n/a | else: |
---|
681 | n/a | raise OSError |
---|
682 | n/a | |
---|
683 | n/a | def path_stats(self, path): |
---|
684 | n/a | if path != self.path: |
---|
685 | n/a | raise IOError |
---|
686 | n/a | return {'mtime': self.source_mtime, 'size': self.source_size} |
---|
687 | n/a | |
---|
688 | n/a | def set_data(self, path, data): |
---|
689 | n/a | self.written[path] = bytes(data) |
---|
690 | n/a | return path == self.bytecode_path |
---|
691 | n/a | |
---|
692 | n/a | |
---|
693 | n/a | SPLIT_SL = make_abc_subclasses(SourceLoader, util=util, init=init) |
---|
694 | n/a | |
---|
695 | n/a | |
---|
696 | n/a | class SourceLoaderTestHarness: |
---|
697 | n/a | |
---|
698 | n/a | def setUp(self, *, is_package=True, **kwargs): |
---|
699 | n/a | self.package = 'pkg' |
---|
700 | n/a | if is_package: |
---|
701 | n/a | self.path = os.path.join(self.package, '__init__.py') |
---|
702 | n/a | self.name = self.package |
---|
703 | n/a | else: |
---|
704 | n/a | module_name = 'mod' |
---|
705 | n/a | self.path = os.path.join(self.package, '.'.join(['mod', 'py'])) |
---|
706 | n/a | self.name = '.'.join([self.package, module_name]) |
---|
707 | n/a | self.cached = self.util.cache_from_source(self.path) |
---|
708 | n/a | self.loader = self.loader_mock(self.path, **kwargs) |
---|
709 | n/a | |
---|
710 | n/a | def verify_module(self, module): |
---|
711 | n/a | self.assertEqual(module.__name__, self.name) |
---|
712 | n/a | self.assertEqual(module.__file__, self.path) |
---|
713 | n/a | self.assertEqual(module.__cached__, self.cached) |
---|
714 | n/a | self.assertEqual(module.__package__, self.package) |
---|
715 | n/a | self.assertEqual(module.__loader__, self.loader) |
---|
716 | n/a | values = module._.split('::') |
---|
717 | n/a | self.assertEqual(values[0], self.name) |
---|
718 | n/a | self.assertEqual(values[1], self.path) |
---|
719 | n/a | self.assertEqual(values[2], self.cached) |
---|
720 | n/a | self.assertEqual(values[3], self.package) |
---|
721 | n/a | self.assertEqual(values[4], repr(self.loader)) |
---|
722 | n/a | |
---|
723 | n/a | def verify_code(self, code_object): |
---|
724 | n/a | module = types.ModuleType(self.name) |
---|
725 | n/a | module.__file__ = self.path |
---|
726 | n/a | module.__cached__ = self.cached |
---|
727 | n/a | module.__package__ = self.package |
---|
728 | n/a | module.__loader__ = self.loader |
---|
729 | n/a | module.__path__ = [] |
---|
730 | n/a | exec(code_object, module.__dict__) |
---|
731 | n/a | self.verify_module(module) |
---|
732 | n/a | |
---|
733 | n/a | |
---|
734 | n/a | class SourceOnlyLoaderTests(SourceLoaderTestHarness): |
---|
735 | n/a | |
---|
736 | n/a | """Test importlib.abc.SourceLoader for source-only loading. |
---|
737 | n/a | |
---|
738 | n/a | Reload testing is subsumed by the tests for |
---|
739 | n/a | importlib.util.module_for_loader. |
---|
740 | n/a | |
---|
741 | n/a | """ |
---|
742 | n/a | |
---|
743 | n/a | def test_get_source(self): |
---|
744 | n/a | # Verify the source code is returned as a string. |
---|
745 | n/a | # If an OSError is raised by get_data then raise ImportError. |
---|
746 | n/a | expected_source = self.loader.source.decode('utf-8') |
---|
747 | n/a | self.assertEqual(self.loader.get_source(self.name), expected_source) |
---|
748 | n/a | def raise_OSError(path): |
---|
749 | n/a | raise OSError |
---|
750 | n/a | self.loader.get_data = raise_OSError |
---|
751 | n/a | with self.assertRaises(ImportError) as cm: |
---|
752 | n/a | self.loader.get_source(self.name) |
---|
753 | n/a | self.assertEqual(cm.exception.name, self.name) |
---|
754 | n/a | |
---|
755 | n/a | def test_is_package(self): |
---|
756 | n/a | # Properly detect when loading a package. |
---|
757 | n/a | self.setUp(is_package=False) |
---|
758 | n/a | self.assertFalse(self.loader.is_package(self.name)) |
---|
759 | n/a | self.setUp(is_package=True) |
---|
760 | n/a | self.assertTrue(self.loader.is_package(self.name)) |
---|
761 | n/a | self.assertFalse(self.loader.is_package(self.name + '.__init__')) |
---|
762 | n/a | |
---|
763 | n/a | def test_get_code(self): |
---|
764 | n/a | # Verify the code object is created. |
---|
765 | n/a | code_object = self.loader.get_code(self.name) |
---|
766 | n/a | self.verify_code(code_object) |
---|
767 | n/a | |
---|
768 | n/a | def test_source_to_code(self): |
---|
769 | n/a | # Verify the compiled code object. |
---|
770 | n/a | code = self.loader.source_to_code(self.loader.source, self.path) |
---|
771 | n/a | self.verify_code(code) |
---|
772 | n/a | |
---|
773 | n/a | def test_load_module(self): |
---|
774 | n/a | # Loading a module should set __name__, __loader__, __package__, |
---|
775 | n/a | # __path__ (for packages), __file__, and __cached__. |
---|
776 | n/a | # The module should also be put into sys.modules. |
---|
777 | n/a | with test_util.uncache(self.name): |
---|
778 | n/a | with warnings.catch_warnings(): |
---|
779 | n/a | warnings.simplefilter('ignore', DeprecationWarning) |
---|
780 | n/a | module = self.loader.load_module(self.name) |
---|
781 | n/a | self.verify_module(module) |
---|
782 | n/a | self.assertEqual(module.__path__, [os.path.dirname(self.path)]) |
---|
783 | n/a | self.assertIn(self.name, sys.modules) |
---|
784 | n/a | |
---|
785 | n/a | def test_package_settings(self): |
---|
786 | n/a | # __package__ needs to be set, while __path__ is set on if the module |
---|
787 | n/a | # is a package. |
---|
788 | n/a | # Testing the values for a package are covered by test_load_module. |
---|
789 | n/a | self.setUp(is_package=False) |
---|
790 | n/a | with test_util.uncache(self.name): |
---|
791 | n/a | with warnings.catch_warnings(): |
---|
792 | n/a | warnings.simplefilter('ignore', DeprecationWarning) |
---|
793 | n/a | module = self.loader.load_module(self.name) |
---|
794 | n/a | self.verify_module(module) |
---|
795 | n/a | self.assertFalse(hasattr(module, '__path__')) |
---|
796 | n/a | |
---|
797 | n/a | def test_get_source_encoding(self): |
---|
798 | n/a | # Source is considered encoded in UTF-8 by default unless otherwise |
---|
799 | n/a | # specified by an encoding line. |
---|
800 | n/a | source = "_ = 'ü'" |
---|
801 | n/a | self.loader.source = source.encode('utf-8') |
---|
802 | n/a | returned_source = self.loader.get_source(self.name) |
---|
803 | n/a | self.assertEqual(returned_source, source) |
---|
804 | n/a | source = "# coding: latin-1\n_ = ü" |
---|
805 | n/a | self.loader.source = source.encode('latin-1') |
---|
806 | n/a | returned_source = self.loader.get_source(self.name) |
---|
807 | n/a | self.assertEqual(returned_source, source) |
---|
808 | n/a | |
---|
809 | n/a | |
---|
810 | n/a | (Frozen_SourceOnlyLoaderTests, |
---|
811 | n/a | Source_SourceOnlyLoaderTests |
---|
812 | n/a | ) = test_util.test_both(SourceOnlyLoaderTests, util=util, |
---|
813 | n/a | loader_mock=SPLIT_SOL) |
---|
814 | n/a | |
---|
815 | n/a | |
---|
816 | n/a | @unittest.skipIf(sys.dont_write_bytecode, "sys.dont_write_bytecode is true") |
---|
817 | n/a | class SourceLoaderBytecodeTests(SourceLoaderTestHarness): |
---|
818 | n/a | |
---|
819 | n/a | """Test importlib.abc.SourceLoader's use of bytecode. |
---|
820 | n/a | |
---|
821 | n/a | Source-only testing handled by SourceOnlyLoaderTests. |
---|
822 | n/a | |
---|
823 | n/a | """ |
---|
824 | n/a | |
---|
825 | n/a | def verify_code(self, code_object, *, bytecode_written=False): |
---|
826 | n/a | super().verify_code(code_object) |
---|
827 | n/a | if bytecode_written: |
---|
828 | n/a | self.assertIn(self.cached, self.loader.written) |
---|
829 | n/a | data = bytearray(self.util.MAGIC_NUMBER) |
---|
830 | n/a | data.extend(self.init._w_long(self.loader.source_mtime)) |
---|
831 | n/a | data.extend(self.init._w_long(self.loader.source_size)) |
---|
832 | n/a | data.extend(marshal.dumps(code_object)) |
---|
833 | n/a | self.assertEqual(self.loader.written[self.cached], bytes(data)) |
---|
834 | n/a | |
---|
835 | n/a | def test_code_with_everything(self): |
---|
836 | n/a | # When everything should work. |
---|
837 | n/a | code_object = self.loader.get_code(self.name) |
---|
838 | n/a | self.verify_code(code_object) |
---|
839 | n/a | |
---|
840 | n/a | def test_no_bytecode(self): |
---|
841 | n/a | # If no bytecode exists then move on to the source. |
---|
842 | n/a | self.loader.bytecode_path = "<does not exist>" |
---|
843 | n/a | # Sanity check |
---|
844 | n/a | with self.assertRaises(OSError): |
---|
845 | n/a | bytecode_path = self.util.cache_from_source(self.path) |
---|
846 | n/a | self.loader.get_data(bytecode_path) |
---|
847 | n/a | code_object = self.loader.get_code(self.name) |
---|
848 | n/a | self.verify_code(code_object, bytecode_written=True) |
---|
849 | n/a | |
---|
850 | n/a | def test_code_bad_timestamp(self): |
---|
851 | n/a | # Bytecode is only used when the timestamp matches the source EXACTLY. |
---|
852 | n/a | for source_mtime in (0, 2): |
---|
853 | n/a | assert source_mtime != self.loader.source_mtime |
---|
854 | n/a | original = self.loader.source_mtime |
---|
855 | n/a | self.loader.source_mtime = source_mtime |
---|
856 | n/a | # If bytecode is used then EOFError would be raised by marshal. |
---|
857 | n/a | self.loader.bytecode = self.loader.bytecode[8:] |
---|
858 | n/a | code_object = self.loader.get_code(self.name) |
---|
859 | n/a | self.verify_code(code_object, bytecode_written=True) |
---|
860 | n/a | self.loader.source_mtime = original |
---|
861 | n/a | |
---|
862 | n/a | def test_code_bad_magic(self): |
---|
863 | n/a | # Skip over bytecode with a bad magic number. |
---|
864 | n/a | self.setUp(magic=b'0000') |
---|
865 | n/a | # If bytecode is used then EOFError would be raised by marshal. |
---|
866 | n/a | self.loader.bytecode = self.loader.bytecode[8:] |
---|
867 | n/a | code_object = self.loader.get_code(self.name) |
---|
868 | n/a | self.verify_code(code_object, bytecode_written=True) |
---|
869 | n/a | |
---|
870 | n/a | def test_dont_write_bytecode(self): |
---|
871 | n/a | # Bytecode is not written if sys.dont_write_bytecode is true. |
---|
872 | n/a | # Can assume it is false already thanks to the skipIf class decorator. |
---|
873 | n/a | try: |
---|
874 | n/a | sys.dont_write_bytecode = True |
---|
875 | n/a | self.loader.bytecode_path = "<does not exist>" |
---|
876 | n/a | code_object = self.loader.get_code(self.name) |
---|
877 | n/a | self.assertNotIn(self.cached, self.loader.written) |
---|
878 | n/a | finally: |
---|
879 | n/a | sys.dont_write_bytecode = False |
---|
880 | n/a | |
---|
881 | n/a | def test_no_set_data(self): |
---|
882 | n/a | # If set_data is not defined, one can still read bytecode. |
---|
883 | n/a | self.setUp(magic=b'0000') |
---|
884 | n/a | original_set_data = self.loader.__class__.mro()[1].set_data |
---|
885 | n/a | try: |
---|
886 | n/a | del self.loader.__class__.mro()[1].set_data |
---|
887 | n/a | code_object = self.loader.get_code(self.name) |
---|
888 | n/a | self.verify_code(code_object) |
---|
889 | n/a | finally: |
---|
890 | n/a | self.loader.__class__.mro()[1].set_data = original_set_data |
---|
891 | n/a | |
---|
892 | n/a | def test_set_data_raises_exceptions(self): |
---|
893 | n/a | # Raising NotImplementedError or OSError is okay for set_data. |
---|
894 | n/a | def raise_exception(exc): |
---|
895 | n/a | def closure(*args, **kwargs): |
---|
896 | n/a | raise exc |
---|
897 | n/a | return closure |
---|
898 | n/a | |
---|
899 | n/a | self.setUp(magic=b'0000') |
---|
900 | n/a | self.loader.set_data = raise_exception(NotImplementedError) |
---|
901 | n/a | code_object = self.loader.get_code(self.name) |
---|
902 | n/a | self.verify_code(code_object) |
---|
903 | n/a | |
---|
904 | n/a | |
---|
905 | n/a | (Frozen_SLBytecodeTests, |
---|
906 | n/a | SourceSLBytecodeTests |
---|
907 | n/a | ) = test_util.test_both(SourceLoaderBytecodeTests, init=init, util=util, |
---|
908 | n/a | loader_mock=SPLIT_SL) |
---|
909 | n/a | |
---|
910 | n/a | |
---|
911 | n/a | class SourceLoaderGetSourceTests: |
---|
912 | n/a | |
---|
913 | n/a | """Tests for importlib.abc.SourceLoader.get_source().""" |
---|
914 | n/a | |
---|
915 | n/a | def test_default_encoding(self): |
---|
916 | n/a | # Should have no problems with UTF-8 text. |
---|
917 | n/a | name = 'mod' |
---|
918 | n/a | mock = self.SourceOnlyLoaderMock('mod.file') |
---|
919 | n/a | source = 'x = "ü"' |
---|
920 | n/a | mock.source = source.encode('utf-8') |
---|
921 | n/a | returned_source = mock.get_source(name) |
---|
922 | n/a | self.assertEqual(returned_source, source) |
---|
923 | n/a | |
---|
924 | n/a | def test_decoded_source(self): |
---|
925 | n/a | # Decoding should work. |
---|
926 | n/a | name = 'mod' |
---|
927 | n/a | mock = self.SourceOnlyLoaderMock("mod.file") |
---|
928 | n/a | source = "# coding: Latin-1\nx='ü'" |
---|
929 | n/a | assert source.encode('latin-1') != source.encode('utf-8') |
---|
930 | n/a | mock.source = source.encode('latin-1') |
---|
931 | n/a | returned_source = mock.get_source(name) |
---|
932 | n/a | self.assertEqual(returned_source, source) |
---|
933 | n/a | |
---|
934 | n/a | def test_universal_newlines(self): |
---|
935 | n/a | # PEP 302 says universal newlines should be used. |
---|
936 | n/a | name = 'mod' |
---|
937 | n/a | mock = self.SourceOnlyLoaderMock('mod.file') |
---|
938 | n/a | source = "x = 42\r\ny = -13\r\n" |
---|
939 | n/a | mock.source = source.encode('utf-8') |
---|
940 | n/a | expect = io.IncrementalNewlineDecoder(None, True).decode(source) |
---|
941 | n/a | self.assertEqual(mock.get_source(name), expect) |
---|
942 | n/a | |
---|
943 | n/a | |
---|
944 | n/a | (Frozen_SourceOnlyLoaderGetSourceTests, |
---|
945 | n/a | Source_SourceOnlyLoaderGetSourceTests |
---|
946 | n/a | ) = test_util.test_both(SourceLoaderGetSourceTests, |
---|
947 | n/a | SourceOnlyLoaderMock=SPLIT_SOL) |
---|
948 | n/a | |
---|
949 | n/a | |
---|
950 | n/a | if __name__ == '__main__': |
---|
951 | n/a | unittest.main() |
---|