/Lib/test/test_modulefinder.py

http://unladen-swallow.googlecode.com/ · Python · 280 lines · 115 code · 27 blank · 138 comment · 11 complexity · 83e16847c3964ec633d4ec856f4d502b MD5 · raw file

  1. import __future__
  2. import os
  3. import unittest
  4. import distutils.dir_util
  5. import tempfile
  6. from test import test_support
  7. try: set
  8. except NameError: from sets import Set as set
  9. import modulefinder
  10. # Note: To test modulefinder with Python 2.2, sets.py and
  11. # modulefinder.py must be available - they are not in the standard
  12. # library.
  13. TEST_DIR = tempfile.mkdtemp()
  14. TEST_PATH = [TEST_DIR, os.path.dirname(__future__.__file__)]
  15. # Each test description is a list of 5 items:
  16. #
  17. # 1. a module name that will be imported by modulefinder
  18. # 2. a list of module names that modulefinder is required to find
  19. # 3. a list of module names that modulefinder should complain
  20. # about because they are not found
  21. # 4. a list of module names that modulefinder should complain
  22. # about because they MAY be not found
  23. # 5. a string specifying packages to create; the format is obvious imo.
  24. #
  25. # Each package will be created in TEST_DIR, and TEST_DIR will be
  26. # removed after the tests again.
  27. # Modulefinder searches in a path that contains TEST_DIR, plus
  28. # the standard Lib directory.
  29. maybe_test = [
  30. "a.module",
  31. ["a", "a.module", "sys",
  32. "b"],
  33. ["c"], ["b.something"],
  34. """\
  35. a/__init__.py
  36. a/module.py
  37. from b import something
  38. from c import something
  39. b/__init__.py
  40. from sys import *
  41. """]
  42. maybe_test_new = [
  43. "a.module",
  44. ["a", "a.module", "sys",
  45. "b", "__future__"],
  46. ["c"], ["b.something"],
  47. """\
  48. a/__init__.py
  49. a/module.py
  50. from b import something
  51. from c import something
  52. b/__init__.py
  53. from __future__ import absolute_import
  54. from sys import *
  55. """]
  56. package_test = [
  57. "a.module",
  58. ["a", "a.b", "a.c", "a.module", "mymodule", "sys"],
  59. ["blahblah"], [],
  60. """\
  61. mymodule.py
  62. a/__init__.py
  63. import blahblah
  64. from a import b
  65. import c
  66. a/module.py
  67. import sys
  68. from a import b as x
  69. from a.c import sillyname
  70. a/b.py
  71. a/c.py
  72. from a.module import x
  73. import mymodule as sillyname
  74. from sys import version_info
  75. """]
  76. absolute_import_test = [
  77. "a.module",
  78. ["a", "a.module",
  79. "b", "b.x", "b.y", "b.z",
  80. "__future__", "sys", "exceptions"],
  81. ["blahblah"], [],
  82. """\
  83. mymodule.py
  84. a/__init__.py
  85. a/module.py
  86. from __future__ import absolute_import
  87. import sys # sys
  88. import blahblah # fails
  89. import exceptions # exceptions
  90. import b.x # b.x
  91. from b import y # b.y
  92. from b.z import * # b.z.*
  93. a/exceptions.py
  94. a/sys.py
  95. import mymodule
  96. a/b/__init__.py
  97. a/b/x.py
  98. a/b/y.py
  99. a/b/z.py
  100. b/__init__.py
  101. import z
  102. b/unused.py
  103. b/x.py
  104. b/y.py
  105. b/z.py
  106. """]
  107. relative_import_test = [
  108. "a.module",
  109. ["__future__",
  110. "a", "a.module",
  111. "a.b", "a.b.y", "a.b.z",
  112. "a.b.c", "a.b.c.moduleC",
  113. "a.b.c.d", "a.b.c.e",
  114. "a.b.x",
  115. "exceptions"],
  116. [], [],
  117. """\
  118. mymodule.py
  119. a/__init__.py
  120. from .b import y, z # a.b.y, a.b.z
  121. a/module.py
  122. from __future__ import absolute_import # __future__
  123. import exceptions # exceptions
  124. a/exceptions.py
  125. a/sys.py
  126. a/b/__init__.py
  127. from ..b import x # a.b.x
  128. #from a.b.c import moduleC
  129. from .c import moduleC # a.b.moduleC
  130. a/b/x.py
  131. a/b/y.py
  132. a/b/z.py
  133. a/b/g.py
  134. a/b/c/__init__.py
  135. from ..c import e # a.b.c.e
  136. a/b/c/moduleC.py
  137. from ..c import d # a.b.c.d
  138. a/b/c/d.py
  139. a/b/c/e.py
  140. a/b/c/x.py
  141. """]
  142. relative_import_test_2 = [
  143. "a.module",
  144. ["a", "a.module",
  145. "a.sys",
  146. "a.b", "a.b.y", "a.b.z",
  147. "a.b.c", "a.b.c.d",
  148. "a.b.c.e",
  149. "a.b.c.moduleC",
  150. "a.b.c.f",
  151. "a.b.x",
  152. "a.another"],
  153. [], [],
  154. """\
  155. mymodule.py
  156. a/__init__.py
  157. from . import sys # a.sys
  158. a/another.py
  159. a/module.py
  160. from .b import y, z # a.b.y, a.b.z
  161. a/exceptions.py
  162. a/sys.py
  163. a/b/__init__.py
  164. from .c import moduleC # a.b.c.moduleC
  165. from .c import d # a.b.c.d
  166. a/b/x.py
  167. a/b/y.py
  168. a/b/z.py
  169. a/b/c/__init__.py
  170. from . import e # a.b.c.e
  171. a/b/c/moduleC.py
  172. #
  173. from . import f # a.b.c.f
  174. from .. import x # a.b.x
  175. from ... import another # a.another
  176. a/b/c/d.py
  177. a/b/c/e.py
  178. a/b/c/f.py
  179. """]
  180. relative_import_test_3 = [
  181. "a.module",
  182. ["a", "a.module"],
  183. ["a.bar"],
  184. [],
  185. """\
  186. a/__init__.py
  187. def foo(): pass
  188. a/module.py
  189. from . import foo
  190. from . import bar
  191. """]
  192. def open_file(path):
  193. ##print "#", os.path.abspath(path)
  194. dirname = os.path.dirname(path)
  195. distutils.dir_util.mkpath(dirname)
  196. return open(path, "w")
  197. def create_package(source):
  198. ofi = None
  199. for line in source.splitlines():
  200. if line.startswith(" ") or line.startswith("\t"):
  201. ofi.write(line.strip() + "\n")
  202. else:
  203. ofi = open_file(os.path.join(TEST_DIR, line.strip()))
  204. class ModuleFinderTest(unittest.TestCase):
  205. def _do_test(self, info, report=False):
  206. import_this, modules, missing, maybe_missing, source = info
  207. create_package(source)
  208. try:
  209. mf = modulefinder.ModuleFinder(path=TEST_PATH)
  210. mf.import_hook(import_this)
  211. if report:
  212. mf.report()
  213. ## # This wouldn't work in general when executed several times:
  214. ## opath = sys.path[:]
  215. ## sys.path = TEST_PATH
  216. ## try:
  217. ## __import__(import_this)
  218. ## except:
  219. ## import traceback; traceback.print_exc()
  220. ## sys.path = opath
  221. ## return
  222. modules = set(modules)
  223. found = set(mf.modules.keys())
  224. more = list(found - modules)
  225. less = list(modules - found)
  226. # check if we found what we expected, not more, not less
  227. self.failUnlessEqual((more, less), ([], []))
  228. # check for missing and maybe missing modules
  229. bad, maybe = mf.any_missing_maybe()
  230. self.failUnlessEqual(bad, missing)
  231. self.failUnlessEqual(maybe, maybe_missing)
  232. finally:
  233. distutils.dir_util.remove_tree(TEST_DIR)
  234. def test_package(self):
  235. self._do_test(package_test)
  236. def test_maybe(self):
  237. self._do_test(maybe_test)
  238. if getattr(__future__, "absolute_import", None):
  239. def test_maybe_new(self):
  240. self._do_test(maybe_test_new)
  241. def test_absolute_imports(self):
  242. self._do_test(absolute_import_test)
  243. def test_relative_imports(self):
  244. self._do_test(relative_import_test)
  245. def test_relative_imports_2(self):
  246. self._do_test(relative_import_test_2)
  247. def test_relative_imports_3(self):
  248. self._do_test(relative_import_test_3)
  249. def test_main():
  250. distutils.log.set_threshold(distutils.log.WARN)
  251. test_support.run_unittest(ModuleFinderTest)
  252. if __name__ == "__main__":
  253. unittest.main()