1# Test packages (dotted-name import) 2 3import sys 4import os 5import tempfile 6import textwrap 7import unittest 8from test import support 9 10 11# Helpers to create and destroy hierarchies. 12 13def 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 23def 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 47class 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 294if __name__ == "__main__": 295 unittest.main() 296