test_imp.py revision 7fdd0fe48f3f342273c1d396df142b1d4b9a1a5c
1import imp 2import os 3import os.path 4import shutil 5import sys 6import unittest 7from test import support 8import importlib 9 10class LockTests(unittest.TestCase): 11 12 """Very basic test of import lock functions.""" 13 14 def verify_lock_state(self, expected): 15 self.assertEqual(imp.lock_held(), expected, 16 "expected imp.lock_held() to be %r" % expected) 17 def testLock(self): 18 LOOPS = 50 19 20 # The import lock may already be held, e.g. if the test suite is run 21 # via "import test.autotest". 22 lock_held_at_start = imp.lock_held() 23 self.verify_lock_state(lock_held_at_start) 24 25 for i in range(LOOPS): 26 imp.acquire_lock() 27 self.verify_lock_state(True) 28 29 for i in range(LOOPS): 30 imp.release_lock() 31 32 # The original state should be restored now. 33 self.verify_lock_state(lock_held_at_start) 34 35 if not lock_held_at_start: 36 try: 37 imp.release_lock() 38 except RuntimeError: 39 pass 40 else: 41 self.fail("release_lock() without lock should raise " 42 "RuntimeError") 43 44class ImportTests(unittest.TestCase): 45 def setUp(self): 46 mod = importlib.import_module('test.encoded_modules') 47 self.test_strings = mod.test_strings 48 self.test_path = mod.__path__ 49 50 def test_import_encoded_module(self): 51 for modname, encoding, teststr in self.test_strings: 52 mod = importlib.import_module('test.encoded_modules.' 53 'module_' + modname) 54 self.assertEqual(teststr, mod.test) 55 56 def test_find_module_encoding(self): 57 for mod, encoding, _ in self.test_strings: 58 with imp.find_module('module_' + mod, self.test_path)[0] as fd: 59 self.assertEqual(fd.encoding, encoding) 60 61 def test_issue1267(self): 62 for mod, encoding, _ in self.test_strings: 63 fp, filename, info = imp.find_module('module_' + mod, 64 self.test_path) 65 with fp: 66 self.assertNotEqual(fp, None) 67 self.assertEqual(fp.encoding, encoding) 68 self.assertEqual(fp.tell(), 0) 69 self.assertEqual(fp.readline(), '# test %s encoding\n' 70 % encoding) 71 72 fp, filename, info = imp.find_module("tokenize") 73 with fp: 74 self.assertNotEqual(fp, None) 75 self.assertEqual(fp.encoding, "utf-8") 76 self.assertEqual(fp.tell(), 0) 77 self.assertEqual(fp.readline(), 78 '"""Tokenization help for Python programs.\n') 79 80 def test_issue3594(self): 81 temp_mod_name = 'test_imp_helper' 82 sys.path.insert(0, '.') 83 try: 84 with open(temp_mod_name + '.py', 'w') as file: 85 file.write("# coding: cp1252\nu = 'test.test_imp'\n") 86 file, filename, info = imp.find_module(temp_mod_name) 87 file.close() 88 self.assertEqual(file.encoding, 'cp1252') 89 finally: 90 del sys.path[0] 91 support.unlink(temp_mod_name + '.py') 92 support.unlink(temp_mod_name + '.pyc') 93 support.unlink(temp_mod_name + '.pyo') 94 95 def test_issue5604(self): 96 # Test cannot cover imp.load_compiled function. 97 # Martin von Loewis note what shared library cannot have non-ascii 98 # character because init_xxx function cannot be compiled 99 # and issue never happens for dynamic modules. 100 # But sources modified to follow generic way for processing pathes. 101 102 # the return encoding could be uppercase or None 103 fs_encoding = sys.getfilesystemencoding() 104 105 # covers utf-8 and Windows ANSI code pages 106 # one non-space symbol from every page 107 # (http://en.wikipedia.org/wiki/Code_page) 108 known_locales = { 109 'utf-8' : b'\xc3\xa4', 110 'cp1250' : b'\x8C', 111 'cp1251' : b'\xc0', 112 'cp1252' : b'\xc0', 113 'cp1253' : b'\xc1', 114 'cp1254' : b'\xc0', 115 'cp1255' : b'\xe0', 116 'cp1256' : b'\xe0', 117 'cp1257' : b'\xc0', 118 'cp1258' : b'\xc0', 119 } 120 121 if sys.platform == 'darwin': 122 self.assertEqual(fs_encoding, 'utf-8') 123 # Mac OS X uses the Normal Form D decomposition 124 # http://developer.apple.com/mac/library/qa/qa2001/qa1173.html 125 special_char = b'a\xcc\x88' 126 else: 127 special_char = known_locales.get(fs_encoding) 128 129 if not special_char: 130 self.skipTest("can't run this test with %s as filesystem encoding" 131 % fs_encoding) 132 decoded_char = special_char.decode(fs_encoding) 133 temp_mod_name = 'test_imp_helper_' + decoded_char 134 test_package_name = 'test_imp_helper_package_' + decoded_char 135 init_file_name = os.path.join(test_package_name, '__init__.py') 136 try: 137 # if the curdir is not in sys.path the test fails when run with 138 # ./python ./Lib/test/regrtest.py test_imp 139 sys.path.insert(0, os.curdir) 140 with open(temp_mod_name + '.py', 'w') as file: 141 file.write('a = 1\n') 142 file, filename, info = imp.find_module(temp_mod_name) 143 with file: 144 self.assertIsNotNone(file) 145 self.assertTrue(filename[:-3].endswith(temp_mod_name)) 146 self.assertEqual(info[0], '.py') 147 self.assertEqual(info[1], 'U') 148 self.assertEqual(info[2], imp.PY_SOURCE) 149 150 mod = imp.load_module(temp_mod_name, file, filename, info) 151 self.assertEqual(mod.a, 1) 152 153 mod = imp.load_source(temp_mod_name, temp_mod_name + '.py') 154 self.assertEqual(mod.a, 1) 155 156 mod = imp.load_compiled( 157 temp_mod_name, imp.cache_from_source(temp_mod_name + '.py')) 158 self.assertEqual(mod.a, 1) 159 160 if not os.path.exists(test_package_name): 161 os.mkdir(test_package_name) 162 with open(init_file_name, 'w') as file: 163 file.write('b = 2\n') 164 package = imp.load_package(test_package_name, test_package_name) 165 self.assertEqual(package.b, 2) 166 finally: 167 del sys.path[0] 168 for ext in ('.py', '.pyc', '.pyo'): 169 support.unlink(temp_mod_name + ext) 170 support.unlink(init_file_name + ext) 171 support.rmtree(test_package_name) 172 173 def test_issue9319(self): 174 self.assertRaises(SyntaxError, 175 imp.find_module, "test/badsyntax_pep3120") 176 177 178class ReloadTests(unittest.TestCase): 179 180 """Very basic tests to make sure that imp.reload() operates just like 181 reload().""" 182 183 def test_source(self): 184 # XXX (ncoghlan): It would be nice to use test.support.CleanImport 185 # here, but that breaks because the os module registers some 186 # handlers in copy_reg on import. Since CleanImport doesn't 187 # revert that registration, the module is left in a broken 188 # state after reversion. Reinitialising the module contents 189 # and just reverting os.environ to its previous state is an OK 190 # workaround 191 with support.EnvironmentVarGuard(): 192 import os 193 imp.reload(os) 194 195 def test_extension(self): 196 with support.CleanImport('time'): 197 import time 198 imp.reload(time) 199 200 def test_builtin(self): 201 with support.CleanImport('marshal'): 202 import marshal 203 imp.reload(marshal) 204 205 206class PEP3147Tests(unittest.TestCase): 207 """Tests of PEP 3147.""" 208 209 tag = imp.get_tag() 210 211 def test_cache_from_source(self): 212 # Given the path to a .py file, return the path to its PEP 3147 213 # defined .pyc file (i.e. under __pycache__). 214 self.assertEqual( 215 imp.cache_from_source('/foo/bar/baz/qux.py', True), 216 '/foo/bar/baz/__pycache__/qux.{}.pyc'.format(self.tag)) 217 218 def test_cache_from_source_optimized(self): 219 # Given the path to a .py file, return the path to its PEP 3147 220 # defined .pyo file (i.e. under __pycache__). 221 self.assertEqual( 222 imp.cache_from_source('/foo/bar/baz/qux.py', False), 223 '/foo/bar/baz/__pycache__/qux.{}.pyo'.format(self.tag)) 224 225 def test_cache_from_source_cwd(self): 226 self.assertEqual(imp.cache_from_source('foo.py', True), 227 os.sep.join(('__pycache__', 228 'foo.{}.pyc'.format(self.tag)))) 229 230 def test_cache_from_source_override(self): 231 # When debug_override is not None, it can be any true-ish or false-ish 232 # value. 233 self.assertEqual( 234 imp.cache_from_source('/foo/bar/baz.py', []), 235 '/foo/bar/__pycache__/baz.{}.pyo'.format(self.tag)) 236 self.assertEqual( 237 imp.cache_from_source('/foo/bar/baz.py', [17]), 238 '/foo/bar/__pycache__/baz.{}.pyc'.format(self.tag)) 239 # However if the bool-ishness can't be determined, the exception 240 # propagates. 241 class Bearish: 242 def __bool__(self): raise RuntimeError 243 self.assertRaises( 244 RuntimeError, 245 imp.cache_from_source, '/foo/bar/baz.py', Bearish()) 246 247 @unittest.skipIf(os.altsep is None, 248 'test meaningful only where os.altsep is defined') 249 def test_altsep_cache_from_source(self): 250 # Windows path and PEP 3147. 251 self.assertEqual( 252 imp.cache_from_source('\\foo\\bar\\baz\\qux.py', True), 253 '\\foo\\bar\\baz\\__pycache__\\qux.{}.pyc'.format(self.tag)) 254 255 @unittest.skipIf(os.altsep is None, 256 'test meaningful only where os.altsep is defined') 257 def test_altsep_and_sep_cache_from_source(self): 258 # Windows path and PEP 3147 where altsep is right of sep. 259 self.assertEqual( 260 imp.cache_from_source('\\foo\\bar/baz\\qux.py', True), 261 '\\foo\\bar/baz\\__pycache__\\qux.{}.pyc'.format(self.tag)) 262 263 @unittest.skipIf(os.altsep is None, 264 'test meaningful only where os.altsep is defined') 265 def test_sep_altsep_and_sep_cache_from_source(self): 266 # Windows path and PEP 3147 where sep is right of altsep. 267 self.assertEqual( 268 imp.cache_from_source('\\foo\\bar\\baz/qux.py', True), 269 '\\foo\\bar\\baz/__pycache__/qux.{}.pyc'.format(self.tag)) 270 271 def test_source_from_cache(self): 272 # Given the path to a PEP 3147 defined .pyc file, return the path to 273 # its source. This tests the good path. 274 self.assertEqual(imp.source_from_cache( 275 '/foo/bar/baz/__pycache__/qux.{}.pyc'.format(self.tag)), 276 '/foo/bar/baz/qux.py') 277 278 def test_source_from_cache_bad_path(self): 279 # When the path to a pyc file is not in PEP 3147 format, a ValueError 280 # is raised. 281 self.assertRaises( 282 ValueError, imp.source_from_cache, '/foo/bar/bazqux.pyc') 283 284 def test_source_from_cache_no_slash(self): 285 # No slashes at all in path -> ValueError 286 self.assertRaises( 287 ValueError, imp.source_from_cache, 'foo.cpython-32.pyc') 288 289 def test_source_from_cache_too_few_dots(self): 290 # Too few dots in final path component -> ValueError 291 self.assertRaises( 292 ValueError, imp.source_from_cache, '__pycache__/foo.pyc') 293 294 def test_source_from_cache_too_many_dots(self): 295 # Too many dots in final path component -> ValueError 296 self.assertRaises( 297 ValueError, imp.source_from_cache, 298 '__pycache__/foo.cpython-32.foo.pyc') 299 300 def test_source_from_cache_no__pycache__(self): 301 # Another problem with the path -> ValueError 302 self.assertRaises( 303 ValueError, imp.source_from_cache, 304 '/foo/bar/foo.cpython-32.foo.pyc') 305 306 def test_package___file__(self): 307 # Test that a package's __file__ points to the right source directory. 308 os.mkdir('pep3147') 309 sys.path.insert(0, os.curdir) 310 def cleanup(): 311 if sys.path[0] == os.curdir: 312 del sys.path[0] 313 shutil.rmtree('pep3147') 314 self.addCleanup(cleanup) 315 # Touch the __init__.py file. 316 with open('pep3147/__init__.py', 'w'): 317 pass 318 m = __import__('pep3147') 319 # Ensure we load the pyc file. 320 support.forget('pep3147') 321 m = __import__('pep3147') 322 self.assertEqual(m.__file__, 323 os.sep.join(('.', 'pep3147', '__init__.py'))) 324 325 326class NullImporterTests(unittest.TestCase): 327 @unittest.skipIf(support.TESTFN_UNENCODABLE is None, 328 "Need an undecodeable filename") 329 def test_unencodeable(self): 330 name = support.TESTFN_UNENCODABLE 331 os.mkdir(name) 332 try: 333 self.assertRaises(ImportError, imp.NullImporter, name) 334 finally: 335 os.rmdir(name) 336 337 338def test_main(): 339 tests = [ 340 ImportTests, 341 PEP3147Tests, 342 ReloadTests, 343 NullImporterTests, 344 ] 345 try: 346 import _thread 347 except ImportError: 348 pass 349 else: 350 tests.append(LockTests) 351 support.run_unittest(*tests) 352 353if __name__ == "__main__": 354 test_main() 355