ยปCore Development>Code coverage>Lib/importlib/test/source/test_finder.py

Python code coverage for Lib/importlib/test/source/test_finder.py

#countcontent
1n/afrom .. import abc
2n/afrom . import util as source_util
3n/a
4n/afrom importlib import machinery
5n/aimport errno
6n/aimport imp
7n/aimport os
8n/aimport py_compile
9n/afrom test.support import make_legacy_pyc
10n/aimport unittest
11n/aimport warnings
12n/a
13n/a
14n/aclass FinderTests(abc.FinderTests):
15n/a
16n/a """For a top-level module, it should just be found directly in the
17n/a directory being searched. This is true for a directory with source
18n/a [top-level source], bytecode [top-level bc], or both [top-level both].
19n/a There is also the possibility that it is a package [top-level package], in
20n/a which case there will be a directory with the module name and an
21n/a __init__.py file. If there is a directory without an __init__.py an
22n/a ImportWarning is returned [empty dir].
23n/a
24n/a For sub-modules and sub-packages, the same happens as above but only use
25n/a the tail end of the name [sub module] [sub package] [sub empty].
26n/a
27n/a When there is a conflict between a package and module having the same name
28n/a in the same directory, the package wins out [package over module]. This is
29n/a so that imports of modules within the package can occur rather than trigger
30n/a an import error.
31n/a
32n/a When there is a package and module with the same name, always pick the
33n/a package over the module [package over module]. This is so that imports from
34n/a the package have the possibility of succeeding.
35n/a
36n/a """
37n/a
38n/a def import_(self, root, module):
39n/a loader_details = [(machinery.SourceFileLoader,
40n/a machinery.SOURCE_SUFFIXES, True),
41n/a (machinery.SourcelessFileLoader,
42n/a machinery.BYTECODE_SUFFIXES, True)]
43n/a finder = machinery.FileFinder(root, *loader_details)
44n/a return finder.find_module(module)
45n/a
46n/a def run_test(self, test, create=None, *, compile_=None, unlink=None):
47n/a """Test the finding of 'test' with the creation of modules listed in
48n/a 'create'.
49n/a
50n/a Any names listed in 'compile_' are byte-compiled. Modules
51n/a listed in 'unlink' have their source files deleted.
52n/a
53n/a """
54n/a if create is None:
55n/a create = {test}
56n/a with source_util.create_modules(*create) as mapping:
57n/a if compile_:
58n/a for name in compile_:
59n/a py_compile.compile(mapping[name])
60n/a if unlink:
61n/a for name in unlink:
62n/a os.unlink(mapping[name])
63n/a try:
64n/a make_legacy_pyc(mapping[name])
65n/a except OSError as error:
66n/a # Some tests do not set compile_=True so the source
67n/a # module will not get compiled and there will be no
68n/a # PEP 3147 pyc file to rename.
69n/a if error.errno != errno.ENOENT:
70n/a raise
71n/a loader = self.import_(mapping['.root'], test)
72n/a self.assertTrue(hasattr(loader, 'load_module'))
73n/a return loader
74n/a
75n/a def test_module(self):
76n/a # [top-level source]
77n/a self.run_test('top_level')
78n/a # [top-level bc]
79n/a self.run_test('top_level', compile_={'top_level'},
80n/a unlink={'top_level'})
81n/a # [top-level both]
82n/a self.run_test('top_level', compile_={'top_level'})
83n/a
84n/a # [top-level package]
85n/a def test_package(self):
86n/a # Source.
87n/a self.run_test('pkg', {'pkg.__init__'})
88n/a # Bytecode.
89n/a self.run_test('pkg', {'pkg.__init__'}, compile_={'pkg.__init__'},
90n/a unlink={'pkg.__init__'})
91n/a # Both.
92n/a self.run_test('pkg', {'pkg.__init__'}, compile_={'pkg.__init__'})
93n/a
94n/a # [sub module]
95n/a def test_module_in_package(self):
96n/a with source_util.create_modules('pkg.__init__', 'pkg.sub') as mapping:
97n/a pkg_dir = os.path.dirname(mapping['pkg.__init__'])
98n/a loader = self.import_(pkg_dir, 'pkg.sub')
99n/a self.assertTrue(hasattr(loader, 'load_module'))
100n/a
101n/a # [sub package]
102n/a def test_package_in_package(self):
103n/a context = source_util.create_modules('pkg.__init__', 'pkg.sub.__init__')
104n/a with context as mapping:
105n/a pkg_dir = os.path.dirname(mapping['pkg.__init__'])
106n/a loader = self.import_(pkg_dir, 'pkg.sub')
107n/a self.assertTrue(hasattr(loader, 'load_module'))
108n/a
109n/a # [package over modules]
110n/a def test_package_over_module(self):
111n/a name = '_temp'
112n/a loader = self.run_test(name, {'{0}.__init__'.format(name), name})
113n/a self.assertIn('__init__', loader.get_filename(name))
114n/a
115n/a def test_failure(self):
116n/a with source_util.create_modules('blah') as mapping:
117n/a nothing = self.import_(mapping['.root'], 'sdfsadsadf')
118n/a self.assertIsNone(nothing)
119n/a
120n/a def test_empty_string_for_dir(self):
121n/a # The empty string from sys.path means to search in the cwd.
122n/a finder = machinery.FileFinder('', (machinery.SourceFileLoader,
123n/a machinery.SOURCE_SUFFIXES, True))
124n/a with open('mod.py', 'w') as file:
125n/a file.write("# test file for importlib")
126n/a try:
127n/a loader = finder.find_module('mod')
128n/a self.assertTrue(hasattr(loader, 'load_module'))
129n/a finally:
130n/a os.unlink('mod.py')
131n/a
132n/a def test_invalidate_caches(self):
133n/a # invalidate_caches() should reset the mtime.
134n/a finder = machinery.FileFinder('', (machinery.SourceFileLoader,
135n/a machinery.SOURCE_SUFFIXES, True))
136n/a finder._path_mtime = 42
137n/a finder.invalidate_caches()
138n/a self.assertEqual(finder._path_mtime, -1)
139n/a
140n/a
141n/adef test_main():
142n/a from test.support import run_unittest
143n/a run_unittest(FinderTests)
144n/a
145n/a
146n/aif __name__ == '__main__':
147n/a test_main()