/Lib/test/test_pkg.py

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