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