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

Python code coverage for Lib/test/test_zipimport_support.py

#countcontent
1n/a# This test module covers support in various parts of the standard library
2n/a# for working with modules located inside zipfiles
3n/a# The tests are centralised in this fashion to make it easy to drop them
4n/a# if a platform doesn't support zipimport
5n/aimport test.support
6n/aimport os
7n/aimport os.path
8n/aimport sys
9n/aimport textwrap
10n/aimport zipfile
11n/aimport zipimport
12n/aimport doctest
13n/aimport inspect
14n/aimport linecache
15n/aimport unittest
16n/afrom test.support.script_helper import (spawn_python, kill_python, assert_python_ok,
17n/a make_script, make_zip_script)
18n/a
19n/averbose = test.support.verbose
20n/a
21n/a# Library modules covered by this test set
22n/a# pdb (Issue 4201)
23n/a# inspect (Issue 4223)
24n/a# doctest (Issue 4197)
25n/a
26n/a# Other test modules with zipimport related tests
27n/a# test_zipimport (of course!)
28n/a# test_cmd_line_script (covers the zipimport support in runpy)
29n/a
30n/a# Retrieve some helpers from other test cases
31n/afrom test import (test_doctest, sample_doctest, sample_doctest_no_doctests,
32n/a sample_doctest_no_docstrings)
33n/a
34n/a
35n/adef _run_object_doctest(obj, module):
36n/a finder = doctest.DocTestFinder(verbose=verbose, recurse=False)
37n/a runner = doctest.DocTestRunner(verbose=verbose)
38n/a # Use the object's fully qualified name if it has one
39n/a # Otherwise, use the module's name
40n/a try:
41n/a name = "%s.%s" % (obj.__module__, obj.__qualname__)
42n/a except AttributeError:
43n/a name = module.__name__
44n/a for example in finder.find(obj, name, module):
45n/a runner.run(example)
46n/a f, t = runner.failures, runner.tries
47n/a if f:
48n/a raise test.support.TestFailed("%d of %d doctests failed" % (f, t))
49n/a if verbose:
50n/a print ('doctest (%s) ... %d tests with zero failures' % (module.__name__, t))
51n/a return f, t
52n/a
53n/a
54n/a
55n/aclass ZipSupportTests(unittest.TestCase):
56n/a # This used to use the ImportHooksBaseTestCase to restore
57n/a # the state of the import related information
58n/a # in the sys module after each test. However, that restores
59n/a # *too much* information and breaks for the invocation
60n/a # of test_doctest. So we do our own thing and leave
61n/a # sys.modules alone.
62n/a # We also clear the linecache and zipimport cache
63n/a # just to avoid any bogus errors due to name reuse in the tests
64n/a def setUp(self):
65n/a linecache.clearcache()
66n/a zipimport._zip_directory_cache.clear()
67n/a self.path = sys.path[:]
68n/a self.meta_path = sys.meta_path[:]
69n/a self.path_hooks = sys.path_hooks[:]
70n/a sys.path_importer_cache.clear()
71n/a
72n/a def tearDown(self):
73n/a sys.path[:] = self.path
74n/a sys.meta_path[:] = self.meta_path
75n/a sys.path_hooks[:] = self.path_hooks
76n/a sys.path_importer_cache.clear()
77n/a
78n/a def test_inspect_getsource_issue4223(self):
79n/a test_src = "def foo(): pass\n"
80n/a with test.support.temp_dir() as d:
81n/a init_name = make_script(d, '__init__', test_src)
82n/a name_in_zip = os.path.join('zip_pkg',
83n/a os.path.basename(init_name))
84n/a zip_name, run_name = make_zip_script(d, 'test_zip',
85n/a init_name, name_in_zip)
86n/a os.remove(init_name)
87n/a sys.path.insert(0, zip_name)
88n/a import zip_pkg
89n/a try:
90n/a self.assertEqual(inspect.getsource(zip_pkg.foo), test_src)
91n/a finally:
92n/a del sys.modules["zip_pkg"]
93n/a
94n/a def test_doctest_issue4197(self):
95n/a # To avoid having to keep two copies of the doctest module's
96n/a # unit tests in sync, this test works by taking the source of
97n/a # test_doctest itself, rewriting it a bit to cope with a new
98n/a # location, and then throwing it in a zip file to make sure
99n/a # everything still works correctly
100n/a test_src = inspect.getsource(test_doctest)
101n/a test_src = test_src.replace(
102n/a "from test import test_doctest",
103n/a "import test_zipped_doctest as test_doctest")
104n/a test_src = test_src.replace("test.test_doctest",
105n/a "test_zipped_doctest")
106n/a test_src = test_src.replace("test.sample_doctest",
107n/a "sample_zipped_doctest")
108n/a # The sample doctest files rewritten to include in the zipped version.
109n/a sample_sources = {}
110n/a for mod in [sample_doctest, sample_doctest_no_doctests,
111n/a sample_doctest_no_docstrings]:
112n/a src = inspect.getsource(mod)
113n/a src = src.replace("test.test_doctest", "test_zipped_doctest")
114n/a # Rewrite the module name so that, for example,
115n/a # "test.sample_doctest" becomes "sample_zipped_doctest".
116n/a mod_name = mod.__name__.split(".")[-1]
117n/a mod_name = mod_name.replace("sample_", "sample_zipped_")
118n/a sample_sources[mod_name] = src
119n/a
120n/a with test.support.temp_dir() as d:
121n/a script_name = make_script(d, 'test_zipped_doctest',
122n/a test_src)
123n/a zip_name, run_name = make_zip_script(d, 'test_zip',
124n/a script_name)
125n/a z = zipfile.ZipFile(zip_name, 'a')
126n/a for mod_name, src in sample_sources.items():
127n/a z.writestr(mod_name + ".py", src)
128n/a z.close()
129n/a if verbose:
130n/a zip_file = zipfile.ZipFile(zip_name, 'r')
131n/a print ('Contents of %r:' % zip_name)
132n/a zip_file.printdir()
133n/a zip_file.close()
134n/a os.remove(script_name)
135n/a sys.path.insert(0, zip_name)
136n/a import test_zipped_doctest
137n/a try:
138n/a # Some of the doc tests depend on the colocated text files
139n/a # which aren't available to the zipped version (the doctest
140n/a # module currently requires real filenames for non-embedded
141n/a # tests). So we're forced to be selective about which tests
142n/a # to run.
143n/a # doctest could really use some APIs which take a text
144n/a # string or a file object instead of a filename...
145n/a known_good_tests = [
146n/a test_zipped_doctest.SampleClass,
147n/a test_zipped_doctest.SampleClass.NestedClass,
148n/a test_zipped_doctest.SampleClass.NestedClass.__init__,
149n/a test_zipped_doctest.SampleClass.__init__,
150n/a test_zipped_doctest.SampleClass.a_classmethod,
151n/a test_zipped_doctest.SampleClass.a_property,
152n/a test_zipped_doctest.SampleClass.a_staticmethod,
153n/a test_zipped_doctest.SampleClass.double,
154n/a test_zipped_doctest.SampleClass.get,
155n/a test_zipped_doctest.SampleNewStyleClass,
156n/a test_zipped_doctest.SampleNewStyleClass.__init__,
157n/a test_zipped_doctest.SampleNewStyleClass.double,
158n/a test_zipped_doctest.SampleNewStyleClass.get,
159n/a test_zipped_doctest.sample_func,
160n/a test_zipped_doctest.test_DocTest,
161n/a test_zipped_doctest.test_DocTestParser,
162n/a test_zipped_doctest.test_DocTestRunner.basics,
163n/a test_zipped_doctest.test_DocTestRunner.exceptions,
164n/a test_zipped_doctest.test_DocTestRunner.option_directives,
165n/a test_zipped_doctest.test_DocTestRunner.optionflags,
166n/a test_zipped_doctest.test_DocTestRunner.verbose_flag,
167n/a test_zipped_doctest.test_Example,
168n/a test_zipped_doctest.test_debug,
169n/a test_zipped_doctest.test_testsource,
170n/a test_zipped_doctest.test_trailing_space_in_test,
171n/a test_zipped_doctest.test_DocTestSuite,
172n/a test_zipped_doctest.test_DocTestFinder,
173n/a ]
174n/a # These tests are the ones which need access
175n/a # to the data files, so we don't run them
176n/a fail_due_to_missing_data_files = [
177n/a test_zipped_doctest.test_DocFileSuite,
178n/a test_zipped_doctest.test_testfile,
179n/a test_zipped_doctest.test_unittest_reportflags,
180n/a ]
181n/a
182n/a for obj in known_good_tests:
183n/a _run_object_doctest(obj, test_zipped_doctest)
184n/a finally:
185n/a del sys.modules["test_zipped_doctest"]
186n/a
187n/a def test_doctest_main_issue4197(self):
188n/a test_src = textwrap.dedent("""\
189n/a class Test:
190n/a ">>> 'line 2'"
191n/a pass
192n/a
193n/a import doctest
194n/a doctest.testmod()
195n/a """)
196n/a pattern = 'File "%s", line 2, in %s'
197n/a with test.support.temp_dir() as d:
198n/a script_name = make_script(d, 'script', test_src)
199n/a rc, out, err = assert_python_ok(script_name)
200n/a expected = pattern % (script_name, "__main__.Test")
201n/a if verbose:
202n/a print ("Expected line", expected)
203n/a print ("Got stdout:")
204n/a print (ascii(out))
205n/a self.assertIn(expected.encode('utf-8'), out)
206n/a zip_name, run_name = make_zip_script(d, "test_zip",
207n/a script_name, '__main__.py')
208n/a rc, out, err = assert_python_ok(zip_name)
209n/a expected = pattern % (run_name, "__main__.Test")
210n/a if verbose:
211n/a print ("Expected line", expected)
212n/a print ("Got stdout:")
213n/a print (ascii(out))
214n/a self.assertIn(expected.encode('utf-8'), out)
215n/a
216n/a def test_pdb_issue4201(self):
217n/a test_src = textwrap.dedent("""\
218n/a def f():
219n/a pass
220n/a
221n/a import pdb
222n/a pdb.Pdb(nosigint=True).runcall(f)
223n/a """)
224n/a with test.support.temp_dir() as d:
225n/a script_name = make_script(d, 'script', test_src)
226n/a p = spawn_python(script_name)
227n/a p.stdin.write(b'l\n')
228n/a data = kill_python(p)
229n/a # bdb/pdb applies normcase to its filename before displaying
230n/a self.assertIn(os.path.normcase(script_name.encode('utf-8')), data)
231n/a zip_name, run_name = make_zip_script(d, "test_zip",
232n/a script_name, '__main__.py')
233n/a p = spawn_python(zip_name)
234n/a p.stdin.write(b'l\n')
235n/a data = kill_python(p)
236n/a # bdb/pdb applies normcase to its filename before displaying
237n/a self.assertIn(os.path.normcase(run_name.encode('utf-8')), data)
238n/a
239n/a
240n/adef tearDownModule():
241n/a test.support.reap_children()
242n/a
243n/aif __name__ == '__main__':
244n/a unittest.main()