blob: ed30d6fe3a45e554570a84622b4019c957b64156 [file] [log] [blame]
Christian Heimes05e8be12008-02-23 18:30:17 +00001import os
Éric Araujo1e3a68d2011-07-28 23:35:29 +02002import errno
Brett Cannon298bb962014-02-28 10:44:45 -05003import importlib.machinery
4import py_compile
Éric Araujo1e3a68d2011-07-28 23:35:29 +02005import shutil
Guido van Rossumfc2a0a82006-10-27 23:06:01 +00006import unittest
Guido van Rossumfc2a0a82006-10-27 23:06:01 +00007import tempfile
8
Benjamin Petersonee8712c2008-05-20 21:35:26 +00009from test import support
Guido van Rossumfc2a0a82006-10-27 23:06:01 +000010
Guido van Rossumfc2a0a82006-10-27 23:06:01 +000011import modulefinder
12
Guido van Rossumfc2a0a82006-10-27 23:06:01 +000013TEST_DIR = tempfile.mkdtemp()
Éric Araujo1e3a68d2011-07-28 23:35:29 +020014TEST_PATH = [TEST_DIR, os.path.dirname(tempfile.__file__)]
Guido van Rossumfc2a0a82006-10-27 23:06:01 +000015
16# Each test description is a list of 5 items:
17#
18# 1. a module name that will be imported by modulefinder
19# 2. a list of module names that modulefinder is required to find
20# 3. a list of module names that modulefinder should complain
21# about because they are not found
22# 4. a list of module names that modulefinder should complain
23# about because they MAY be not found
24# 5. a string specifying packages to create; the format is obvious imo.
25#
26# Each package will be created in TEST_DIR, and TEST_DIR will be
27# removed after the tests again.
28# Modulefinder searches in a path that contains TEST_DIR, plus
29# the standard Lib directory.
30
31maybe_test = [
32 "a.module",
33 ["a", "a.module", "sys",
34 "b"],
35 ["c"], ["b.something"],
36 """\
37a/__init__.py
38a/module.py
39 from b import something
40 from c import something
41b/__init__.py
42 from sys import *
43"""]
44
45maybe_test_new = [
46 "a.module",
47 ["a", "a.module", "sys",
Thomas Wouters89f507f2006-12-13 04:49:30 +000048 "b", "__future__"],
Guido van Rossumfc2a0a82006-10-27 23:06:01 +000049 ["c"], ["b.something"],
50 """\
51a/__init__.py
52a/module.py
53 from b import something
54 from c import something
55b/__init__.py
Thomas Wouters89f507f2006-12-13 04:49:30 +000056 from __future__ import absolute_import
Guido van Rossumfc2a0a82006-10-27 23:06:01 +000057 from sys import *
58"""]
59
60package_test = [
61 "a.module",
62 ["a", "a.b", "a.c", "a.module", "mymodule", "sys"],
63 ["blahblah", "c"], [],
64 """\
65mymodule.py
66a/__init__.py
67 import blahblah
68 from a import b
69 import c
70a/module.py
71 import sys
72 from a import b as x
73 from a.c import sillyname
74a/b.py
75a/c.py
76 from a.module import x
77 import mymodule as sillyname
78 from sys import version_info
79"""]
80
81absolute_import_test = [
82 "a.module",
83 ["a", "a.module",
84 "b", "b.x", "b.y", "b.z",
Neal Norwitz2633c692007-02-26 22:22:47 +000085 "__future__", "sys", "gc"],
Guido van Rossumfc2a0a82006-10-27 23:06:01 +000086 ["blahblah", "z"], [],
87 """\
88mymodule.py
89a/__init__.py
90a/module.py
Thomas Wouters89f507f2006-12-13 04:49:30 +000091 from __future__ import absolute_import
Guido van Rossumfc2a0a82006-10-27 23:06:01 +000092 import sys # sys
93 import blahblah # fails
Neal Norwitz2633c692007-02-26 22:22:47 +000094 import gc # gc
Guido van Rossumfc2a0a82006-10-27 23:06:01 +000095 import b.x # b.x
96 from b import y # b.y
97 from b.z import * # b.z.*
Neal Norwitz2633c692007-02-26 22:22:47 +000098a/gc.py
Guido van Rossumfc2a0a82006-10-27 23:06:01 +000099a/sys.py
100 import mymodule
101a/b/__init__.py
102a/b/x.py
103a/b/y.py
104a/b/z.py
105b/__init__.py
106 import z
107b/unused.py
108b/x.py
109b/y.py
110b/z.py
111"""]
112
113relative_import_test = [
114 "a.module",
Thomas Wouters89f507f2006-12-13 04:49:30 +0000115 ["__future__",
116 "a", "a.module",
Guido van Rossumfc2a0a82006-10-27 23:06:01 +0000117 "a.b", "a.b.y", "a.b.z",
118 "a.b.c", "a.b.c.moduleC",
119 "a.b.c.d", "a.b.c.e",
120 "a.b.x",
Neal Norwitz2633c692007-02-26 22:22:47 +0000121 "gc"],
Guido van Rossumfc2a0a82006-10-27 23:06:01 +0000122 [], [],
123 """\
124mymodule.py
125a/__init__.py
126 from .b import y, z # a.b.y, a.b.z
127a/module.py
Thomas Wouters89f507f2006-12-13 04:49:30 +0000128 from __future__ import absolute_import # __future__
Neal Norwitz2633c692007-02-26 22:22:47 +0000129 import gc # gc
130a/gc.py
Guido van Rossumfc2a0a82006-10-27 23:06:01 +0000131a/sys.py
132a/b/__init__.py
133 from ..b import x # a.b.x
134 #from a.b.c import moduleC
135 from .c import moduleC # a.b.moduleC
136a/b/x.py
137a/b/y.py
138a/b/z.py
139a/b/g.py
140a/b/c/__init__.py
141 from ..c import e # a.b.c.e
142a/b/c/moduleC.py
143 from ..c import d # a.b.c.d
144a/b/c/d.py
145a/b/c/e.py
146a/b/c/x.py
147"""]
148
149relative_import_test_2 = [
150 "a.module",
151 ["a", "a.module",
152 "a.sys",
153 "a.b", "a.b.y", "a.b.z",
154 "a.b.c", "a.b.c.d",
155 "a.b.c.e",
156 "a.b.c.moduleC",
157 "a.b.c.f",
158 "a.b.x",
159 "a.another"],
160 [], [],
161 """\
162mymodule.py
163a/__init__.py
164 from . import sys # a.sys
165a/another.py
166a/module.py
167 from .b import y, z # a.b.y, a.b.z
Neal Norwitz2633c692007-02-26 22:22:47 +0000168a/gc.py
Guido van Rossumfc2a0a82006-10-27 23:06:01 +0000169a/sys.py
170a/b/__init__.py
171 from .c import moduleC # a.b.c.moduleC
172 from .c import d # a.b.c.d
173a/b/x.py
174a/b/y.py
175a/b/z.py
176a/b/c/__init__.py
177 from . import e # a.b.c.e
178a/b/c/moduleC.py
179 #
180 from . import f # a.b.c.f
181 from .. import x # a.b.x
182 from ... import another # a.another
183a/b/c/d.py
184a/b/c/e.py
185a/b/c/f.py
186"""]
187
Benjamin Petersonc0747cf2008-11-03 20:31:38 +0000188relative_import_test_3 = [
189 "a.module",
190 ["a", "a.module"],
191 ["a.bar"],
192 [],
193 """\
194a/__init__.py
195 def foo(): pass
196a/module.py
197 from . import foo
198 from . import bar
199"""]
200
Brett Cannon73b969e2012-12-22 19:34:21 -0500201relative_import_test_4 = [
202 "a.module",
203 ["a", "a.module"],
204 [],
205 [],
206 """\
207a/__init__.py
208 def foo(): pass
209a/module.py
210 from . import *
211"""]
212
Brett Cannon298bb962014-02-28 10:44:45 -0500213bytecode_test = [
214 "a",
215 ["a"],
216 [],
217 [],
218 ""
219]
220
Éric Araujo1e3a68d2011-07-28 23:35:29 +0200221
Guido van Rossumfc2a0a82006-10-27 23:06:01 +0000222def open_file(path):
Guido van Rossumfc2a0a82006-10-27 23:06:01 +0000223 dirname = os.path.dirname(path)
Éric Araujo1e3a68d2011-07-28 23:35:29 +0200224 try:
225 os.makedirs(dirname)
226 except OSError as e:
227 if e.errno != errno.EEXIST:
228 raise
Guido van Rossumfc2a0a82006-10-27 23:06:01 +0000229 return open(path, "w")
230
Éric Araujo1e3a68d2011-07-28 23:35:29 +0200231
Guido van Rossumfc2a0a82006-10-27 23:06:01 +0000232def create_package(source):
233 ofi = None
Antoine Pitrou92f60ed2010-10-14 22:11:44 +0000234 try:
235 for line in source.splitlines():
236 if line.startswith(" ") or line.startswith("\t"):
237 ofi.write(line.strip() + "\n")
238 else:
239 if ofi:
240 ofi.close()
241 ofi = open_file(os.path.join(TEST_DIR, line.strip()))
242 finally:
243 if ofi:
244 ofi.close()
Guido van Rossumfc2a0a82006-10-27 23:06:01 +0000245
Éric Araujo1e3a68d2011-07-28 23:35:29 +0200246
Guido van Rossumfc2a0a82006-10-27 23:06:01 +0000247class ModuleFinderTest(unittest.TestCase):
248 def _do_test(self, info, report=False):
249 import_this, modules, missing, maybe_missing, source = info
250 create_package(source)
251 try:
252 mf = modulefinder.ModuleFinder(path=TEST_PATH)
253 mf.import_hook(import_this)
254 if report:
255 mf.report()
256## # This wouldn't work in general when executed several times:
257## opath = sys.path[:]
258## sys.path = TEST_PATH
259## try:
260## __import__(import_this)
261## except:
262## import traceback; traceback.print_exc()
263## sys.path = opath
264## return
Éric Araujo1e3a68d2011-07-28 23:35:29 +0200265 modules = sorted(set(modules))
266 found = sorted(mf.modules)
Guido van Rossumfc2a0a82006-10-27 23:06:01 +0000267 # check if we found what we expected, not more, not less
Éric Araujo1e3a68d2011-07-28 23:35:29 +0200268 self.assertEqual(found, modules)
Guido van Rossumfc2a0a82006-10-27 23:06:01 +0000269
270 # check for missing and maybe missing modules
271 bad, maybe = mf.any_missing_maybe()
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000272 self.assertEqual(bad, missing)
273 self.assertEqual(maybe, maybe_missing)
Guido van Rossumfc2a0a82006-10-27 23:06:01 +0000274 finally:
Éric Araujo1e3a68d2011-07-28 23:35:29 +0200275 shutil.rmtree(TEST_DIR)
Guido van Rossumfc2a0a82006-10-27 23:06:01 +0000276
277 def test_package(self):
278 self._do_test(package_test)
279
280 def test_maybe(self):
281 self._do_test(maybe_test)
282
Éric Araujo1e3a68d2011-07-28 23:35:29 +0200283 def test_maybe_new(self):
284 self._do_test(maybe_test_new)
Guido van Rossumfc2a0a82006-10-27 23:06:01 +0000285
Éric Araujo1e3a68d2011-07-28 23:35:29 +0200286 def test_absolute_imports(self):
287 self._do_test(absolute_import_test)
Guido van Rossumfc2a0a82006-10-27 23:06:01 +0000288
Éric Araujo1e3a68d2011-07-28 23:35:29 +0200289 def test_relative_imports(self):
290 self._do_test(relative_import_test)
Guido van Rossumfc2a0a82006-10-27 23:06:01 +0000291
Éric Araujo1e3a68d2011-07-28 23:35:29 +0200292 def test_relative_imports_2(self):
293 self._do_test(relative_import_test_2)
Guido van Rossumfc2a0a82006-10-27 23:06:01 +0000294
Éric Araujo1e3a68d2011-07-28 23:35:29 +0200295 def test_relative_imports_3(self):
296 self._do_test(relative_import_test_3)
Guido van Rossumfc2a0a82006-10-27 23:06:01 +0000297
Brett Cannon73b969e2012-12-22 19:34:21 -0500298 def test_relative_imports_4(self):
299 self._do_test(relative_import_test_4)
300
Brett Cannon298bb962014-02-28 10:44:45 -0500301 def test_bytecode(self):
302 base_path = os.path.join(TEST_DIR, 'a')
303 source_path = base_path + importlib.machinery.SOURCE_SUFFIXES[0]
304 bytecode_path = base_path + importlib.machinery.BYTECODE_SUFFIXES[0]
305 with open_file(source_path) as file:
306 file.write('testing_modulefinder = True\n')
307 py_compile.compile(source_path, cfile=bytecode_path)
308 os.remove(source_path)
309 self._do_test(bytecode_test)
310
Benjamin Petersonc0747cf2008-11-03 20:31:38 +0000311
Guido van Rossumfc2a0a82006-10-27 23:06:01 +0000312def test_main():
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000313 support.run_unittest(ModuleFinderTest)
Guido van Rossumfc2a0a82006-10-27 23:06:01 +0000314
315if __name__ == "__main__":
316 unittest.main()