PageRenderTime 34ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/Lib/test/test_modulefinder.py

https://gitlab.com/unofficial-mirrors/cpython
Python | 337 lines | 311 code | 5 blank | 21 comment | 0 complexity | 69cd6f1b098b94877328d6ca0e1b7648 MD5 | raw file
  1. import os
  2. import errno
  3. import importlib.machinery
  4. import py_compile
  5. import shutil
  6. import unittest
  7. import tempfile
  8. from test import support
  9. import modulefinder
  10. TEST_DIR = tempfile.mkdtemp()
  11. TEST_PATH = [TEST_DIR, os.path.dirname(tempfile.__file__)]
  12. # Each test description is a list of 5 items:
  13. #
  14. # 1. a module name that will be imported by modulefinder
  15. # 2. a list of module names that modulefinder is required to find
  16. # 3. a list of module names that modulefinder should complain
  17. # about because they are not found
  18. # 4. a list of module names that modulefinder should complain
  19. # about because they MAY be not found
  20. # 5. a string specifying packages to create; the format is obvious imo.
  21. #
  22. # Each package will be created in TEST_DIR, and TEST_DIR will be
  23. # removed after the tests again.
  24. # Modulefinder searches in a path that contains TEST_DIR, plus
  25. # the standard Lib directory.
  26. maybe_test = [
  27. "a.module",
  28. ["a", "a.module", "sys",
  29. "b"],
  30. ["c"], ["b.something"],
  31. """\
  32. a/__init__.py
  33. a/module.py
  34. from b import something
  35. from c import something
  36. b/__init__.py
  37. from sys import *
  38. """]
  39. maybe_test_new = [
  40. "a.module",
  41. ["a", "a.module", "sys",
  42. "b", "__future__"],
  43. ["c"], ["b.something"],
  44. """\
  45. a/__init__.py
  46. a/module.py
  47. from b import something
  48. from c import something
  49. b/__init__.py
  50. from __future__ import absolute_import
  51. from sys import *
  52. """]
  53. package_test = [
  54. "a.module",
  55. ["a", "a.b", "a.c", "a.module", "mymodule", "sys"],
  56. ["blahblah", "c"], [],
  57. """\
  58. mymodule.py
  59. a/__init__.py
  60. import blahblah
  61. from a import b
  62. import c
  63. a/module.py
  64. import sys
  65. from a import b as x
  66. from a.c import sillyname
  67. a/b.py
  68. a/c.py
  69. from a.module import x
  70. import mymodule as sillyname
  71. from sys import version_info
  72. """]
  73. absolute_import_test = [
  74. "a.module",
  75. ["a", "a.module",
  76. "b", "b.x", "b.y", "b.z",
  77. "__future__", "sys", "gc"],
  78. ["blahblah", "z"], [],
  79. """\
  80. mymodule.py
  81. a/__init__.py
  82. a/module.py
  83. from __future__ import absolute_import
  84. import sys # sys
  85. import blahblah # fails
  86. import gc # gc
  87. import b.x # b.x
  88. from b import y # b.y
  89. from b.z import * # b.z.*
  90. a/gc.py
  91. a/sys.py
  92. import mymodule
  93. a/b/__init__.py
  94. a/b/x.py
  95. a/b/y.py
  96. a/b/z.py
  97. b/__init__.py
  98. import z
  99. b/unused.py
  100. b/x.py
  101. b/y.py
  102. b/z.py
  103. """]
  104. relative_import_test = [
  105. "a.module",
  106. ["__future__",
  107. "a", "a.module",
  108. "a.b", "a.b.y", "a.b.z",
  109. "a.b.c", "a.b.c.moduleC",
  110. "a.b.c.d", "a.b.c.e",
  111. "a.b.x",
  112. "gc"],
  113. [], [],
  114. """\
  115. mymodule.py
  116. a/__init__.py
  117. from .b import y, z # a.b.y, a.b.z
  118. a/module.py
  119. from __future__ import absolute_import # __future__
  120. import gc # gc
  121. a/gc.py
  122. a/sys.py
  123. a/b/__init__.py
  124. from ..b import x # a.b.x
  125. #from a.b.c import moduleC
  126. from .c import moduleC # a.b.moduleC
  127. a/b/x.py
  128. a/b/y.py
  129. a/b/z.py
  130. a/b/g.py
  131. a/b/c/__init__.py
  132. from ..c import e # a.b.c.e
  133. a/b/c/moduleC.py
  134. from ..c import d # a.b.c.d
  135. a/b/c/d.py
  136. a/b/c/e.py
  137. a/b/c/x.py
  138. """]
  139. relative_import_test_2 = [
  140. "a.module",
  141. ["a", "a.module",
  142. "a.sys",
  143. "a.b", "a.b.y", "a.b.z",
  144. "a.b.c", "a.b.c.d",
  145. "a.b.c.e",
  146. "a.b.c.moduleC",
  147. "a.b.c.f",
  148. "a.b.x",
  149. "a.another"],
  150. [], [],
  151. """\
  152. mymodule.py
  153. a/__init__.py
  154. from . import sys # a.sys
  155. a/another.py
  156. a/module.py
  157. from .b import y, z # a.b.y, a.b.z
  158. a/gc.py
  159. a/sys.py
  160. a/b/__init__.py
  161. from .c import moduleC # a.b.c.moduleC
  162. from .c import d # a.b.c.d
  163. a/b/x.py
  164. a/b/y.py
  165. a/b/z.py
  166. a/b/c/__init__.py
  167. from . import e # a.b.c.e
  168. a/b/c/moduleC.py
  169. #
  170. from . import f # a.b.c.f
  171. from .. import x # a.b.x
  172. from ... import another # a.another
  173. a/b/c/d.py
  174. a/b/c/e.py
  175. a/b/c/f.py
  176. """]
  177. relative_import_test_3 = [
  178. "a.module",
  179. ["a", "a.module"],
  180. ["a.bar"],
  181. [],
  182. """\
  183. a/__init__.py
  184. def foo(): pass
  185. a/module.py
  186. from . import foo
  187. from . import bar
  188. """]
  189. relative_import_test_4 = [
  190. "a.module",
  191. ["a", "a.module"],
  192. [],
  193. [],
  194. """\
  195. a/__init__.py
  196. def foo(): pass
  197. a/module.py
  198. from . import *
  199. """]
  200. bytecode_test = [
  201. "a",
  202. ["a"],
  203. [],
  204. [],
  205. ""
  206. ]
  207. def open_file(path):
  208. dirname = os.path.dirname(path)
  209. try:
  210. os.makedirs(dirname)
  211. except OSError as e:
  212. if e.errno != errno.EEXIST:
  213. raise
  214. return open(path, "w")
  215. def create_package(source):
  216. ofi = None
  217. try:
  218. for line in source.splitlines():
  219. if line.startswith(" ") or line.startswith("\t"):
  220. ofi.write(line.strip() + "\n")
  221. else:
  222. if ofi:
  223. ofi.close()
  224. ofi = open_file(os.path.join(TEST_DIR, line.strip()))
  225. finally:
  226. if ofi:
  227. ofi.close()
  228. class ModuleFinderTest(unittest.TestCase):
  229. def _do_test(self, info, report=False, debug=0, replace_paths=[]):
  230. import_this, modules, missing, maybe_missing, source = info
  231. create_package(source)
  232. try:
  233. mf = modulefinder.ModuleFinder(path=TEST_PATH, debug=debug,
  234. replace_paths=replace_paths)
  235. mf.import_hook(import_this)
  236. if report:
  237. mf.report()
  238. ## # This wouldn't work in general when executed several times:
  239. ## opath = sys.path[:]
  240. ## sys.path = TEST_PATH
  241. ## try:
  242. ## __import__(import_this)
  243. ## except:
  244. ## import traceback; traceback.print_exc()
  245. ## sys.path = opath
  246. ## return
  247. modules = sorted(set(modules))
  248. found = sorted(mf.modules)
  249. # check if we found what we expected, not more, not less
  250. self.assertEqual(found, modules)
  251. # check for missing and maybe missing modules
  252. bad, maybe = mf.any_missing_maybe()
  253. self.assertEqual(bad, missing)
  254. self.assertEqual(maybe, maybe_missing)
  255. finally:
  256. shutil.rmtree(TEST_DIR)
  257. def test_package(self):
  258. self._do_test(package_test)
  259. def test_maybe(self):
  260. self._do_test(maybe_test)
  261. def test_maybe_new(self):
  262. self._do_test(maybe_test_new)
  263. def test_absolute_imports(self):
  264. self._do_test(absolute_import_test)
  265. def test_relative_imports(self):
  266. self._do_test(relative_import_test)
  267. def test_relative_imports_2(self):
  268. self._do_test(relative_import_test_2)
  269. def test_relative_imports_3(self):
  270. self._do_test(relative_import_test_3)
  271. def test_relative_imports_4(self):
  272. self._do_test(relative_import_test_4)
  273. def test_bytecode(self):
  274. base_path = os.path.join(TEST_DIR, 'a')
  275. source_path = base_path + importlib.machinery.SOURCE_SUFFIXES[0]
  276. bytecode_path = base_path + importlib.machinery.BYTECODE_SUFFIXES[0]
  277. with open_file(source_path) as file:
  278. file.write('testing_modulefinder = True\n')
  279. py_compile.compile(source_path, cfile=bytecode_path)
  280. os.remove(source_path)
  281. self._do_test(bytecode_test)
  282. def test_replace_paths(self):
  283. old_path = os.path.join(TEST_DIR, 'a', 'module.py')
  284. new_path = os.path.join(TEST_DIR, 'a', 'spam.py')
  285. with support.captured_stdout() as output:
  286. self._do_test(maybe_test, debug=2,
  287. replace_paths=[(old_path, new_path)])
  288. output = output.getvalue()
  289. expected = "co_filename %r changed to %r" % (old_path, new_path)
  290. self.assertIn(expected, output)
  291. def test_extended_opargs(self):
  292. extended_opargs_test = [
  293. "a",
  294. ["a", "b"],
  295. [], [],
  296. """\
  297. a.py
  298. %r
  299. import b
  300. b.py
  301. """ % list(range(2**16))] # 2**16 constants
  302. self._do_test(extended_opargs_test)
  303. if __name__ == "__main__":
  304. unittest.main()