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() 287