ยปCore Development>Code coverage>Lib/test/test_importlib/test_lazy.py

Python code coverage for Lib/test/test_importlib/test_lazy.py

#countcontent
1n/aimport importlib
2n/afrom importlib import abc
3n/afrom importlib import util
4n/aimport sys
5n/aimport types
6n/aimport unittest
7n/a
8n/afrom . import util as test_util
9n/a
10n/a
11n/aclass CollectInit:
12n/a
13n/a def __init__(self, *args, **kwargs):
14n/a self.args = args
15n/a self.kwargs = kwargs
16n/a
17n/a def exec_module(self, module):
18n/a return self
19n/a
20n/a
21n/aclass LazyLoaderFactoryTests(unittest.TestCase):
22n/a
23n/a def test_init(self):
24n/a factory = util.LazyLoader.factory(CollectInit)
25n/a # E.g. what importlib.machinery.FileFinder instantiates loaders with
26n/a # plus keyword arguments.
27n/a lazy_loader = factory('module name', 'module path', kw='kw')
28n/a loader = lazy_loader.loader
29n/a self.assertEqual(('module name', 'module path'), loader.args)
30n/a self.assertEqual({'kw': 'kw'}, loader.kwargs)
31n/a
32n/a def test_validation(self):
33n/a # No exec_module(), no lazy loading.
34n/a with self.assertRaises(TypeError):
35n/a util.LazyLoader.factory(object)
36n/a
37n/a
38n/aclass TestingImporter(abc.MetaPathFinder, abc.Loader):
39n/a
40n/a module_name = 'lazy_loader_test'
41n/a mutated_name = 'changed'
42n/a loaded = None
43n/a source_code = 'attr = 42; __name__ = {!r}'.format(mutated_name)
44n/a
45n/a def find_spec(self, name, path, target=None):
46n/a if name != self.module_name:
47n/a return None
48n/a return util.spec_from_loader(name, util.LazyLoader(self))
49n/a
50n/a def exec_module(self, module):
51n/a exec(self.source_code, module.__dict__)
52n/a self.loaded = module
53n/a
54n/a
55n/aclass LazyLoaderTests(unittest.TestCase):
56n/a
57n/a def test_init(self):
58n/a with self.assertRaises(TypeError):
59n/a # Classes that dono't define exec_module() trigger TypeError.
60n/a util.LazyLoader(object)
61n/a
62n/a def new_module(self, source_code=None):
63n/a loader = TestingImporter()
64n/a if source_code is not None:
65n/a loader.source_code = source_code
66n/a spec = util.spec_from_loader(TestingImporter.module_name,
67n/a util.LazyLoader(loader))
68n/a module = spec.loader.create_module(spec)
69n/a if module is None:
70n/a module = types.ModuleType(TestingImporter.module_name)
71n/a module.__spec__ = spec
72n/a module.__loader__ = spec.loader
73n/a spec.loader.exec_module(module)
74n/a # Module is now lazy.
75n/a self.assertIsNone(loader.loaded)
76n/a return module
77n/a
78n/a def test_e2e(self):
79n/a # End-to-end test to verify the load is in fact lazy.
80n/a importer = TestingImporter()
81n/a assert importer.loaded is None
82n/a with test_util.uncache(importer.module_name):
83n/a with test_util.import_state(meta_path=[importer]):
84n/a module = importlib.import_module(importer.module_name)
85n/a self.assertIsNone(importer.loaded)
86n/a # Trigger load.
87n/a self.assertEqual(module.__loader__, importer)
88n/a self.assertIsNotNone(importer.loaded)
89n/a self.assertEqual(module, importer.loaded)
90n/a
91n/a def test_attr_unchanged(self):
92n/a # An attribute only mutated as a side-effect of import should not be
93n/a # changed needlessly.
94n/a module = self.new_module()
95n/a self.assertEqual(TestingImporter.mutated_name, module.__name__)
96n/a
97n/a def test_new_attr(self):
98n/a # A new attribute should persist.
99n/a module = self.new_module()
100n/a module.new_attr = 42
101n/a self.assertEqual(42, module.new_attr)
102n/a
103n/a def test_mutated_preexisting_attr(self):
104n/a # Changing an attribute that already existed on the module --
105n/a # e.g. __name__ -- should persist.
106n/a module = self.new_module()
107n/a module.__name__ = 'bogus'
108n/a self.assertEqual('bogus', module.__name__)
109n/a
110n/a def test_mutated_attr(self):
111n/a # Changing an attribute that comes into existence after an import
112n/a # should persist.
113n/a module = self.new_module()
114n/a module.attr = 6
115n/a self.assertEqual(6, module.attr)
116n/a
117n/a def test_delete_eventual_attr(self):
118n/a # Deleting an attribute should stay deleted.
119n/a module = self.new_module()
120n/a del module.attr
121n/a self.assertFalse(hasattr(module, 'attr'))
122n/a
123n/a def test_delete_preexisting_attr(self):
124n/a module = self.new_module()
125n/a del module.__name__
126n/a self.assertFalse(hasattr(module, '__name__'))
127n/a
128n/a def test_module_substitution_error(self):
129n/a with test_util.uncache(TestingImporter.module_name):
130n/a fresh_module = types.ModuleType(TestingImporter.module_name)
131n/a sys.modules[TestingImporter.module_name] = fresh_module
132n/a module = self.new_module()
133n/a with self.assertRaisesRegex(ValueError, "substituted"):
134n/a module.__name__
135n/a
136n/a def test_module_already_in_sys(self):
137n/a with test_util.uncache(TestingImporter.module_name):
138n/a module = self.new_module()
139n/a sys.modules[TestingImporter.module_name] = module
140n/a # Force the load; just care that no exception is raised.
141n/a module.__name__
142n/a
143n/a
144n/aif __name__ == '__main__':
145n/a unittest.main()