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