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

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

#countcontent
1n/afrom . import util as test_util
2n/a
3n/ainit = test_util.import_importlib('importlib')
4n/autil = test_util.import_importlib('importlib.util')
5n/amachinery = test_util.import_importlib('importlib.machinery')
6n/a
7n/aimport os.path
8n/aimport sys
9n/afrom test import support
10n/aimport types
11n/aimport unittest
12n/aimport warnings
13n/a
14n/a
15n/aclass ImportModuleTests:
16n/a
17n/a """Test importlib.import_module."""
18n/a
19n/a def test_module_import(self):
20n/a # Test importing a top-level module.
21n/a with test_util.mock_modules('top_level') as mock:
22n/a with test_util.import_state(meta_path=[mock]):
23n/a module = self.init.import_module('top_level')
24n/a self.assertEqual(module.__name__, 'top_level')
25n/a
26n/a def test_absolute_package_import(self):
27n/a # Test importing a module from a package with an absolute name.
28n/a pkg_name = 'pkg'
29n/a pkg_long_name = '{0}.__init__'.format(pkg_name)
30n/a name = '{0}.mod'.format(pkg_name)
31n/a with test_util.mock_modules(pkg_long_name, name) as mock:
32n/a with test_util.import_state(meta_path=[mock]):
33n/a module = self.init.import_module(name)
34n/a self.assertEqual(module.__name__, name)
35n/a
36n/a def test_shallow_relative_package_import(self):
37n/a # Test importing a module from a package through a relative import.
38n/a pkg_name = 'pkg'
39n/a pkg_long_name = '{0}.__init__'.format(pkg_name)
40n/a module_name = 'mod'
41n/a absolute_name = '{0}.{1}'.format(pkg_name, module_name)
42n/a relative_name = '.{0}'.format(module_name)
43n/a with test_util.mock_modules(pkg_long_name, absolute_name) as mock:
44n/a with test_util.import_state(meta_path=[mock]):
45n/a self.init.import_module(pkg_name)
46n/a module = self.init.import_module(relative_name, pkg_name)
47n/a self.assertEqual(module.__name__, absolute_name)
48n/a
49n/a def test_deep_relative_package_import(self):
50n/a modules = ['a.__init__', 'a.b.__init__', 'a.c']
51n/a with test_util.mock_modules(*modules) as mock:
52n/a with test_util.import_state(meta_path=[mock]):
53n/a self.init.import_module('a')
54n/a self.init.import_module('a.b')
55n/a module = self.init.import_module('..c', 'a.b')
56n/a self.assertEqual(module.__name__, 'a.c')
57n/a
58n/a def test_absolute_import_with_package(self):
59n/a # Test importing a module from a package with an absolute name with
60n/a # the 'package' argument given.
61n/a pkg_name = 'pkg'
62n/a pkg_long_name = '{0}.__init__'.format(pkg_name)
63n/a name = '{0}.mod'.format(pkg_name)
64n/a with test_util.mock_modules(pkg_long_name, name) as mock:
65n/a with test_util.import_state(meta_path=[mock]):
66n/a self.init.import_module(pkg_name)
67n/a module = self.init.import_module(name, pkg_name)
68n/a self.assertEqual(module.__name__, name)
69n/a
70n/a def test_relative_import_wo_package(self):
71n/a # Relative imports cannot happen without the 'package' argument being
72n/a # set.
73n/a with self.assertRaises(TypeError):
74n/a self.init.import_module('.support')
75n/a
76n/a
77n/a def test_loaded_once(self):
78n/a # Issue #13591: Modules should only be loaded once when
79n/a # initializing the parent package attempts to import the
80n/a # module currently being imported.
81n/a b_load_count = 0
82n/a def load_a():
83n/a self.init.import_module('a.b')
84n/a def load_b():
85n/a nonlocal b_load_count
86n/a b_load_count += 1
87n/a code = {'a': load_a, 'a.b': load_b}
88n/a modules = ['a.__init__', 'a.b']
89n/a with test_util.mock_modules(*modules, module_code=code) as mock:
90n/a with test_util.import_state(meta_path=[mock]):
91n/a self.init.import_module('a.b')
92n/a self.assertEqual(b_load_count, 1)
93n/a
94n/a
95n/a(Frozen_ImportModuleTests,
96n/a Source_ImportModuleTests
97n/a ) = test_util.test_both(ImportModuleTests, init=init)
98n/a
99n/a
100n/aclass FindLoaderTests:
101n/a
102n/a FakeMetaFinder = None
103n/a
104n/a def test_sys_modules(self):
105n/a # If a module with __loader__ is in sys.modules, then return it.
106n/a name = 'some_mod'
107n/a with test_util.uncache(name):
108n/a module = types.ModuleType(name)
109n/a loader = 'a loader!'
110n/a module.__loader__ = loader
111n/a sys.modules[name] = module
112n/a with warnings.catch_warnings():
113n/a warnings.simplefilter('ignore', DeprecationWarning)
114n/a found = self.init.find_loader(name)
115n/a self.assertEqual(loader, found)
116n/a
117n/a def test_sys_modules_loader_is_None(self):
118n/a # If sys.modules[name].__loader__ is None, raise ValueError.
119n/a name = 'some_mod'
120n/a with test_util.uncache(name):
121n/a module = types.ModuleType(name)
122n/a module.__loader__ = None
123n/a sys.modules[name] = module
124n/a with self.assertRaises(ValueError):
125n/a with warnings.catch_warnings():
126n/a warnings.simplefilter('ignore', DeprecationWarning)
127n/a self.init.find_loader(name)
128n/a
129n/a def test_sys_modules_loader_is_not_set(self):
130n/a # Should raise ValueError
131n/a # Issue #17099
132n/a name = 'some_mod'
133n/a with test_util.uncache(name):
134n/a module = types.ModuleType(name)
135n/a try:
136n/a del module.__loader__
137n/a except AttributeError:
138n/a pass
139n/a sys.modules[name] = module
140n/a with self.assertRaises(ValueError):
141n/a with warnings.catch_warnings():
142n/a warnings.simplefilter('ignore', DeprecationWarning)
143n/a self.init.find_loader(name)
144n/a
145n/a def test_success(self):
146n/a # Return the loader found on sys.meta_path.
147n/a name = 'some_mod'
148n/a with test_util.uncache(name):
149n/a with test_util.import_state(meta_path=[self.FakeMetaFinder]):
150n/a with warnings.catch_warnings():
151n/a warnings.simplefilter('ignore', DeprecationWarning)
152n/a self.assertEqual((name, None), self.init.find_loader(name))
153n/a
154n/a def test_success_path(self):
155n/a # Searching on a path should work.
156n/a name = 'some_mod'
157n/a path = 'path to some place'
158n/a with test_util.uncache(name):
159n/a with test_util.import_state(meta_path=[self.FakeMetaFinder]):
160n/a with warnings.catch_warnings():
161n/a warnings.simplefilter('ignore', DeprecationWarning)
162n/a self.assertEqual((name, path),
163n/a self.init.find_loader(name, path))
164n/a
165n/a def test_nothing(self):
166n/a # None is returned upon failure to find a loader.
167n/a with warnings.catch_warnings():
168n/a warnings.simplefilter('ignore', DeprecationWarning)
169n/a self.assertIsNone(self.init.find_loader('nevergoingtofindthismodule'))
170n/a
171n/a
172n/aclass FindLoaderPEP451Tests(FindLoaderTests):
173n/a
174n/a class FakeMetaFinder:
175n/a @staticmethod
176n/a def find_spec(name, path=None, target=None):
177n/a return machinery['Source'].ModuleSpec(name, (name, path))
178n/a
179n/a
180n/a(Frozen_FindLoaderPEP451Tests,
181n/a Source_FindLoaderPEP451Tests
182n/a ) = test_util.test_both(FindLoaderPEP451Tests, init=init)
183n/a
184n/a
185n/aclass FindLoaderPEP302Tests(FindLoaderTests):
186n/a
187n/a class FakeMetaFinder:
188n/a @staticmethod
189n/a def find_module(name, path=None):
190n/a return name, path
191n/a
192n/a
193n/a(Frozen_FindLoaderPEP302Tests,
194n/a Source_FindLoaderPEP302Tests
195n/a ) = test_util.test_both(FindLoaderPEP302Tests, init=init)
196n/a
197n/a
198n/aclass ReloadTests:
199n/a
200n/a """Test module reloading for builtin and extension modules."""
201n/a
202n/a def test_reload_modules(self):
203n/a for mod in ('tokenize', 'time', 'marshal'):
204n/a with self.subTest(module=mod):
205n/a with support.CleanImport(mod):
206n/a module = self.init.import_module(mod)
207n/a self.init.reload(module)
208n/a
209n/a def test_module_replaced(self):
210n/a def code():
211n/a import sys
212n/a module = type(sys)('top_level')
213n/a module.spam = 3
214n/a sys.modules['top_level'] = module
215n/a mock = test_util.mock_modules('top_level',
216n/a module_code={'top_level': code})
217n/a with mock:
218n/a with test_util.import_state(meta_path=[mock]):
219n/a module = self.init.import_module('top_level')
220n/a reloaded = self.init.reload(module)
221n/a actual = sys.modules['top_level']
222n/a self.assertEqual(actual.spam, 3)
223n/a self.assertEqual(reloaded.spam, 3)
224n/a
225n/a def test_reload_missing_loader(self):
226n/a with support.CleanImport('types'):
227n/a import types
228n/a loader = types.__loader__
229n/a del types.__loader__
230n/a reloaded = self.init.reload(types)
231n/a
232n/a self.assertIs(reloaded, types)
233n/a self.assertIs(sys.modules['types'], types)
234n/a self.assertEqual(reloaded.__loader__.path, loader.path)
235n/a
236n/a def test_reload_loader_replaced(self):
237n/a with support.CleanImport('types'):
238n/a import types
239n/a types.__loader__ = None
240n/a self.init.invalidate_caches()
241n/a reloaded = self.init.reload(types)
242n/a
243n/a self.assertIsNot(reloaded.__loader__, None)
244n/a self.assertIs(reloaded, types)
245n/a self.assertIs(sys.modules['types'], types)
246n/a
247n/a def test_reload_location_changed(self):
248n/a name = 'spam'
249n/a with support.temp_cwd(None) as cwd:
250n/a with test_util.uncache('spam'):
251n/a with support.DirsOnSysPath(cwd):
252n/a # Start as a plain module.
253n/a self.init.invalidate_caches()
254n/a path = os.path.join(cwd, name + '.py')
255n/a cached = self.util.cache_from_source(path)
256n/a expected = {'__name__': name,
257n/a '__package__': '',
258n/a '__file__': path,
259n/a '__cached__': cached,
260n/a '__doc__': None,
261n/a }
262n/a support.create_empty_file(path)
263n/a module = self.init.import_module(name)
264n/a ns = vars(module).copy()
265n/a loader = ns.pop('__loader__')
266n/a spec = ns.pop('__spec__')
267n/a ns.pop('__builtins__', None) # An implementation detail.
268n/a self.assertEqual(spec.name, name)
269n/a self.assertEqual(spec.loader, loader)
270n/a self.assertEqual(loader.path, path)
271n/a self.assertEqual(ns, expected)
272n/a
273n/a # Change to a package.
274n/a self.init.invalidate_caches()
275n/a init_path = os.path.join(cwd, name, '__init__.py')
276n/a cached = self.util.cache_from_source(init_path)
277n/a expected = {'__name__': name,
278n/a '__package__': name,
279n/a '__file__': init_path,
280n/a '__cached__': cached,
281n/a '__path__': [os.path.dirname(init_path)],
282n/a '__doc__': None,
283n/a }
284n/a os.mkdir(name)
285n/a os.rename(path, init_path)
286n/a reloaded = self.init.reload(module)
287n/a ns = vars(reloaded).copy()
288n/a loader = ns.pop('__loader__')
289n/a spec = ns.pop('__spec__')
290n/a ns.pop('__builtins__', None) # An implementation detail.
291n/a self.assertEqual(spec.name, name)
292n/a self.assertEqual(spec.loader, loader)
293n/a self.assertIs(reloaded, module)
294n/a self.assertEqual(loader.path, init_path)
295n/a self.maxDiff = None
296n/a self.assertEqual(ns, expected)
297n/a
298n/a def test_reload_namespace_changed(self):
299n/a name = 'spam'
300n/a with support.temp_cwd(None) as cwd:
301n/a with test_util.uncache('spam'):
302n/a with support.DirsOnSysPath(cwd):
303n/a # Start as a namespace package.
304n/a self.init.invalidate_caches()
305n/a bad_path = os.path.join(cwd, name, '__init.py')
306n/a cached = self.util.cache_from_source(bad_path)
307n/a expected = {'__name__': name,
308n/a '__package__': name,
309n/a '__doc__': None,
310n/a }
311n/a os.mkdir(name)
312n/a with open(bad_path, 'w') as init_file:
313n/a init_file.write('eggs = None')
314n/a module = self.init.import_module(name)
315n/a ns = vars(module).copy()
316n/a loader = ns.pop('__loader__')
317n/a path = ns.pop('__path__')
318n/a spec = ns.pop('__spec__')
319n/a ns.pop('__builtins__', None) # An implementation detail.
320n/a self.assertEqual(spec.name, name)
321n/a self.assertIs(spec.loader, None)
322n/a self.assertIsNot(loader, None)
323n/a self.assertEqual(set(path),
324n/a set([os.path.dirname(bad_path)]))
325n/a with self.assertRaises(AttributeError):
326n/a # a NamespaceLoader
327n/a loader.path
328n/a self.assertEqual(ns, expected)
329n/a
330n/a # Change to a regular package.
331n/a self.init.invalidate_caches()
332n/a init_path = os.path.join(cwd, name, '__init__.py')
333n/a cached = self.util.cache_from_source(init_path)
334n/a expected = {'__name__': name,
335n/a '__package__': name,
336n/a '__file__': init_path,
337n/a '__cached__': cached,
338n/a '__path__': [os.path.dirname(init_path)],
339n/a '__doc__': None,
340n/a 'eggs': None,
341n/a }
342n/a os.rename(bad_path, init_path)
343n/a reloaded = self.init.reload(module)
344n/a ns = vars(reloaded).copy()
345n/a loader = ns.pop('__loader__')
346n/a spec = ns.pop('__spec__')
347n/a ns.pop('__builtins__', None) # An implementation detail.
348n/a self.assertEqual(spec.name, name)
349n/a self.assertEqual(spec.loader, loader)
350n/a self.assertIs(reloaded, module)
351n/a self.assertEqual(loader.path, init_path)
352n/a self.assertEqual(ns, expected)
353n/a
354n/a def test_reload_submodule(self):
355n/a # See #19851.
356n/a name = 'spam'
357n/a subname = 'ham'
358n/a with test_util.temp_module(name, pkg=True) as pkg_dir:
359n/a fullname, _ = test_util.submodule(name, subname, pkg_dir)
360n/a ham = self.init.import_module(fullname)
361n/a reloaded = self.init.reload(ham)
362n/a self.assertIs(reloaded, ham)
363n/a
364n/a
365n/a(Frozen_ReloadTests,
366n/a Source_ReloadTests
367n/a ) = test_util.test_both(ReloadTests, init=init, util=util)
368n/a
369n/a
370n/aclass InvalidateCacheTests:
371n/a
372n/a def test_method_called(self):
373n/a # If defined the method should be called.
374n/a class InvalidatingNullFinder:
375n/a def __init__(self, *ignored):
376n/a self.called = False
377n/a def find_module(self, *args):
378n/a return None
379n/a def invalidate_caches(self):
380n/a self.called = True
381n/a
382n/a key = 'gobledeegook'
383n/a meta_ins = InvalidatingNullFinder()
384n/a path_ins = InvalidatingNullFinder()
385n/a sys.meta_path.insert(0, meta_ins)
386n/a self.addCleanup(lambda: sys.path_importer_cache.__delitem__(key))
387n/a sys.path_importer_cache[key] = path_ins
388n/a self.addCleanup(lambda: sys.meta_path.remove(meta_ins))
389n/a self.init.invalidate_caches()
390n/a self.assertTrue(meta_ins.called)
391n/a self.assertTrue(path_ins.called)
392n/a
393n/a def test_method_lacking(self):
394n/a # There should be no issues if the method is not defined.
395n/a key = 'gobbledeegook'
396n/a sys.path_importer_cache[key] = None
397n/a self.addCleanup(lambda: sys.path_importer_cache.__delitem__(key))
398n/a self.init.invalidate_caches() # Shouldn't trigger an exception.
399n/a
400n/a
401n/a(Frozen_InvalidateCacheTests,
402n/a Source_InvalidateCacheTests
403n/a ) = test_util.test_both(InvalidateCacheTests, init=init)
404n/a
405n/a
406n/aclass FrozenImportlibTests(unittest.TestCase):
407n/a
408n/a def test_no_frozen_importlib(self):
409n/a # Should be able to import w/o _frozen_importlib being defined.
410n/a # Can't do an isinstance() check since separate copies of importlib
411n/a # may have been used for import, so just check the name is not for the
412n/a # frozen loader.
413n/a source_init = init['Source']
414n/a self.assertNotEqual(source_init.__loader__.__class__.__name__,
415n/a 'FrozenImporter')
416n/a
417n/a
418n/aclass StartupTests:
419n/a
420n/a def test_everyone_has___loader__(self):
421n/a # Issue #17098: all modules should have __loader__ defined.
422n/a for name, module in sys.modules.items():
423n/a if isinstance(module, types.ModuleType):
424n/a with self.subTest(name=name):
425n/a self.assertTrue(hasattr(module, '__loader__'),
426n/a '{!r} lacks a __loader__ attribute'.format(name))
427n/a if self.machinery.BuiltinImporter.find_module(name):
428n/a self.assertIsNot(module.__loader__, None)
429n/a elif self.machinery.FrozenImporter.find_module(name):
430n/a self.assertIsNot(module.__loader__, None)
431n/a
432n/a def test_everyone_has___spec__(self):
433n/a for name, module in sys.modules.items():
434n/a if isinstance(module, types.ModuleType):
435n/a with self.subTest(name=name):
436n/a self.assertTrue(hasattr(module, '__spec__'))
437n/a if self.machinery.BuiltinImporter.find_module(name):
438n/a self.assertIsNot(module.__spec__, None)
439n/a elif self.machinery.FrozenImporter.find_module(name):
440n/a self.assertIsNot(module.__spec__, None)
441n/a
442n/a
443n/a(Frozen_StartupTests,
444n/a Source_StartupTests
445n/a ) = test_util.test_both(StartupTests, machinery=machinery)
446n/a
447n/a
448n/aif __name__ == '__main__':
449n/a unittest.main()