PageRenderTime 45ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/Lib/test/test_zipimport_support.py

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