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