blob: a868ced87b107db408638a5bd66088baed459da6 [file] [log] [blame]
Nick Coghlanf088e5e2008-12-14 11:50:48 +00001# This test module covers support in various parts of the standard library
2# for working with modules located inside zipfiles
3# The tests are centralised in this fashion to make it easy to drop them
4# if a platform doesn't support zipimport
5import unittest
6import test.support
7import os
8import os.path
9import sys
10import textwrap
11import zipfile
12import zipimport
13import doctest
14import inspect
15import linecache
16import pdb
Nick Coghlan260bd3e2009-11-16 06:49:25 +000017from test.script_helper import (spawn_python, kill_python, run_python,
18 temp_dir, make_script, compile_script,
19 make_pkg, make_zip_script, make_zip_pkg)
Nick Coghlanf088e5e2008-12-14 11:50:48 +000020
21verbose = test.support.verbose
22
23# Library modules covered by this test set
24# pdb (Issue 4201)
25# inspect (Issue 4223)
26# doctest (Issue 4197)
27
28# Other test modules with zipimport related tests
29# test_zipimport (of course!)
30# test_cmd_line_script (covers the zipimport support in runpy)
31
32# Retrieve some helpers from other test cases
33from test import test_doctest, sample_doctest
34from test.test_importhooks import ImportHooksBaseTestCase
Nick Coghlanf088e5e2008-12-14 11:50:48 +000035
36
37def _run_object_doctest(obj, module):
38 # Direct doctest output (normally just errors) to real stdout; doctest
39 # output shouldn't be compared by regrtest.
40 save_stdout = sys.stdout
41 sys.stdout = test.support.get_original_stdout()
42 try:
43 finder = doctest.DocTestFinder(verbose=verbose, recurse=False)
44 runner = doctest.DocTestRunner(verbose=verbose)
45 # Use the object's fully qualified name if it has one
46 # Otherwise, use the module's name
47 try:
48 name = "%s.%s" % (obj.__module__, obj.__name__)
49 except AttributeError:
50 name = module.__name__
51 for example in finder.find(obj, name, module):
52 runner.run(example)
53 f, t = runner.failures, runner.tries
54 if f:
55 raise test.support.TestFailed("%d of %d doctests failed" % (f, t))
56 finally:
57 sys.stdout = save_stdout
58 if verbose:
59 print ('doctest (%s) ... %d tests with zero failures' % (module.__name__, t))
60 return f, t
61
62
63
64class ZipSupportTests(ImportHooksBaseTestCase):
65 # We use the ImportHooksBaseTestCase to restore
66 # the state of the import related information
67 # in the sys module after each test
68 # We also clear the linecache and zipimport cache
69 # just to avoid any bogus errors due to name reuse in the tests
70 def setUp(self):
71 linecache.clearcache()
72 zipimport._zip_directory_cache.clear()
73 ImportHooksBaseTestCase.setUp(self)
74
75
76 def test_inspect_getsource_issue4223(self):
77 test_src = "def foo(): pass\n"
78 with temp_dir() as d:
Nick Coghlan260bd3e2009-11-16 06:49:25 +000079 init_name = make_script(d, '__init__', test_src)
Nick Coghlanf088e5e2008-12-14 11:50:48 +000080 name_in_zip = os.path.join('zip_pkg',
81 os.path.basename(init_name))
Nick Coghlan260bd3e2009-11-16 06:49:25 +000082 zip_name, run_name = make_zip_script(d, 'test_zip',
Nick Coghlanf088e5e2008-12-14 11:50:48 +000083 init_name, name_in_zip)
84 os.remove(init_name)
85 sys.path.insert(0, zip_name)
86 import zip_pkg
87 self.assertEqual(inspect.getsource(zip_pkg.foo), test_src)
88
89 def test_doctest_issue4197(self):
90 # To avoid having to keep two copies of the doctest module's
91 # unit tests in sync, this test works by taking the source of
92 # test_doctest itself, rewriting it a bit to cope with a new
93 # location, and then throwing it in a zip file to make sure
94 # everything still works correctly
95 test_src = inspect.getsource(test_doctest)
96 test_src = test_src.replace(
97 "from test import test_doctest",
98 "import test_zipped_doctest as test_doctest")
99 test_src = test_src.replace("test.test_doctest",
100 "test_zipped_doctest")
101 test_src = test_src.replace("test.sample_doctest",
102 "sample_zipped_doctest")
103 sample_src = inspect.getsource(sample_doctest)
104 sample_src = sample_src.replace("test.test_doctest",
105 "test_zipped_doctest")
106 with temp_dir() as d:
Nick Coghlan260bd3e2009-11-16 06:49:25 +0000107 script_name = make_script(d, 'test_zipped_doctest',
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000108 test_src)
Nick Coghlan260bd3e2009-11-16 06:49:25 +0000109 zip_name, run_name = make_zip_script(d, 'test_zip',
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000110 script_name)
111 z = zipfile.ZipFile(zip_name, 'a')
112 z.writestr("sample_zipped_doctest.py", sample_src)
113 z.close()
114 if verbose:
115 zip_file = zipfile.ZipFile(zip_name, 'r')
116 print ('Contents of %r:' % zip_name)
117 zip_file.printdir()
118 zip_file.close()
119 os.remove(script_name)
120 sys.path.insert(0, zip_name)
121 import test_zipped_doctest
122 # Some of the doc tests depend on the colocated text files
123 # which aren't available to the zipped version (the doctest
124 # module currently requires real filenames for non-embedded
125 # tests). So we're forced to be selective about which tests
126 # to run.
127 # doctest could really use some APIs which take a text
128 # string or a file object instead of a filename...
129 known_good_tests = [
130 test_zipped_doctest.SampleClass,
131 test_zipped_doctest.SampleClass.NestedClass,
132 test_zipped_doctest.SampleClass.NestedClass.__init__,
133 test_zipped_doctest.SampleClass.__init__,
134 test_zipped_doctest.SampleClass.a_classmethod,
135 test_zipped_doctest.SampleClass.a_property,
136 test_zipped_doctest.SampleClass.a_staticmethod,
137 test_zipped_doctest.SampleClass.double,
138 test_zipped_doctest.SampleClass.get,
139 test_zipped_doctest.SampleNewStyleClass,
140 test_zipped_doctest.SampleNewStyleClass.__init__,
141 test_zipped_doctest.SampleNewStyleClass.double,
142 test_zipped_doctest.SampleNewStyleClass.get,
143 test_zipped_doctest.sample_func,
144 test_zipped_doctest.test_DocTest,
145 test_zipped_doctest.test_DocTestParser,
146 test_zipped_doctest.test_DocTestRunner.basics,
147 test_zipped_doctest.test_DocTestRunner.exceptions,
148 test_zipped_doctest.test_DocTestRunner.option_directives,
149 test_zipped_doctest.test_DocTestRunner.optionflags,
150 test_zipped_doctest.test_DocTestRunner.verbose_flag,
151 test_zipped_doctest.test_Example,
152 test_zipped_doctest.test_debug,
153 test_zipped_doctest.test_pdb_set_trace,
154 test_zipped_doctest.test_pdb_set_trace_nested,
155 test_zipped_doctest.test_testsource,
156 test_zipped_doctest.test_trailing_space_in_test,
157 test_zipped_doctest.test_DocTestSuite,
158 test_zipped_doctest.test_DocTestFinder,
159 ]
160 # These remaining tests are the ones which need access
161 # to the data files, so we don't run them
162 fail_due_to_missing_data_files = [
163 test_zipped_doctest.test_DocFileSuite,
164 test_zipped_doctest.test_testfile,
165 test_zipped_doctest.test_unittest_reportflags,
166 ]
167 for obj in known_good_tests:
168 _run_object_doctest(obj, test_zipped_doctest)
169
Nick Coghlan38622002008-12-15 12:01:34 +0000170 def test_doctest_main_issue4197(self):
171 test_src = textwrap.dedent("""\
172 class Test:
173 ">>> 'line 2'"
174 pass
175
176 import doctest
177 doctest.testmod()
178 """)
179 pattern = 'File "%s", line 2, in %s'
180 with temp_dir() as d:
Nick Coghlan260bd3e2009-11-16 06:49:25 +0000181 script_name = make_script(d, 'script', test_src)
182 exit_code, data = run_python(script_name)
Nick Coghlan38622002008-12-15 12:01:34 +0000183 expected = pattern % (script_name, "__main__.Test")
184 if verbose:
185 print ("Expected line", expected)
186 print ("Got stdout:")
187 print (data)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000188 self.assertIn(expected.encode('utf-8'), data)
Nick Coghlan260bd3e2009-11-16 06:49:25 +0000189 zip_name, run_name = make_zip_script(d, "test_zip",
Nick Coghlan38622002008-12-15 12:01:34 +0000190 script_name, '__main__.py')
Nick Coghlan260bd3e2009-11-16 06:49:25 +0000191 exit_code, data = run_python(zip_name)
Nick Coghlan38622002008-12-15 12:01:34 +0000192 expected = pattern % (run_name, "__main__.Test")
193 if verbose:
194 print ("Expected line", expected)
195 print ("Got stdout:")
196 print (data)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000197 self.assertIn(expected.encode('utf-8'), data)
Nick Coghlan38622002008-12-15 12:01:34 +0000198
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000199 def test_pdb_issue4201(self):
200 test_src = textwrap.dedent("""\
201 def f():
202 pass
203
204 import pdb
205 pdb.runcall(f)
206 """)
207 with temp_dir() as d:
Nick Coghlan260bd3e2009-11-16 06:49:25 +0000208 script_name = make_script(d, 'script', test_src)
209 p = spawn_python(script_name)
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000210 p.stdin.write(b'l\n')
Nick Coghlan260bd3e2009-11-16 06:49:25 +0000211 data = kill_python(p)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000212 self.assertIn(script_name.encode('utf-8'), data)
Nick Coghlan260bd3e2009-11-16 06:49:25 +0000213 zip_name, run_name = make_zip_script(d, "test_zip",
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000214 script_name, '__main__.py')
Nick Coghlan260bd3e2009-11-16 06:49:25 +0000215 p = spawn_python(zip_name)
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000216 p.stdin.write(b'l\n')
Nick Coghlan260bd3e2009-11-16 06:49:25 +0000217 data = kill_python(p)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000218 self.assertIn(run_name.encode('utf-8'), data)
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000219
220
221def test_main():
222 test.support.run_unittest(ZipSupportTests)
223 test.support.reap_children()
224
225if __name__ == '__main__':
226 test_main()