Home | History | Annotate | Download | only in test
      1 import errno
      2 import imp
      3 import marshal
      4 import os
      5 import py_compile
      6 import random
      7 import stat
      8 import struct
      9 import sys
     10 import unittest
     11 import textwrap
     12 import shutil
     13 
     14 from test.test_support import (unlink, TESTFN, unload, run_unittest, rmtree,
     15                                is_jython, check_warnings, EnvironmentVarGuard)
     16 from test import symlink_support
     17 from test import script_helper
     18 
     19 def _files(name):
     20     return (name + os.extsep + "py",
     21             name + os.extsep + "pyc",
     22             name + os.extsep + "pyo",
     23             name + os.extsep + "pyw",
     24             name + "$py.class")
     25 
     26 def chmod_files(name):
     27     for f in _files(name):
     28         try:
     29             os.chmod(f, 0600)
     30         except OSError as exc:
     31             if exc.errno != errno.ENOENT:
     32                 raise
     33 
     34 def remove_files(name):
     35     for f in _files(name):
     36         unlink(f)
     37 
     38 
     39 class ImportTests(unittest.TestCase):
     40 
     41     def tearDown(self):
     42         unload(TESTFN)
     43     setUp = tearDown
     44 
     45     def test_case_sensitivity(self):
     46         # Brief digression to test that import is case-sensitive:  if we got
     47         # this far, we know for sure that "random" exists.
     48         try:
     49             import RAnDoM
     50         except ImportError:
     51             pass
     52         else:
     53             self.fail("import of RAnDoM should have failed (case mismatch)")
     54 
     55     def test_double_const(self):
     56         # Another brief digression to test the accuracy of manifest float
     57         # constants.
     58         from test import double_const  # don't blink -- that *was* the test
     59 
     60     def test_import(self):
     61         def test_with_extension(ext):
     62             # The extension is normally ".py", perhaps ".pyw".
     63             source = TESTFN + ext
     64             pyo = TESTFN + os.extsep + "pyo"
     65             if is_jython:
     66                 pyc = TESTFN + "$py.class"
     67             else:
     68                 pyc = TESTFN + os.extsep + "pyc"
     69 
     70             with open(source, "w") as f:
     71                 print >> f, ("# This tests Python's ability to import a", ext,
     72                              "file.")
     73                 a = random.randrange(1000)
     74                 b = random.randrange(1000)
     75                 print >> f, "a =", a
     76                 print >> f, "b =", b
     77 
     78             try:
     79                 mod = __import__(TESTFN)
     80             except ImportError, err:
     81                 self.fail("import from %s failed: %s" % (ext, err))
     82             else:
     83                 self.assertEqual(mod.a, a,
     84                     "module loaded (%s) but contents invalid" % mod)
     85                 self.assertEqual(mod.b, b,
     86                     "module loaded (%s) but contents invalid" % mod)
     87             finally:
     88                 unlink(source)
     89 
     90             try:
     91                 if not sys.dont_write_bytecode:
     92                     imp.reload(mod)
     93             except ImportError, err:
     94                 self.fail("import from .pyc/.pyo failed: %s" % err)
     95             finally:
     96                 unlink(pyc)
     97                 unlink(pyo)
     98                 unload(TESTFN)
     99 
    100         sys.path.insert(0, os.curdir)
    101         try:
    102             test_with_extension(os.extsep + "py")
    103             if sys.platform.startswith("win"):
    104                 for ext in [".PY", ".Py", ".pY", ".pyw", ".PYW", ".pYw"]:
    105                     test_with_extension(ext)
    106         finally:
    107             del sys.path[0]
    108 
    109     @unittest.skipUnless(os.name == 'posix',
    110         "test meaningful only on posix systems")
    111     @unittest.skipIf(sys.dont_write_bytecode,
    112         "test meaningful only when writing bytecode")
    113     def test_execute_bit_not_copied(self):
    114         # Issue 6070: under posix .pyc files got their execute bit set if
    115         # the .py file had the execute bit set, but they aren't executable.
    116         oldmask = os.umask(022)
    117         sys.path.insert(0, os.curdir)
    118         try:
    119             fname = TESTFN + os.extsep + "py"
    120             f = open(fname, 'w').close()
    121             os.chmod(fname, (stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH |
    122                              stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH))
    123             __import__(TESTFN)
    124             fn = fname + 'c'
    125             if not os.path.exists(fn):
    126                 fn = fname + 'o'
    127                 if not os.path.exists(fn):
    128                     self.fail("__import__ did not result in creation of "
    129                               "either a .pyc or .pyo file")
    130             s = os.stat(fn)
    131             self.assertEqual(stat.S_IMODE(s.st_mode),
    132                              stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH)
    133         finally:
    134             os.umask(oldmask)
    135             remove_files(TESTFN)
    136             unload(TESTFN)
    137             del sys.path[0]
    138 
    139     @unittest.skipIf(sys.dont_write_bytecode,
    140         "test meaningful only when writing bytecode")
    141     def test_rewrite_pyc_with_read_only_source(self):
    142         # Issue 6074: a long time ago on posix, and more recently on Windows,
    143         # a read only source file resulted in a read only pyc file, which
    144         # led to problems with updating it later
    145         sys.path.insert(0, os.curdir)
    146         fname = TESTFN + os.extsep + "py"
    147         try:
    148             # Write a Python file, make it read-only and import it
    149             with open(fname, 'w') as f:
    150                 f.write("x = 'original'\n")
    151             # Tweak the mtime of the source to ensure pyc gets updated later
    152             s = os.stat(fname)
    153             os.utime(fname, (s.st_atime, s.st_mtime-100000000))
    154             os.chmod(fname, 0400)
    155             m1 = __import__(TESTFN)
    156             self.assertEqual(m1.x, 'original')
    157             # Change the file and then reimport it
    158             os.chmod(fname, 0600)
    159             with open(fname, 'w') as f:
    160                 f.write("x = 'rewritten'\n")
    161             unload(TESTFN)
    162             m2 = __import__(TESTFN)
    163             self.assertEqual(m2.x, 'rewritten')
    164             # Now delete the source file and check the pyc was rewritten
    165             unlink(fname)
    166             unload(TESTFN)
    167             m3 = __import__(TESTFN)
    168             self.assertEqual(m3.x, 'rewritten')
    169         finally:
    170             chmod_files(TESTFN)
    171             remove_files(TESTFN)
    172             unload(TESTFN)
    173             del sys.path[0]
    174 
    175     def test_imp_module(self):
    176         # Verify that the imp module can correctly load and find .py files
    177 
    178         # XXX (ncoghlan): It would be nice to use test_support.CleanImport
    179         # here, but that breaks because the os module registers some
    180         # handlers in copy_reg on import. Since CleanImport doesn't
    181         # revert that registration, the module is left in a broken
    182         # state after reversion. Reinitialising the module contents
    183         # and just reverting os.environ to its previous state is an OK
    184         # workaround
    185         orig_path = os.path
    186         orig_getenv = os.getenv
    187         with EnvironmentVarGuard():
    188             x = imp.find_module("os")
    189             new_os = imp.load_module("os", *x)
    190             self.assertIs(os, new_os)
    191             self.assertIs(orig_path, new_os.path)
    192             self.assertIsNot(orig_getenv, new_os.getenv)
    193 
    194     def test_module_with_large_stack(self, module='longlist'):
    195         # Regression test for http://bugs.python.org/issue561858.
    196         filename = module + os.extsep + 'py'
    197 
    198         # Create a file with a list of 65000 elements.
    199         with open(filename, 'w+') as f:
    200             f.write('d = [\n')
    201             for i in range(65000):
    202                 f.write('"",\n')
    203             f.write(']')
    204 
    205         # Compile & remove .py file, we only need .pyc (or .pyo).
    206         with open(filename, 'r') as f:
    207             py_compile.compile(filename)
    208         unlink(filename)
    209 
    210         # Need to be able to load from current dir.
    211         sys.path.append('')
    212 
    213         # This used to crash.
    214         exec 'import ' + module
    215 
    216         # Cleanup.
    217         del sys.path[-1]
    218         unlink(filename + 'c')
    219         unlink(filename + 'o')
    220 
    221     def test_failing_import_sticks(self):
    222         source = TESTFN + os.extsep + "py"
    223         with open(source, "w") as f:
    224             print >> f, "a = 1 // 0"
    225 
    226         # New in 2.4, we shouldn't be able to import that no matter how often
    227         # we try.
    228         sys.path.insert(0, os.curdir)
    229         try:
    230             for i in [1, 2, 3]:
    231                 self.assertRaises(ZeroDivisionError, __import__, TESTFN)
    232                 self.assertNotIn(TESTFN, sys.modules,
    233                                  "damaged module in sys.modules on %i try" % i)
    234         finally:
    235             del sys.path[0]
    236             remove_files(TESTFN)
    237 
    238     def test_failing_reload(self):
    239         # A failing reload should leave the module object in sys.modules.
    240         source = TESTFN + os.extsep + "py"
    241         with open(source, "w") as f:
    242             print >> f, "a = 1"
    243             print >> f, "b = 2"
    244 
    245         sys.path.insert(0, os.curdir)
    246         try:
    247             mod = __import__(TESTFN)
    248             self.assertIn(TESTFN, sys.modules)
    249             self.assertEqual(mod.a, 1, "module has wrong attribute values")
    250             self.assertEqual(mod.b, 2, "module has wrong attribute values")
    251 
    252             # On WinXP, just replacing the .py file wasn't enough to
    253             # convince reload() to reparse it.  Maybe the timestamp didn't
    254             # move enough.  We force it to get reparsed by removing the
    255             # compiled file too.
    256             remove_files(TESTFN)
    257 
    258             # Now damage the module.
    259             with open(source, "w") as f:
    260                 print >> f, "a = 10"
    261                 print >> f, "b = 20//0"
    262 
    263             self.assertRaises(ZeroDivisionError, imp.reload, mod)
    264 
    265             # But we still expect the module to be in sys.modules.
    266             mod = sys.modules.get(TESTFN)
    267             self.assertIsNot(mod, None, "expected module to be in sys.modules")
    268 
    269             # We should have replaced a w/ 10, but the old b value should
    270             # stick.
    271             self.assertEqual(mod.a, 10, "module has wrong attribute values")
    272             self.assertEqual(mod.b, 2, "module has wrong attribute values")
    273 
    274         finally:
    275             del sys.path[0]
    276             remove_files(TESTFN)
    277             unload(TESTFN)
    278 
    279     def test_infinite_reload(self):
    280         # http://bugs.python.org/issue742342 reports that Python segfaults
    281         # (infinite recursion in C) when faced with self-recursive reload()ing.
    282 
    283         sys.path.insert(0, os.path.dirname(__file__))
    284         try:
    285             import infinite_reload
    286         finally:
    287             del sys.path[0]
    288 
    289     def test_import_name_binding(self):
    290         # import x.y.z binds x in the current namespace.
    291         import test as x
    292         import test.test_support
    293         self.assertIs(x, test, x.__name__)
    294         self.assertTrue(hasattr(test.test_support, "__file__"))
    295 
    296         # import x.y.z as w binds z as w.
    297         import test.test_support as y
    298         self.assertIs(y, test.test_support, y.__name__)
    299 
    300     def test_import_initless_directory_warning(self):
    301         with check_warnings(('', ImportWarning)):
    302             # Just a random non-package directory we always expect to be
    303             # somewhere in sys.path...
    304             self.assertRaises(ImportError, __import__, "site-packages")
    305 
    306     def test_import_by_filename(self):
    307         path = os.path.abspath(TESTFN)
    308         with self.assertRaises(ImportError) as c:
    309             __import__(path)
    310         self.assertEqual("Import by filename is not supported.",
    311                          c.exception.args[0])
    312 
    313     def test_import_in_del_does_not_crash(self):
    314         # Issue 4236
    315         testfn = script_helper.make_script('', TESTFN, textwrap.dedent("""\
    316             import sys
    317             class C:
    318                def __del__(self):
    319                   import imp
    320             sys.argv.insert(0, C())
    321             """))
    322         try:
    323             script_helper.assert_python_ok(testfn)
    324         finally:
    325             unlink(testfn)
    326 
    327     def test_bug7732(self):
    328         source = TESTFN + '.py'
    329         os.mkdir(source)
    330         try:
    331             self.assertRaises((ImportError, IOError),
    332                               imp.find_module, TESTFN, ["."])
    333         finally:
    334             os.rmdir(source)
    335 
    336     def test_timestamp_overflow(self):
    337         # A modification timestamp larger than 2**32 should not be a problem
    338         # when importing a module (issue #11235).
    339         sys.path.insert(0, os.curdir)
    340         try:
    341             source = TESTFN + ".py"
    342             compiled = source + ('c' if __debug__ else 'o')
    343             with open(source, 'w') as f:
    344                 pass
    345             try:
    346                 os.utime(source, (2 ** 33 - 5, 2 ** 33 - 5))
    347             except OverflowError:
    348                 self.skipTest("cannot set modification time to large integer")
    349             except OSError as e:
    350                 if e.errno != getattr(errno, 'EOVERFLOW', None):
    351                     raise
    352                 self.skipTest("cannot set modification time to large integer ({})".format(e))
    353             __import__(TESTFN)
    354             # The pyc file was created.
    355             os.stat(compiled)
    356         finally:
    357             del sys.path[0]
    358             remove_files(TESTFN)
    359 
    360     def test_pyc_mtime(self):
    361         # Test for issue #13863: .pyc timestamp sometimes incorrect on Windows.
    362         sys.path.insert(0, os.curdir)
    363         try:
    364             # Jan 1, 2012; Jul 1, 2012.
    365             mtimes = 1325376000, 1341100800
    366 
    367             # Different names to avoid running into import caching.
    368             tails = "spam", "eggs"
    369             for mtime, tail in zip(mtimes, tails):
    370                 module = TESTFN + tail
    371                 source = module + ".py"
    372                 compiled = source + ('c' if __debug__ else 'o')
    373 
    374                 # Create a new Python file with the given mtime.
    375                 with open(source, 'w') as f:
    376                     f.write("# Just testing\nx=1, 2, 3\n")
    377                 os.utime(source, (mtime, mtime))
    378 
    379                 # Generate the .pyc/o file; if it couldn't be created
    380                 # for some reason, skip the test.
    381                 m = __import__(module)
    382                 if not os.path.exists(compiled):
    383                     unlink(source)
    384                     self.skipTest("Couldn't create .pyc/.pyo file.")
    385 
    386                 # Actual modification time of .py file.
    387                 mtime1 = int(os.stat(source).st_mtime) & 0xffffffff
    388 
    389                 # mtime that was encoded in the .pyc file.
    390                 with open(compiled, 'rb') as f:
    391                     mtime2 = struct.unpack('<L', f.read(8)[4:])[0]
    392 
    393                 unlink(compiled)
    394                 unlink(source)
    395 
    396                 self.assertEqual(mtime1, mtime2)
    397         finally:
    398             sys.path.pop(0)
    399 
    400 
    401 class PycRewritingTests(unittest.TestCase):
    402     # Test that the `co_filename` attribute on code objects always points
    403     # to the right file, even when various things happen (e.g. both the .py
    404     # and the .pyc file are renamed).
    405 
    406     module_name = "unlikely_module_name"
    407     module_source = """
    408 import sys
    409 code_filename = sys._getframe().f_code.co_filename
    410 module_filename = __file__
    411 constant = 1
    412 def func():
    413     pass
    414 func_filename = func.func_code.co_filename
    415 """
    416     dir_name = os.path.abspath(TESTFN)
    417     file_name = os.path.join(dir_name, module_name) + os.extsep + "py"
    418     compiled_name = file_name + ("c" if __debug__ else "o")
    419 
    420     def setUp(self):
    421         self.sys_path = sys.path[:]
    422         self.orig_module = sys.modules.pop(self.module_name, None)
    423         os.mkdir(self.dir_name)
    424         with open(self.file_name, "w") as f:
    425             f.write(self.module_source)
    426         sys.path.insert(0, self.dir_name)
    427 
    428     def tearDown(self):
    429         sys.path[:] = self.sys_path
    430         if self.orig_module is not None:
    431             sys.modules[self.module_name] = self.orig_module
    432         else:
    433             unload(self.module_name)
    434         unlink(self.file_name)
    435         unlink(self.compiled_name)
    436         rmtree(self.dir_name)
    437 
    438     def import_module(self):
    439         ns = globals()
    440         __import__(self.module_name, ns, ns)
    441         return sys.modules[self.module_name]
    442 
    443     def test_basics(self):
    444         mod = self.import_module()
    445         self.assertEqual(mod.module_filename, self.file_name)
    446         self.assertEqual(mod.code_filename, self.file_name)
    447         self.assertEqual(mod.func_filename, self.file_name)
    448         del sys.modules[self.module_name]
    449         mod = self.import_module()
    450         if not sys.dont_write_bytecode:
    451             self.assertEqual(mod.module_filename, self.compiled_name)
    452         self.assertEqual(mod.code_filename, self.file_name)
    453         self.assertEqual(mod.func_filename, self.file_name)
    454 
    455     def test_incorrect_code_name(self):
    456         py_compile.compile(self.file_name, dfile="another_module.py")
    457         mod = self.import_module()
    458         self.assertEqual(mod.module_filename, self.compiled_name)
    459         self.assertEqual(mod.code_filename, self.file_name)
    460         self.assertEqual(mod.func_filename, self.file_name)
    461 
    462     def test_module_without_source(self):
    463         target = "another_module.py"
    464         py_compile.compile(self.file_name, dfile=target)
    465         os.remove(self.file_name)
    466         mod = self.import_module()
    467         self.assertEqual(mod.module_filename, self.compiled_name)
    468         self.assertEqual(mod.code_filename, target)
    469         self.assertEqual(mod.func_filename, target)
    470 
    471     def test_foreign_code(self):
    472         py_compile.compile(self.file_name)
    473         with open(self.compiled_name, "rb") as f:
    474             header = f.read(8)
    475             code = marshal.load(f)
    476         constants = list(code.co_consts)
    477         foreign_code = test_main.func_code
    478         pos = constants.index(1)
    479         constants[pos] = foreign_code
    480         code = type(code)(code.co_argcount, code.co_nlocals, code.co_stacksize,
    481                           code.co_flags, code.co_code, tuple(constants),
    482                           code.co_names, code.co_varnames, code.co_filename,
    483                           code.co_name, code.co_firstlineno, code.co_lnotab,
    484                           code.co_freevars, code.co_cellvars)
    485         with open(self.compiled_name, "wb") as f:
    486             f.write(header)
    487             marshal.dump(code, f)
    488         mod = self.import_module()
    489         self.assertEqual(mod.constant.co_filename, foreign_code.co_filename)
    490 
    491 
    492 class PathsTests(unittest.TestCase):
    493     path = TESTFN
    494 
    495     def setUp(self):
    496         os.mkdir(self.path)
    497         self.syspath = sys.path[:]
    498 
    499     def tearDown(self):
    500         rmtree(self.path)
    501         sys.path[:] = self.syspath
    502 
    503     # Regression test for http://bugs.python.org/issue1293.
    504     def test_trailing_slash(self):
    505         with open(os.path.join(self.path, 'test_trailing_slash.py'), 'w') as f:
    506             f.write("testdata = 'test_trailing_slash'")
    507         sys.path.append(self.path+'/')
    508         mod = __import__("test_trailing_slash")
    509         self.assertEqual(mod.testdata, 'test_trailing_slash')
    510         unload("test_trailing_slash")
    511 
    512     # Regression test for http://bugs.python.org/issue3677.
    513     def _test_UNC_path(self):
    514         with open(os.path.join(self.path, 'test_trailing_slash.py'), 'w') as f:
    515             f.write("testdata = 'test_trailing_slash'")
    516         # Create the UNC path, like \\myhost\c$\foo\bar.
    517         path = os.path.abspath(self.path)
    518         import socket
    519         hn = socket.gethostname()
    520         drive = path[0]
    521         unc = "\\\\%s\\%s$"%(hn, drive)
    522         unc += path[2:]
    523         try:
    524             os.listdir(unc)
    525         except OSError as e:
    526             if e.errno in (errno.EPERM, errno.EACCES):
    527                 # See issue #15338
    528                 self.skipTest("cannot access administrative share %r" % (unc,))
    529             raise
    530         sys.path.append(path)
    531         mod = __import__("test_trailing_slash")
    532         self.assertEqual(mod.testdata, 'test_trailing_slash')
    533         unload("test_trailing_slash")
    534 
    535     if sys.platform == "win32":
    536         test_UNC_path = _test_UNC_path
    537 
    538 
    539 class RelativeImportTests(unittest.TestCase):
    540 
    541     def tearDown(self):
    542         unload("test.relimport")
    543     setUp = tearDown
    544 
    545     def test_relimport_star(self):
    546         # This will import * from .test_import.
    547         from . import relimport
    548         self.assertTrue(hasattr(relimport, "RelativeImportTests"))
    549 
    550     def test_issue3221(self):
    551         # Regression test for http://bugs.python.org/issue3221.
    552         def check_absolute():
    553             exec "from os import path" in ns
    554         def check_relative():
    555             exec "from . import relimport" in ns
    556 
    557         # Check both OK with __package__ and __name__ correct
    558         ns = dict(__package__='test', __name__='test.notarealmodule')
    559         check_absolute()
    560         check_relative()
    561 
    562         # Check both OK with only __name__ wrong
    563         ns = dict(__package__='test', __name__='notarealpkg.notarealmodule')
    564         check_absolute()
    565         check_relative()
    566 
    567         # Check relative fails with only __package__ wrong
    568         ns = dict(__package__='foo', __name__='test.notarealmodule')
    569         with check_warnings(('.+foo', RuntimeWarning)):
    570             check_absolute()
    571         self.assertRaises(SystemError, check_relative)
    572 
    573         # Check relative fails with __package__ and __name__ wrong
    574         ns = dict(__package__='foo', __name__='notarealpkg.notarealmodule')
    575         with check_warnings(('.+foo', RuntimeWarning)):
    576             check_absolute()
    577         self.assertRaises(SystemError, check_relative)
    578 
    579         # Check both fail with package set to a non-string
    580         ns = dict(__package__=object())
    581         self.assertRaises(ValueError, check_absolute)
    582         self.assertRaises(ValueError, check_relative)
    583 
    584     def test_absolute_import_without_future(self):
    585         # If explicit relative import syntax is used, then do not try
    586         # to perform an absolute import in the face of failure.
    587         # Issue #7902.
    588         with self.assertRaises(ImportError):
    589             from .os import sep
    590             self.fail("explicit relative import triggered an "
    591                       "implicit absolute import")
    592 
    593 
    594 class TestSymbolicallyLinkedPackage(unittest.TestCase):
    595     package_name = 'sample'
    596 
    597     def setUp(self):
    598         if os.path.exists(self.tagged):
    599             shutil.rmtree(self.tagged)
    600         if os.path.exists(self.package_name):
    601             symlink_support.remove_symlink(self.package_name)
    602         self.orig_sys_path = sys.path[:]
    603 
    604         # create a sample package; imagine you have a package with a tag and
    605         #  you want to symbolically link it from its untagged name.
    606         os.mkdir(self.tagged)
    607         init_file = os.path.join(self.tagged, '__init__.py')
    608         open(init_file, 'w').close()
    609         assert os.path.exists(init_file)
    610 
    611         # now create a symlink to the tagged package
    612         # sample -> sample-tagged
    613         symlink_support.symlink(self.tagged, self.package_name)
    614 
    615         assert os.path.isdir(self.package_name)
    616         assert os.path.isfile(os.path.join(self.package_name, '__init__.py'))
    617 
    618     @property
    619     def tagged(self):
    620         return self.package_name + '-tagged'
    621 
    622     # regression test for issue6727
    623     @unittest.skipUnless(
    624         not hasattr(sys, 'getwindowsversion')
    625         or sys.getwindowsversion() >= (6, 0),
    626         "Windows Vista or later required")
    627     @symlink_support.skip_unless_symlink
    628     def test_symlinked_dir_importable(self):
    629         # make sure sample can only be imported from the current directory.
    630         sys.path[:] = ['.']
    631 
    632         # and try to import the package
    633         __import__(self.package_name)
    634 
    635     def tearDown(self):
    636         # now cleanup
    637         if os.path.exists(self.package_name):
    638             symlink_support.remove_symlink(self.package_name)
    639         if os.path.exists(self.tagged):
    640             shutil.rmtree(self.tagged)
    641         sys.path[:] = self.orig_sys_path
    642 
    643 def test_main(verbose=None):
    644     run_unittest(ImportTests, PycRewritingTests, PathsTests,
    645         RelativeImportTests, TestSymbolicallyLinkedPackage)
    646 
    647 if __name__ == '__main__':
    648     # Test needs to be a package, so we can do relative imports.
    649     from test.test_import import test_main
    650     test_main()
    651