Add NEWS entry as per RDM's suggestion (the bug was actually present
[python.git] / Lib / test / test_pkg.py
blobe3b86e6d8ea6a45c6ccb71fa0578df30a6b61e63
1 # Test packages (dotted-name import)
3 import sys
4 import os
5 import tempfile
6 import textwrap
7 import unittest
8 from test import test_support
11 # Helpers to create and destroy hierarchies.
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)
23 def fixdir(lst):
24 if "__builtins__" in lst:
25 lst.remove("__builtins__")
26 return lst
29 # XXX Things to test
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__)
45 class Test(unittest.TestCase):
47 def setUp(self):
48 self.root = None
49 self.pkgname = None
50 self.syspath = list(sys.path)
52 def tearDown(self):
53 sys.path[:] = self.syspath
54 cleanout(self.root)
56 # delete all modules concerning the tested hiearchy
57 if self.pkgname:
58 modules = [name for name in sys.modules
59 if self.pkgname in name.split('.')]
60 for name in modules:
61 del sys.modules[name]
63 def run_code(self, code):
64 exec(textwrap.dedent(code), globals(), {"self": self})
66 def mkhier(self, descr):
67 root = tempfile.mkdtemp()
68 sys.path.insert(0, root)
69 if not os.path.isdir(root):
70 os.mkdir(root)
71 for name, contents in descr:
72 comps = name.split()
73 fullname = root
74 for c in comps:
75 fullname = os.path.join(fullname, c)
76 if contents is None:
77 os.mkdir(fullname)
78 else:
79 f = open(fullname, "w")
80 f.write(contents)
81 if contents and contents[-1] != '\n':
82 f.write('\n')
83 f.close()
84 self.root = root
85 # package name is the name of the first item
86 self.pkgname = descr[0][0]
88 def test_1(self):
89 hier = [("t1", None), ("t1 __init__"+os.extsep+"py", "")]
90 self.mkhier(hier)
91 import t1
93 def test_2(self):
94 hier = [
95 ("t2", None),
96 ("t2 __init__"+os.extsep+"py", "'doc for t2'"),
97 ("t2 sub", None),
98 ("t2 sub __init__"+os.extsep+"py", ""),
99 ("t2 sub subsub", None),
100 ("t2 sub subsub __init__"+os.extsep+"py", "spam = 1"),
102 self.mkhier(hier)
104 import t2
105 self.assertEqual(t2.__doc__, "doc for t2")
107 import t2.sub
108 import t2.sub.subsub
109 self.assertEqual(t2.__name__, "t2")
110 self.assertEqual(t2.sub.__name__, "t2.sub")
111 self.assertEqual(t2.sub.subsub.__name__, "t2.sub.subsub")
113 # This exec crap is needed because Py3k forbids 'import *' outside
114 # of module-scope and __import__() is insufficient for what we need.
115 s = """
116 import t2
117 from t2 import *
118 self.assertEqual(dir(), ['self', 'sub', 't2'])
120 self.run_code(s)
122 from t2 import sub
123 from t2.sub import subsub
124 from t2.sub.subsub import spam
125 self.assertEqual(sub.__name__, "t2.sub")
126 self.assertEqual(subsub.__name__, "t2.sub.subsub")
127 self.assertEqual(sub.subsub.__name__, "t2.sub.subsub")
128 for name in ['spam', 'sub', 'subsub', 't2']:
129 self.assertTrue(locals()["name"], "Failed to import %s" % name)
131 import t2.sub
132 import t2.sub.subsub
133 self.assertEqual(t2.__name__, "t2")
134 self.assertEqual(t2.sub.__name__, "t2.sub")
135 self.assertEqual(t2.sub.subsub.__name__, "t2.sub.subsub")
137 s = """
138 from t2 import *
139 self.assertTrue(dir(), ['self', 'sub'])
141 self.run_code(s)
143 def test_3(self):
144 hier = [
145 ("t3", None),
146 ("t3 __init__"+os.extsep+"py", ""),
147 ("t3 sub", None),
148 ("t3 sub __init__"+os.extsep+"py", ""),
149 ("t3 sub subsub", None),
150 ("t3 sub subsub __init__"+os.extsep+"py", "spam = 1"),
152 self.mkhier(hier)
154 import t3.sub.subsub
155 self.assertEqual(t3.__name__, "t3")
156 self.assertEqual(t3.sub.__name__, "t3.sub")
157 self.assertEqual(t3.sub.subsub.__name__, "t3.sub.subsub")
159 def test_4(self):
160 hier = [
161 ("t4.py", "raise RuntimeError('Shouldnt load t4.py')"),
162 ("t4", None),
163 ("t4 __init__"+os.extsep+"py", ""),
164 ("t4 sub.py", "raise RuntimeError('Shouldnt load sub.py')"),
165 ("t4 sub", None),
166 ("t4 sub __init__"+os.extsep+"py", ""),
167 ("t4 sub subsub"+os.extsep+"py",
168 "raise RuntimeError('Shouldnt load subsub.py')"),
169 ("t4 sub subsub", None),
170 ("t4 sub subsub __init__"+os.extsep+"py", "spam = 1"),
172 self.mkhier(hier)
174 s = """
175 from t4.sub.subsub import *
176 self.assertEqual(spam, 1)
178 self.run_code(s)
180 def test_5(self):
181 hier = [
182 ("t5", None),
183 ("t5 __init__"+os.extsep+"py", "import t5.foo"),
184 ("t5 string"+os.extsep+"py", "spam = 1"),
185 ("t5 foo"+os.extsep+"py",
186 "from . import string; assert string.spam == 1"),
188 self.mkhier(hier)
190 import t5
191 s = """
192 from t5 import *
193 self.assertEqual(dir(), ['foo', 'self', 'string', 't5'])
195 self.run_code(s)
197 import t5
198 self.assertEqual(fixdir(dir(t5)),
199 ['__doc__', '__file__', '__name__',
200 '__package__', '__path__', 'foo', 'string', 't5'])
201 self.assertEqual(fixdir(dir(t5.foo)),
202 ['__doc__', '__file__', '__name__', '__package__',
203 'string'])
204 self.assertEqual(fixdir(dir(t5.string)),
205 ['__doc__', '__file__', '__name__','__package__',
206 'spam'])
208 def test_6(self):
209 hier = [
210 ("t6", None),
211 ("t6 __init__"+os.extsep+"py",
212 "__all__ = ['spam', 'ham', 'eggs']"),
213 ("t6 spam"+os.extsep+"py", ""),
214 ("t6 ham"+os.extsep+"py", ""),
215 ("t6 eggs"+os.extsep+"py", ""),
217 self.mkhier(hier)
219 import t6
220 self.assertEqual(fixdir(dir(t6)),
221 ['__all__', '__doc__', '__file__',
222 '__name__', '__package__', '__path__'])
223 s = """
224 import t6
225 from t6 import *
226 self.assertEqual(fixdir(dir(t6)),
227 ['__all__', '__doc__', '__file__',
228 '__name__', '__package__', '__path__',
229 'eggs', 'ham', 'spam'])
230 self.assertEqual(dir(), ['eggs', 'ham', 'self', 'spam', 't6'])
232 self.run_code(s)
234 def test_7(self):
235 hier = [
236 ("t7", None),
237 ("t7"+os.extsep+"py", ""),
238 ("t7 __init__"+os.extsep+"py", ""),
239 ("t7 sub"+os.extsep+"py",
240 "raise RuntimeError('Shouldnt load sub.py')"),
241 ("t7 sub", None),
242 ("t7 sub __init__"+os.extsep+"py", ""),
243 ("t7 sub "+os.extsep+"py",
244 "raise RuntimeError('Shouldnt load subsub.py')"),
245 ("t7 sub subsub", None),
246 ("t7 sub subsub __init__"+os.extsep+"py",
247 "spam = 1"),
249 self.mkhier(hier)
252 t7, sub, subsub = None, None, None
253 import t7 as tas
254 self.assertEqual(fixdir(dir(tas)),
255 ['__doc__', '__file__', '__name__',
256 '__package__', '__path__'])
257 self.assertFalse(t7)
258 from t7 import sub as subpar
259 self.assertEqual(fixdir(dir(subpar)),
260 ['__doc__', '__file__', '__name__',
261 '__package__', '__path__'])
262 self.assertFalse(t7)
263 self.assertFalse(sub)
264 from t7.sub import subsub as subsubsub
265 self.assertEqual(fixdir(dir(subsubsub)),
266 ['__doc__', '__file__', '__name__',
267 '__package__', '__path__', 'spam'])
268 self.assertFalse(t7)
269 self.assertFalse(sub)
270 self.assertFalse(subsub)
271 from t7.sub.subsub import spam as ham
272 self.assertEqual(ham, 1)
273 self.assertFalse(t7)
274 self.assertFalse(sub)
275 self.assertFalse(subsub)
278 def test_main():
279 test_support.run_unittest(__name__)
282 if __name__ == "__main__":
283 test_main()