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