Home | History | Annotate | Download | only in test
      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.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 pdb
     16 import warnings
     17 from test.script_helper import (spawn_python, kill_python, run_python,
     18                                 temp_dir, make_script, make_zip_script)
     19 
     20 verbose = test.test_support.verbose
     21 
     22 # Library modules covered by this test set

     23 #  pdb (Issue 4201)

     24 #  inspect (Issue 4223)

     25 #  doctest (Issue 4197)

     26 
     27 # Other test modules with zipimport related tests

     28 #  test_zipimport (of course!)

     29 #  test_cmd_line_script (covers the zipimport support in runpy)

     30 
     31 # Retrieve some helpers from other test cases

     32 from test import test_doctest, sample_doctest
     33 from test.test_importhooks import ImportHooksBaseTestCase
     34 
     35 
     36 def _run_object_doctest(obj, module):
     37     # Direct doctest output (normally just errors) to real stdout; doctest

     38     # output shouldn't be compared by regrtest.

     39     save_stdout = sys.stdout
     40     sys.stdout = test.test_support.get_original_stdout()
     41     try:
     42         finder = doctest.DocTestFinder(verbose=verbose, recurse=False)
     43         runner = doctest.DocTestRunner(verbose=verbose)
     44         # Use the object's fully qualified name if it has one

     45         # Otherwise, use the module's name

     46         try:
     47             name = "%s.%s" % (obj.__module__, obj.__name__)
     48         except AttributeError:
     49             name = module.__name__
     50         for example in finder.find(obj, name, module):
     51             runner.run(example)
     52         f, t = runner.failures, runner.tries
     53         if f:
     54             raise test.test_support.TestFailed("%d of %d doctests failed" % (f, t))
     55     finally:
     56         sys.stdout = save_stdout
     57     if verbose:
     58         print 'doctest (%s) ... %d tests with zero failures' % (module.__name__, t)
     59     return f, t
     60 
     61 
     62 
     63 class ZipSupportTests(ImportHooksBaseTestCase):
     64     # We use the ImportHooksBaseTestCase to restore

     65     # the state of the import related information

     66     # in the sys module after each test

     67     # We also clear the linecache and zipimport cache

     68     # just to avoid any bogus errors due to name reuse in the tests

     69     def setUp(self):
     70         linecache.clearcache()
     71         zipimport._zip_directory_cache.clear()
     72         ImportHooksBaseTestCase.setUp(self)
     73 
     74 
     75     def test_inspect_getsource_issue4223(self):
     76         test_src = "def foo(): pass\n"
     77         with temp_dir() as d:
     78             init_name = make_script(d, '__init__', test_src)
     79             name_in_zip = os.path.join('zip_pkg',
     80                                        os.path.basename(init_name))
     81             zip_name, run_name = make_zip_script(d, 'test_zip',
     82                                                 init_name, name_in_zip)
     83             os.remove(init_name)
     84             sys.path.insert(0, zip_name)
     85             import zip_pkg
     86             self.assertEqual(inspect.getsource(zip_pkg.foo), test_src)
     87 
     88     def test_doctest_issue4197(self):
     89         # To avoid having to keep two copies of the doctest module's

     90         # unit tests in sync, this test works by taking the source of

     91         # test_doctest itself, rewriting it a bit to cope with a new

     92         # location, and then throwing it in a zip file to make sure

     93         # everything still works correctly

     94         test_src = inspect.getsource(test_doctest)
     95         test_src = test_src.replace(
     96                          "from test import test_doctest",
     97                          "import test_zipped_doctest as test_doctest")
     98         test_src = test_src.replace("test.test_doctest",
     99                                     "test_zipped_doctest")
    100         test_src = test_src.replace("test.sample_doctest",
    101                                     "sample_zipped_doctest")
    102         sample_src = inspect.getsource(sample_doctest)
    103         sample_src = sample_src.replace("test.test_doctest",
    104                                         "test_zipped_doctest")
    105         with temp_dir() as d:
    106             script_name = make_script(d, 'test_zipped_doctest',
    107                                             test_src)
    108             zip_name, run_name = make_zip_script(d, 'test_zip',
    109                                                 script_name)
    110             z = zipfile.ZipFile(zip_name, 'a')
    111             z.writestr("sample_zipped_doctest.py", sample_src)
    112             z.close()
    113             if verbose:
    114                 zip_file = zipfile.ZipFile(zip_name, 'r')
    115                 print 'Contents of %r:' % zip_name
    116                 zip_file.printdir()
    117                 zip_file.close()
    118             os.remove(script_name)
    119             sys.path.insert(0, zip_name)
    120             import test_zipped_doctest
    121             # Some of the doc tests depend on the colocated text files

    122             # which aren't available to the zipped version (the doctest

    123             # module currently requires real filenames for non-embedded

    124             # tests). So we're forced to be selective about which tests

    125             # to run.

    126             # doctest could really use some APIs which take a text

    127             # string or a file object instead of a filename...

    128             known_good_tests = [
    129                 test_zipped_doctest.SampleClass,
    130                 test_zipped_doctest.SampleClass.NestedClass,
    131                 test_zipped_doctest.SampleClass.NestedClass.__init__,
    132                 test_zipped_doctest.SampleClass.__init__,
    133                 test_zipped_doctest.SampleClass.a_classmethod,
    134                 test_zipped_doctest.SampleClass.a_property,
    135                 test_zipped_doctest.SampleClass.a_staticmethod,
    136                 test_zipped_doctest.SampleClass.double,
    137                 test_zipped_doctest.SampleClass.get,
    138                 test_zipped_doctest.SampleNewStyleClass,
    139                 test_zipped_doctest.SampleNewStyleClass.__init__,
    140                 test_zipped_doctest.SampleNewStyleClass.double,
    141                 test_zipped_doctest.SampleNewStyleClass.get,
    142                 test_zipped_doctest.old_test1,
    143                 test_zipped_doctest.old_test2,
    144                 test_zipped_doctest.old_test3,
    145                 test_zipped_doctest.old_test4,
    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_pdb_set_trace,
    157                 test_zipped_doctest.test_pdb_set_trace_nested,
    158                 test_zipped_doctest.test_testsource,
    159                 test_zipped_doctest.test_trailing_space_in_test,
    160                 test_zipped_doctest.test_DocTestSuite,
    161                 test_zipped_doctest.test_DocTestFinder,
    162             ]
    163             # These remaining tests are the ones which need access

    164             # to the data files, so we don't run them

    165             fail_due_to_missing_data_files = [
    166                 test_zipped_doctest.test_DocFileSuite,
    167                 test_zipped_doctest.test_testfile,
    168                 test_zipped_doctest.test_unittest_reportflags,
    169             ]
    170             # Needed for test_DocTestParser and test_debug

    171             deprecations = [
    172                 # Ignore all warnings about the use of class Tester in this module.

    173                 ("class Tester is deprecated", DeprecationWarning)]
    174             if sys.py3kwarning:
    175                 deprecations += [
    176                     ("backquote not supported", SyntaxWarning),
    177                     ("execfile.. not supported", DeprecationWarning)]
    178             with test.test_support.check_warnings(*deprecations):
    179                 for obj in known_good_tests:
    180                     _run_object_doctest(obj, test_zipped_doctest)
    181 
    182     def test_doctest_main_issue4197(self):
    183         test_src = textwrap.dedent("""\
    184                     class Test:
    185                         ">>> 'line 2'"
    186                         pass
    187 
    188                     import doctest
    189                     doctest.testmod()
    190                     """)
    191         pattern = 'File "%s", line 2, in %s'
    192         with temp_dir() as d:
    193             script_name = make_script(d, 'script', test_src)
    194             exit_code, data = run_python(script_name)
    195             expected = pattern % (script_name, "__main__.Test")
    196             if verbose:
    197                 print "Expected line", expected
    198                 print "Got stdout:"
    199                 print data
    200             self.assertIn(expected, data)
    201             zip_name, run_name = make_zip_script(d, "test_zip",
    202                                                 script_name, '__main__.py')
    203             exit_code, data = run_python(zip_name)
    204             expected = pattern % (run_name, "__main__.Test")
    205             if verbose:
    206                 print "Expected line", expected
    207                 print "Got stdout:"
    208                 print data
    209             self.assertIn(expected, data)
    210 
    211     def test_pdb_issue4201(self):
    212         test_src = textwrap.dedent("""\
    213                     def f():
    214                         pass
    215 
    216                     import pdb
    217                     pdb.runcall(f)
    218                     """)
    219         with temp_dir() as d:
    220             script_name = make_script(d, 'script', test_src)
    221             p = spawn_python(script_name)
    222             p.stdin.write('l\n')
    223             data = kill_python(p)
    224             self.assertIn(script_name, data)
    225             zip_name, run_name = make_zip_script(d, "test_zip",
    226                                                 script_name, '__main__.py')
    227             p = spawn_python(zip_name)
    228             p.stdin.write('l\n')
    229             data = kill_python(p)
    230             self.assertIn(run_name, data)
    231 
    232 
    233 def test_main():
    234     test.test_support.run_unittest(ZipSupportTests)
    235     test.test_support.reap_children()
    236 
    237 if __name__ == '__main__':
    238     test_main()
    239