Home | History | Annotate | Download | only in test
      1 # Test packages (dotted-name import)
      2 
      3 import sys
      4 import os
      5 import tempfile
      6 import textwrap
      7 import unittest
      8 from test import support
      9 
     10 
     11 # Helpers to create and destroy hierarchies.
     12 
     13 def cleanout(root):
     14     names = os.listdir(root)
     15     for name in names:
     16         fullname = os.path.join(root, name)
     17         if os.path.isdir(fullname) and not os.path.islink(fullname):
     18             cleanout(fullname)
     19         else:
     20             os.remove(fullname)
     21     os.rmdir(root)
     22 
     23 def fixdir(lst):
     24     if "__builtins__" in lst:
     25         lst.remove("__builtins__")
     26     if "__initializing__" in lst:
     27         lst.remove("__initializing__")
     28     return lst
     29 
     30 
     31 # XXX Things to test
     32 #
     33 # import package without __init__
     34 # import package with __init__
     35 # __init__ importing submodule
     36 # __init__ importing global module
     37 # __init__ defining variables
     38 # submodule importing other submodule
     39 # submodule importing global module
     40 # submodule import submodule via global name
     41 # from package import submodule
     42 # from package import subpackage
     43 # from package import variable (defined in __init__)
     44 # from package import * (defined in __init__)
     45 
     46 
     47 class TestPkg(unittest.TestCase):
     48 
     49     def setUp(self):
     50         self.root = None
     51         self.pkgname = None
     52         self.syspath = list(sys.path)
     53         self.modules_before = support.modules_setup()
     54 
     55     def tearDown(self):
     56         sys.path[:] = self.syspath
     57         support.modules_cleanup(*self.modules_before)
     58         if self.root: # Only clean if the test was actually run
     59             cleanout(self.root)
     60 
     61         # delete all modules concerning the tested hierarchy
     62         if self.pkgname:
     63             modules = [name for name in sys.modules
     64                        if self.pkgname in name.split('.')]
     65             for name in modules:
     66                 del sys.modules[name]
     67 
     68     def run_code(self, code):
     69         exec(textwrap.dedent(code), globals(), {"self": self})
     70 
     71     def mkhier(self, descr):
     72         root = tempfile.mkdtemp()
     73         sys.path.insert(0, root)
     74         if not os.path.isdir(root):
     75             os.mkdir(root)
     76         for name, contents in descr:
     77             comps = name.split()
     78             fullname = root
     79             for c in comps:
     80                 fullname = os.path.join(fullname, c)
     81             if contents is None:
     82                 os.mkdir(fullname)
     83             else:
     84                 f = open(fullname, "w")
     85                 f.write(contents)
     86                 if contents and contents[-1] != '\n':
     87                     f.write('\n')
     88                 f.close()
     89         self.root = root
     90         # package name is the name of the first item
     91         self.pkgname = descr[0][0]
     92 
     93     def test_1(self):
     94         hier = [("t1", None), ("t1 __init__.py", "")]
     95         self.mkhier(hier)
     96         import t1
     97 
     98     def test_2(self):
     99         hier = [
    100          ("t2", None),
    101          ("t2 __init__.py", "'doc for t2'"),
    102          ("t2 sub", None),
    103          ("t2 sub __init__.py", ""),
    104          ("t2 sub subsub", None),
    105          ("t2 sub subsub __init__.py", "spam = 1"),
    106         ]
    107         self.mkhier(hier)
    108 
    109         import t2.sub
    110         import t2.sub.subsub
    111         self.assertEqual(t2.__name__, "t2")
    112         self.assertEqual(t2.sub.__name__, "t2.sub")
    113         self.assertEqual(t2.sub.subsub.__name__, "t2.sub.subsub")
    114 
    115         # This exec crap is needed because Py3k forbids 'import *' outside
    116         # of module-scope and __import__() is insufficient for what we need.
    117         s = """
    118             import t2
    119             from t2 import *
    120             self.assertEqual(dir(), ['self', 'sub', 't2'])
    121             """
    122         self.run_code(s)
    123 
    124         from t2 import sub
    125         from t2.sub import subsub
    126         from t2.sub.subsub import spam
    127         self.assertEqual(sub.__name__, "t2.sub")
    128         self.assertEqual(subsub.__name__, "t2.sub.subsub")
    129         self.assertEqual(sub.subsub.__name__, "t2.sub.subsub")
    130         for name in ['spam', 'sub', 'subsub', 't2']:
    131             self.assertTrue(locals()["name"], "Failed to import %s" % name)
    132 
    133         import t2.sub
    134         import t2.sub.subsub
    135         self.assertEqual(t2.__name__, "t2")
    136         self.assertEqual(t2.sub.__name__, "t2.sub")
    137         self.assertEqual(t2.sub.subsub.__name__, "t2.sub.subsub")
    138 
    139         s = """
    140             from t2 import *
    141             self.assertTrue(dir(), ['self', 'sub'])
    142             """
    143         self.run_code(s)
    144 
    145     def test_3(self):
    146         hier = [
    147                 ("t3", None),
    148                 ("t3 __init__.py", ""),
    149                 ("t3 sub", None),
    150                 ("t3 sub __init__.py", ""),
    151                 ("t3 sub subsub", None),
    152                 ("t3 sub subsub __init__.py", "spam = 1"),
    153                ]
    154         self.mkhier(hier)
    155 
    156         import t3.sub.subsub
    157         self.assertEqual(t3.__name__, "t3")
    158         self.assertEqual(t3.sub.__name__, "t3.sub")
    159         self.assertEqual(t3.sub.subsub.__name__, "t3.sub.subsub")
    160 
    161     def test_4(self):
    162         hier = [
    163         ("t4.py", "raise RuntimeError('Shouldnt load t4.py')"),
    164         ("t4", None),
    165         ("t4 __init__.py", ""),
    166         ("t4 sub.py", "raise RuntimeError('Shouldnt load sub.py')"),
    167         ("t4 sub", None),
    168         ("t4 sub __init__.py", ""),
    169         ("t4 sub subsub.py",
    170          "raise RuntimeError('Shouldnt load subsub.py')"),
    171         ("t4 sub subsub", None),
    172         ("t4 sub subsub __init__.py", "spam = 1"),
    173                ]
    174         self.mkhier(hier)
    175 
    176         s = """
    177             from t4.sub.subsub import *
    178             self.assertEqual(spam, 1)
    179             """
    180         self.run_code(s)
    181 
    182     def test_5(self):
    183         hier = [
    184         ("t5", None),
    185         ("t5 __init__.py", "import t5.foo"),
    186         ("t5 string.py", "spam = 1"),
    187         ("t5 foo.py",
    188          "from . import string; assert string.spam == 1"),
    189          ]
    190         self.mkhier(hier)
    191 
    192         import t5
    193         s = """
    194             from t5 import *
    195             self.assertEqual(dir(), ['foo', 'self', 'string', 't5'])
    196             """
    197         self.run_code(s)
    198 
    199         import t5
    200         self.assertEqual(fixdir(dir(t5)),
    201                          ['__cached__', '__doc__', '__file__', '__loader__',
    202                           '__name__', '__package__', '__path__', '__spec__',
    203                           'foo', 'string', 't5'])
    204         self.assertEqual(fixdir(dir(t5.foo)),
    205                          ['__cached__', '__doc__', '__file__', '__loader__',
    206                           '__name__', '__package__', '__spec__', 'string'])
    207         self.assertEqual(fixdir(dir(t5.string)),
    208                          ['__cached__', '__doc__', '__file__', '__loader__',
    209                           '__name__', '__package__', '__spec__', 'spam'])
    210 
    211     def test_6(self):
    212         hier = [
    213                 ("t6", None),
    214                 ("t6 __init__.py",
    215                  "__all__ = ['spam', 'ham', 'eggs']"),
    216                 ("t6 spam.py", ""),
    217                 ("t6 ham.py", ""),
    218                 ("t6 eggs.py", ""),
    219                ]
    220         self.mkhier(hier)
    221 
    222         import t6
    223         self.assertEqual(fixdir(dir(t6)),
    224                          ['__all__', '__cached__', '__doc__', '__file__',
    225                           '__loader__', '__name__', '__package__', '__path__',
    226                           '__spec__'])
    227         s = """
    228             import t6
    229             from t6 import *
    230             self.assertEqual(fixdir(dir(t6)),
    231                              ['__all__', '__cached__', '__doc__', '__file__',
    232                               '__loader__', '__name__', '__package__',
    233                               '__path__', '__spec__', 'eggs', 'ham', 'spam'])
    234             self.assertEqual(dir(), ['eggs', 'ham', 'self', 'spam', 't6'])
    235             """
    236         self.run_code(s)
    237 
    238     def test_7(self):
    239         hier = [
    240                 ("t7.py", ""),
    241                 ("t7", None),
    242                 ("t7 __init__.py", ""),
    243                 ("t7 sub.py",
    244                  "raise RuntimeError('Shouldnt load sub.py')"),
    245                 ("t7 sub", None),
    246                 ("t7 sub __init__.py", ""),
    247                 ("t7 sub .py",
    248                  "raise RuntimeError('Shouldnt load subsub.py')"),
    249                 ("t7 sub subsub", None),
    250                 ("t7 sub subsub __init__.py",
    251                  "spam = 1"),
    252                ]
    253         self.mkhier(hier)
    254 
    255 
    256         t7, sub, subsub = None, None, None
    257         import t7 as tas
    258         self.assertEqual(fixdir(dir(tas)),
    259                          ['__cached__', '__doc__', '__file__', '__loader__',
    260                           '__name__', '__package__', '__path__', '__spec__'])
    261         self.assertFalse(t7)
    262         from t7 import sub as subpar
    263         self.assertEqual(fixdir(dir(subpar)),
    264                          ['__cached__', '__doc__', '__file__', '__loader__',
    265                           '__name__', '__package__', '__path__', '__spec__'])
    266         self.assertFalse(t7)
    267         self.assertFalse(sub)
    268         from t7.sub import subsub as subsubsub
    269         self.assertEqual(fixdir(dir(subsubsub)),
    270                          ['__cached__', '__doc__', '__file__', '__loader__',
    271                           '__name__', '__package__', '__path__', '__spec__',
    272                           'spam'])
    273         self.assertFalse(t7)
    274         self.assertFalse(sub)
    275         self.assertFalse(subsub)
    276         from t7.sub.subsub import spam as ham
    277         self.assertEqual(ham, 1)
    278         self.assertFalse(t7)
    279         self.assertFalse(sub)
    280         self.assertFalse(subsub)
    281 
    282     @unittest.skipIf(sys.flags.optimize >= 2,
    283                      "Docstrings are omitted with -O2 and above")
    284     def test_8(self):
    285         hier = [
    286                 ("t8", None),
    287                 ("t8 __init__"+os.extsep+"py", "'doc for t8'"),
    288                ]
    289         self.mkhier(hier)
    290 
    291         import t8
    292         self.assertEqual(t8.__doc__, "doc for t8")
    293 
    294 if __name__ == "__main__":
    295     unittest.main()
    296