1import __future__ 2import os 3import unittest 4import distutils.dir_util 5import tempfile 6 7from test import test_support 8 9try: set 10except NameError: from sets import Set as set 11 12import 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 18TEST_DIR = tempfile.mkdtemp() 19TEST_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 36maybe_test = [ 37 "a.module", 38 ["a", "a.module", "sys", 39 "b"], 40 ["c"], ["b.something"], 41 """\ 42a/__init__.py 43a/module.py 44 from b import something 45 from c import something 46b/__init__.py 47 from sys import * 48"""] 49 50maybe_test_new = [ 51 "a.module", 52 ["a", "a.module", "sys", 53 "b", "__future__"], 54 ["c"], ["b.something"], 55 """\ 56a/__init__.py 57a/module.py 58 from b import something 59 from c import something 60b/__init__.py 61 from __future__ import absolute_import 62 from sys import * 63"""] 64 65package_test = [ 66 "a.module", 67 ["a", "a.b", "a.c", "a.module", "mymodule", "sys"], 68 ["blahblah"], [], 69 """\ 70mymodule.py 71a/__init__.py 72 import blahblah 73 from a import b 74 import c 75a/module.py 76 import sys 77 from a import b as x 78 from a.c import sillyname 79a/b.py 80a/c.py 81 from a.module import x 82 import mymodule as sillyname 83 from sys import version_info 84"""] 85 86absolute_import_test = [ 87 "a.module", 88 ["a", "a.module", 89 "b", "b.x", "b.y", "b.z", 90 "__future__", "sys", "exceptions"], 91 ["blahblah"], [], 92 """\ 93mymodule.py 94a/__init__.py 95a/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.* 103a/exceptions.py 104a/sys.py 105 import mymodule 106a/b/__init__.py 107a/b/x.py 108a/b/y.py 109a/b/z.py 110b/__init__.py 111 import z 112b/unused.py 113b/x.py 114b/y.py 115b/z.py 116"""] 117 118relative_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 """\ 129mymodule.py 130a/__init__.py 131 from .b import y, z # a.b.y, a.b.z 132a/module.py 133 from __future__ import absolute_import # __future__ 134 import exceptions # exceptions 135a/exceptions.py 136a/sys.py 137a/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 141a/b/x.py 142a/b/y.py 143a/b/z.py 144a/b/g.py 145a/b/c/__init__.py 146 from ..c import e # a.b.c.e 147a/b/c/moduleC.py 148 from ..c import d # a.b.c.d 149a/b/c/d.py 150a/b/c/e.py 151a/b/c/x.py 152"""] 153 154relative_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 """\ 167mymodule.py 168a/__init__.py 169 from . import sys # a.sys 170a/another.py 171a/module.py 172 from .b import y, z # a.b.y, a.b.z 173a/exceptions.py 174a/sys.py 175a/b/__init__.py 176 from .c import moduleC # a.b.c.moduleC 177 from .c import d # a.b.c.d 178a/b/x.py 179a/b/y.py 180a/b/z.py 181a/b/c/__init__.py 182 from . import e # a.b.c.e 183a/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 188a/b/c/d.py 189a/b/c/e.py 190a/b/c/f.py 191"""] 192 193relative_import_test_3 = [ 194 "a.module", 195 ["a", "a.module"], 196 ["a.bar"], 197 [], 198 """\ 199a/__init__.py 200 def foo(): pass 201a/module.py 202 from . import foo 203 from . import bar 204"""] 205 206def 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 212def 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 226class 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_extended_opargs(self): 282 extended_opargs_test = [ 283 "a", 284 ["a", "b"], 285 [], [], 286 """\ 287a.py 288 %r 289 import b 290b.py 291""" % range(2**16)] # 2**16 constants 292 self._do_test(extended_opargs_test) 293 294def test_main(): 295 distutils.log.set_threshold(distutils.log.WARN) 296 test_support.run_unittest(ModuleFinderTest) 297 298if __name__ == "__main__": 299 unittest.main() 300