1import builtins 2import contextlib 3import errno 4import glob 5import importlib.util 6from importlib._bootstrap_external import _get_sourcefile 7import marshal 8import os 9import py_compile 10import random 11import shutil 12import stat 13import subprocess 14import sys 15import textwrap 16import threading 17import time 18import unittest 19from unittest import mock 20 21import test.support 22from test.support import ( 23 TESTFN, forget, is_jython, 24 make_legacy_pyc, rmtree, swap_attr, swap_item, temp_umask, 25 unlink, unload, cpython_only, TESTFN_UNENCODABLE, 26 temp_dir, DirsOnSysPath) 27from test.support import script_helper 28from test.test_importlib.util import uncache 29from types import ModuleType 30 31 32skip_if_dont_write_bytecode = unittest.skipIf( 33 sys.dont_write_bytecode, 34 "test meaningful only when writing bytecode") 35 36def remove_files(name): 37 for f in (name + ".py", 38 name + ".pyc", 39 name + ".pyw", 40 name + "$py.class"): 41 unlink(f) 42 rmtree('__pycache__') 43 44 45@contextlib.contextmanager 46def _ready_to_import(name=None, source=""): 47 # sets up a temporary directory and removes it 48 # creates the module file 49 # temporarily clears the module from sys.modules (if any) 50 # reverts or removes the module when cleaning up 51 name = name or "spam" 52 with temp_dir() as tempdir: 53 path = script_helper.make_script(tempdir, name, source) 54 old_module = sys.modules.pop(name, None) 55 try: 56 sys.path.insert(0, tempdir) 57 yield name, path 58 sys.path.remove(tempdir) 59 finally: 60 if old_module is not None: 61 sys.modules[name] = old_module 62 elif name in sys.modules: 63 del sys.modules[name] 64 65 66class ImportTests(unittest.TestCase): 67 68 def setUp(self): 69 remove_files(TESTFN) 70 importlib.invalidate_caches() 71 72 def tearDown(self): 73 unload(TESTFN) 74 75 def test_import_raises_ModuleNotFoundError(self): 76 with self.assertRaises(ModuleNotFoundError): 77 import something_that_should_not_exist_anywhere 78 79 def test_from_import_missing_module_raises_ModuleNotFoundError(self): 80 with self.assertRaises(ModuleNotFoundError): 81 from something_that_should_not_exist_anywhere import blah 82 83 def test_from_import_missing_attr_raises_ImportError(self): 84 with self.assertRaises(ImportError): 85 from importlib import something_that_should_not_exist_anywhere 86 87 def test_from_import_missing_attr_has_name_and_path(self): 88 with self.assertRaises(ImportError) as cm: 89 from os import i_dont_exist 90 self.assertEqual(cm.exception.name, 'os') 91 self.assertEqual(cm.exception.path, os.__file__) 92 self.assertRegex(str(cm.exception), r"cannot import name 'i_dont_exist' from 'os' \(.*os.py\)") 93 94 @cpython_only 95 def test_from_import_missing_attr_has_name_and_so_path(self): 96 import _testcapi 97 with self.assertRaises(ImportError) as cm: 98 from _testcapi import i_dont_exist 99 self.assertEqual(cm.exception.name, '_testcapi') 100 self.assertEqual(cm.exception.path, _testcapi.__file__) 101 self.assertRegex(str(cm.exception), r"cannot import name 'i_dont_exist' from '_testcapi' \(.*\.(so|pyd)\)") 102 103 def test_from_import_missing_attr_has_name(self): 104 with self.assertRaises(ImportError) as cm: 105 # _warning has no path as it's a built-in module. 106 from _warning import i_dont_exist 107 self.assertEqual(cm.exception.name, '_warning') 108 self.assertIsNone(cm.exception.path) 109 110 def test_from_import_missing_attr_path_is_canonical(self): 111 with self.assertRaises(ImportError) as cm: 112 from os.path import i_dont_exist 113 self.assertIn(cm.exception.name, {'posixpath', 'ntpath'}) 114 self.assertIsNotNone(cm.exception) 115 116 def test_from_import_star_invalid_type(self): 117 import re 118 with _ready_to_import() as (name, path): 119 with open(path, 'w') as f: 120 f.write("__all__ = [b'invalid_type']") 121 globals = {} 122 with self.assertRaisesRegex( 123 TypeError, f"{re.escape(name)}\\.__all__ must be str" 124 ): 125 exec(f"from {name} import *", globals) 126 self.assertNotIn(b"invalid_type", globals) 127 with _ready_to_import() as (name, path): 128 with open(path, 'w') as f: 129 f.write("globals()[b'invalid_type'] = object()") 130 globals = {} 131 with self.assertRaisesRegex( 132 TypeError, f"{re.escape(name)}\\.__dict__ must be str" 133 ): 134 exec(f"from {name} import *", globals) 135 self.assertNotIn(b"invalid_type", globals) 136 137 def test_case_sensitivity(self): 138 # Brief digression to test that import is case-sensitive: if we got 139 # this far, we know for sure that "random" exists. 140 with self.assertRaises(ImportError): 141 import RAnDoM 142 143 def test_double_const(self): 144 # Another brief digression to test the accuracy of manifest float 145 # constants. 146 from test import double_const # don't blink -- that *was* the test 147 148 def test_import(self): 149 def test_with_extension(ext): 150 # The extension is normally ".py", perhaps ".pyw". 151 source = TESTFN + ext 152 if is_jython: 153 pyc = TESTFN + "$py.class" 154 else: 155 pyc = TESTFN + ".pyc" 156 157 with open(source, "w") as f: 158 print("# This tests Python's ability to import a", 159 ext, "file.", file=f) 160 a = random.randrange(1000) 161 b = random.randrange(1000) 162 print("a =", a, file=f) 163 print("b =", b, file=f) 164 165 if TESTFN in sys.modules: 166 del sys.modules[TESTFN] 167 importlib.invalidate_caches() 168 try: 169 try: 170 mod = __import__(TESTFN) 171 except ImportError as err: 172 self.fail("import from %s failed: %s" % (ext, err)) 173 174 self.assertEqual(mod.a, a, 175 "module loaded (%s) but contents invalid" % mod) 176 self.assertEqual(mod.b, b, 177 "module loaded (%s) but contents invalid" % mod) 178 finally: 179 forget(TESTFN) 180 unlink(source) 181 unlink(pyc) 182 183 sys.path.insert(0, os.curdir) 184 try: 185 test_with_extension(".py") 186 if sys.platform.startswith("win"): 187 for ext in [".PY", ".Py", ".pY", ".pyw", ".PYW", ".pYw"]: 188 test_with_extension(ext) 189 finally: 190 del sys.path[0] 191 192 def test_module_with_large_stack(self, module='longlist'): 193 # Regression test for http://bugs.python.org/issue561858. 194 filename = module + '.py' 195 196 # Create a file with a list of 65000 elements. 197 with open(filename, 'w') as f: 198 f.write('d = [\n') 199 for i in range(65000): 200 f.write('"",\n') 201 f.write(']') 202 203 try: 204 # Compile & remove .py file; we only need .pyc. 205 # Bytecode must be relocated from the PEP 3147 bytecode-only location. 206 py_compile.compile(filename) 207 finally: 208 unlink(filename) 209 210 # Need to be able to load from current dir. 211 sys.path.append('') 212 importlib.invalidate_caches() 213 214 namespace = {} 215 try: 216 make_legacy_pyc(filename) 217 # This used to crash. 218 exec('import ' + module, None, namespace) 219 finally: 220 # Cleanup. 221 del sys.path[-1] 222 unlink(filename + 'c') 223 unlink(filename + 'o') 224 225 # Remove references to the module (unload the module) 226 namespace.clear() 227 try: 228 del sys.modules[module] 229 except KeyError: 230 pass 231 232 def test_failing_import_sticks(self): 233 source = TESTFN + ".py" 234 with open(source, "w") as f: 235 print("a = 1/0", file=f) 236 237 # New in 2.4, we shouldn't be able to import that no matter how often 238 # we try. 239 sys.path.insert(0, os.curdir) 240 importlib.invalidate_caches() 241 if TESTFN in sys.modules: 242 del sys.modules[TESTFN] 243 try: 244 for i in [1, 2, 3]: 245 self.assertRaises(ZeroDivisionError, __import__, TESTFN) 246 self.assertNotIn(TESTFN, sys.modules, 247 "damaged module in sys.modules on %i try" % i) 248 finally: 249 del sys.path[0] 250 remove_files(TESTFN) 251 252 def test_import_name_binding(self): 253 # import x.y.z binds x in the current namespace 254 import test as x 255 import test.support 256 self.assertIs(x, test, x.__name__) 257 self.assertTrue(hasattr(test.support, "__file__")) 258 259 # import x.y.z as w binds z as w 260 import test.support as y 261 self.assertIs(y, test.support, y.__name__) 262 263 def test_issue31286(self): 264 # import in a 'finally' block resulted in SystemError 265 try: 266 x = ... 267 finally: 268 import test.support.script_helper as x 269 270 # import in a 'while' loop resulted in stack overflow 271 i = 0 272 while i < 10: 273 import test.support.script_helper as x 274 i += 1 275 276 # import in a 'for' loop resulted in segmentation fault 277 for i in range(2): 278 import test.support.script_helper as x 279 280 def test_failing_reload(self): 281 # A failing reload should leave the module object in sys.modules. 282 source = TESTFN + os.extsep + "py" 283 with open(source, "w") as f: 284 f.write("a = 1\nb=2\n") 285 286 sys.path.insert(0, os.curdir) 287 try: 288 mod = __import__(TESTFN) 289 self.assertIn(TESTFN, sys.modules) 290 self.assertEqual(mod.a, 1, "module has wrong attribute values") 291 self.assertEqual(mod.b, 2, "module has wrong attribute values") 292 293 # On WinXP, just replacing the .py file wasn't enough to 294 # convince reload() to reparse it. Maybe the timestamp didn't 295 # move enough. We force it to get reparsed by removing the 296 # compiled file too. 297 remove_files(TESTFN) 298 299 # Now damage the module. 300 with open(source, "w") as f: 301 f.write("a = 10\nb=20//0\n") 302 303 self.assertRaises(ZeroDivisionError, importlib.reload, mod) 304 # But we still expect the module to be in sys.modules. 305 mod = sys.modules.get(TESTFN) 306 self.assertIsNotNone(mod, "expected module to be in sys.modules") 307 308 # We should have replaced a w/ 10, but the old b value should 309 # stick. 310 self.assertEqual(mod.a, 10, "module has wrong attribute values") 311 self.assertEqual(mod.b, 2, "module has wrong attribute values") 312 313 finally: 314 del sys.path[0] 315 remove_files(TESTFN) 316 unload(TESTFN) 317 318 @skip_if_dont_write_bytecode 319 def test_file_to_source(self): 320 # check if __file__ points to the source file where available 321 source = TESTFN + ".py" 322 with open(source, "w") as f: 323 f.write("test = None\n") 324 325 sys.path.insert(0, os.curdir) 326 try: 327 mod = __import__(TESTFN) 328 self.assertTrue(mod.__file__.endswith('.py')) 329 os.remove(source) 330 del sys.modules[TESTFN] 331 make_legacy_pyc(source) 332 importlib.invalidate_caches() 333 mod = __import__(TESTFN) 334 base, ext = os.path.splitext(mod.__file__) 335 self.assertEqual(ext, '.pyc') 336 finally: 337 del sys.path[0] 338 remove_files(TESTFN) 339 if TESTFN in sys.modules: 340 del sys.modules[TESTFN] 341 342 def test_import_by_filename(self): 343 path = os.path.abspath(TESTFN) 344 encoding = sys.getfilesystemencoding() 345 try: 346 path.encode(encoding) 347 except UnicodeEncodeError: 348 self.skipTest('path is not encodable to {}'.format(encoding)) 349 with self.assertRaises(ImportError) as c: 350 __import__(path) 351 352 def test_import_in_del_does_not_crash(self): 353 # Issue 4236 354 testfn = script_helper.make_script('', TESTFN, textwrap.dedent("""\ 355 import sys 356 class C: 357 def __del__(self): 358 import importlib 359 sys.argv.insert(0, C()) 360 """)) 361 script_helper.assert_python_ok(testfn) 362 363 @skip_if_dont_write_bytecode 364 def test_timestamp_overflow(self): 365 # A modification timestamp larger than 2**32 should not be a problem 366 # when importing a module (issue #11235). 367 sys.path.insert(0, os.curdir) 368 try: 369 source = TESTFN + ".py" 370 compiled = importlib.util.cache_from_source(source) 371 with open(source, 'w') as f: 372 pass 373 try: 374 os.utime(source, (2 ** 33 - 5, 2 ** 33 - 5)) 375 except OverflowError: 376 self.skipTest("cannot set modification time to large integer") 377 except OSError as e: 378 if e.errno not in (getattr(errno, 'EOVERFLOW', None), 379 getattr(errno, 'EINVAL', None)): 380 raise 381 self.skipTest("cannot set modification time to large integer ({})".format(e)) 382 __import__(TESTFN) 383 # The pyc file was created. 384 os.stat(compiled) 385 finally: 386 del sys.path[0] 387 remove_files(TESTFN) 388 389 def test_bogus_fromlist(self): 390 try: 391 __import__('http', fromlist=['blah']) 392 except ImportError: 393 self.fail("fromlist must allow bogus names") 394 395 @cpython_only 396 def test_delete_builtins_import(self): 397 args = ["-c", "del __builtins__.__import__; import os"] 398 popen = script_helper.spawn_python(*args) 399 stdout, stderr = popen.communicate() 400 self.assertIn(b"ImportError", stdout) 401 402 def test_from_import_message_for_nonexistent_module(self): 403 with self.assertRaisesRegex(ImportError, "^No module named 'bogus'"): 404 from bogus import foo 405 406 def test_from_import_message_for_existing_module(self): 407 with self.assertRaisesRegex(ImportError, "^cannot import name 'bogus'"): 408 from re import bogus 409 410 def test_from_import_AttributeError(self): 411 # Issue #24492: trying to import an attribute that raises an 412 # AttributeError should lead to an ImportError. 413 class AlwaysAttributeError: 414 def __getattr__(self, _): 415 raise AttributeError 416 417 module_name = 'test_from_import_AttributeError' 418 self.addCleanup(unload, module_name) 419 sys.modules[module_name] = AlwaysAttributeError() 420 with self.assertRaises(ImportError) as cm: 421 from test_from_import_AttributeError import does_not_exist 422 423 self.assertEqual(str(cm.exception), 424 "cannot import name 'does_not_exist' from '<unknown module name>' (unknown location)") 425 426 @cpython_only 427 def test_issue31492(self): 428 # There shouldn't be an assertion failure in case of failing to import 429 # from a module with a bad __name__ attribute, or in case of failing 430 # to access an attribute of such a module. 431 with swap_attr(os, '__name__', None): 432 with self.assertRaises(ImportError): 433 from os import does_not_exist 434 435 with self.assertRaises(AttributeError): 436 os.does_not_exist 437 438 def test_concurrency(self): 439 # bpo 38091: this is a hack to slow down the code that calls 440 # has_deadlock(); the logic was itself sometimes deadlocking. 441 def delay_has_deadlock(frame, event, arg): 442 if event == 'call' and frame.f_code.co_name == 'has_deadlock': 443 time.sleep(0.1) 444 445 sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'data')) 446 try: 447 exc = None 448 def run(): 449 sys.settrace(delay_has_deadlock) 450 event.wait() 451 try: 452 import package 453 except BaseException as e: 454 nonlocal exc 455 exc = e 456 sys.settrace(None) 457 458 for i in range(10): 459 event = threading.Event() 460 threads = [threading.Thread(target=run) for x in range(2)] 461 try: 462 with test.support.start_threads(threads, event.set): 463 time.sleep(0) 464 finally: 465 sys.modules.pop('package', None) 466 sys.modules.pop('package.submodule', None) 467 if exc is not None: 468 raise exc 469 finally: 470 del sys.path[0] 471 472 @unittest.skipUnless(sys.platform == "win32", "Windows-specific") 473 def test_dll_dependency_import(self): 474 from _winapi import GetModuleFileName 475 dllname = GetModuleFileName(sys.dllhandle) 476 pydname = importlib.util.find_spec("_sqlite3").origin 477 depname = os.path.join( 478 os.path.dirname(pydname), 479 "sqlite3{}.dll".format("_d" if "_d" in pydname else "")) 480 481 with test.support.temp_dir() as tmp: 482 tmp2 = os.path.join(tmp, "DLLs") 483 os.mkdir(tmp2) 484 485 pyexe = os.path.join(tmp, os.path.basename(sys.executable)) 486 shutil.copy(sys.executable, pyexe) 487 shutil.copy(dllname, tmp) 488 for f in glob.glob(os.path.join(glob.escape(sys.prefix), "vcruntime*.dll")): 489 shutil.copy(f, tmp) 490 491 shutil.copy(pydname, tmp2) 492 493 env = None 494 env = {k.upper(): os.environ[k] for k in os.environ} 495 env["PYTHONPATH"] = tmp2 + ";" + os.path.dirname(os.__file__) 496 497 # Test 1: import with added DLL directory 498 subprocess.check_call([ 499 pyexe, "-Sc", ";".join([ 500 "import os", 501 "p = os.add_dll_directory({!r})".format( 502 os.path.dirname(depname)), 503 "import _sqlite3", 504 "p.close" 505 ])], 506 stderr=subprocess.STDOUT, 507 env=env, 508 cwd=os.path.dirname(pyexe)) 509 510 # Test 2: import with DLL adjacent to PYD 511 shutil.copy(depname, tmp2) 512 subprocess.check_call([pyexe, "-Sc", "import _sqlite3"], 513 stderr=subprocess.STDOUT, 514 env=env, 515 cwd=os.path.dirname(pyexe)) 516 517 518@skip_if_dont_write_bytecode 519class FilePermissionTests(unittest.TestCase): 520 # tests for file mode on cached .pyc files 521 522 @unittest.skipUnless(os.name == 'posix', 523 "test meaningful only on posix systems") 524 def test_creation_mode(self): 525 mask = 0o022 526 with temp_umask(mask), _ready_to_import() as (name, path): 527 cached_path = importlib.util.cache_from_source(path) 528 module = __import__(name) 529 if not os.path.exists(cached_path): 530 self.fail("__import__ did not result in creation of " 531 "a .pyc file") 532 stat_info = os.stat(cached_path) 533 534 # Check that the umask is respected, and the executable bits 535 # aren't set. 536 self.assertEqual(oct(stat.S_IMODE(stat_info.st_mode)), 537 oct(0o666 & ~mask)) 538 539 @unittest.skipUnless(os.name == 'posix', 540 "test meaningful only on posix systems") 541 def test_cached_mode_issue_2051(self): 542 # permissions of .pyc should match those of .py, regardless of mask 543 mode = 0o600 544 with temp_umask(0o022), _ready_to_import() as (name, path): 545 cached_path = importlib.util.cache_from_source(path) 546 os.chmod(path, mode) 547 __import__(name) 548 if not os.path.exists(cached_path): 549 self.fail("__import__ did not result in creation of " 550 "a .pyc file") 551 stat_info = os.stat(cached_path) 552 553 self.assertEqual(oct(stat.S_IMODE(stat_info.st_mode)), oct(mode)) 554 555 @unittest.skipUnless(os.name == 'posix', 556 "test meaningful only on posix systems") 557 def test_cached_readonly(self): 558 mode = 0o400 559 with temp_umask(0o022), _ready_to_import() as (name, path): 560 cached_path = importlib.util.cache_from_source(path) 561 os.chmod(path, mode) 562 __import__(name) 563 if not os.path.exists(cached_path): 564 self.fail("__import__ did not result in creation of " 565 "a .pyc file") 566 stat_info = os.stat(cached_path) 567 568 expected = mode | 0o200 # Account for fix for issue #6074 569 self.assertEqual(oct(stat.S_IMODE(stat_info.st_mode)), oct(expected)) 570 571 def test_pyc_always_writable(self): 572 # Initially read-only .pyc files on Windows used to cause problems 573 # with later updates, see issue #6074 for details 574 with _ready_to_import() as (name, path): 575 # Write a Python file, make it read-only and import it 576 with open(path, 'w') as f: 577 f.write("x = 'original'\n") 578 # Tweak the mtime of the source to ensure pyc gets updated later 579 s = os.stat(path) 580 os.utime(path, (s.st_atime, s.st_mtime-100000000)) 581 os.chmod(path, 0o400) 582 m = __import__(name) 583 self.assertEqual(m.x, 'original') 584 # Change the file and then reimport it 585 os.chmod(path, 0o600) 586 with open(path, 'w') as f: 587 f.write("x = 'rewritten'\n") 588 unload(name) 589 importlib.invalidate_caches() 590 m = __import__(name) 591 self.assertEqual(m.x, 'rewritten') 592 # Now delete the source file and check the pyc was rewritten 593 unlink(path) 594 unload(name) 595 importlib.invalidate_caches() 596 bytecode_only = path + "c" 597 os.rename(importlib.util.cache_from_source(path), bytecode_only) 598 m = __import__(name) 599 self.assertEqual(m.x, 'rewritten') 600 601 602class PycRewritingTests(unittest.TestCase): 603 # Test that the `co_filename` attribute on code objects always points 604 # to the right file, even when various things happen (e.g. both the .py 605 # and the .pyc file are renamed). 606 607 module_name = "unlikely_module_name" 608 module_source = """ 609import sys 610code_filename = sys._getframe().f_code.co_filename 611module_filename = __file__ 612constant = 1 613def func(): 614 pass 615func_filename = func.__code__.co_filename 616""" 617 dir_name = os.path.abspath(TESTFN) 618 file_name = os.path.join(dir_name, module_name) + os.extsep + "py" 619 compiled_name = importlib.util.cache_from_source(file_name) 620 621 def setUp(self): 622 self.sys_path = sys.path[:] 623 self.orig_module = sys.modules.pop(self.module_name, None) 624 os.mkdir(self.dir_name) 625 with open(self.file_name, "w") as f: 626 f.write(self.module_source) 627 sys.path.insert(0, self.dir_name) 628 importlib.invalidate_caches() 629 630 def tearDown(self): 631 sys.path[:] = self.sys_path 632 if self.orig_module is not None: 633 sys.modules[self.module_name] = self.orig_module 634 else: 635 unload(self.module_name) 636 unlink(self.file_name) 637 unlink(self.compiled_name) 638 rmtree(self.dir_name) 639 640 def import_module(self): 641 ns = globals() 642 __import__(self.module_name, ns, ns) 643 return sys.modules[self.module_name] 644 645 def test_basics(self): 646 mod = self.import_module() 647 self.assertEqual(mod.module_filename, self.file_name) 648 self.assertEqual(mod.code_filename, self.file_name) 649 self.assertEqual(mod.func_filename, self.file_name) 650 del sys.modules[self.module_name] 651 mod = self.import_module() 652 self.assertEqual(mod.module_filename, self.file_name) 653 self.assertEqual(mod.code_filename, self.file_name) 654 self.assertEqual(mod.func_filename, self.file_name) 655 656 def test_incorrect_code_name(self): 657 py_compile.compile(self.file_name, dfile="another_module.py") 658 mod = self.import_module() 659 self.assertEqual(mod.module_filename, self.file_name) 660 self.assertEqual(mod.code_filename, self.file_name) 661 self.assertEqual(mod.func_filename, self.file_name) 662 663 def test_module_without_source(self): 664 target = "another_module.py" 665 py_compile.compile(self.file_name, dfile=target) 666 os.remove(self.file_name) 667 pyc_file = make_legacy_pyc(self.file_name) 668 importlib.invalidate_caches() 669 mod = self.import_module() 670 self.assertEqual(mod.module_filename, pyc_file) 671 self.assertEqual(mod.code_filename, target) 672 self.assertEqual(mod.func_filename, target) 673 674 def test_foreign_code(self): 675 py_compile.compile(self.file_name) 676 with open(self.compiled_name, "rb") as f: 677 header = f.read(16) 678 code = marshal.load(f) 679 constants = list(code.co_consts) 680 foreign_code = importlib.import_module.__code__ 681 pos = constants.index(1) 682 constants[pos] = foreign_code 683 code = code.replace(co_consts=tuple(constants)) 684 with open(self.compiled_name, "wb") as f: 685 f.write(header) 686 marshal.dump(code, f) 687 mod = self.import_module() 688 self.assertEqual(mod.constant.co_filename, foreign_code.co_filename) 689 690 691class PathsTests(unittest.TestCase): 692 SAMPLES = ('test', 'test\u00e4\u00f6\u00fc\u00df', 'test\u00e9\u00e8', 693 'test\u00b0\u00b3\u00b2') 694 path = TESTFN 695 696 def setUp(self): 697 os.mkdir(self.path) 698 self.syspath = sys.path[:] 699 700 def tearDown(self): 701 rmtree(self.path) 702 sys.path[:] = self.syspath 703 704 # Regression test for http://bugs.python.org/issue1293. 705 def test_trailing_slash(self): 706 with open(os.path.join(self.path, 'test_trailing_slash.py'), 'w') as f: 707 f.write("testdata = 'test_trailing_slash'") 708 sys.path.append(self.path+'/') 709 mod = __import__("test_trailing_slash") 710 self.assertEqual(mod.testdata, 'test_trailing_slash') 711 unload("test_trailing_slash") 712 713 # Regression test for http://bugs.python.org/issue3677. 714 @unittest.skipUnless(sys.platform == 'win32', 'Windows-specific') 715 def test_UNC_path(self): 716 with open(os.path.join(self.path, 'test_unc_path.py'), 'w') as f: 717 f.write("testdata = 'test_unc_path'") 718 importlib.invalidate_caches() 719 # Create the UNC path, like \\myhost\c$\foo\bar. 720 path = os.path.abspath(self.path) 721 import socket 722 hn = socket.gethostname() 723 drive = path[0] 724 unc = "\\\\%s\\%s$"%(hn, drive) 725 unc += path[2:] 726 try: 727 os.listdir(unc) 728 except OSError as e: 729 if e.errno in (errno.EPERM, errno.EACCES, errno.ENOENT): 730 # See issue #15338 731 self.skipTest("cannot access administrative share %r" % (unc,)) 732 raise 733 sys.path.insert(0, unc) 734 try: 735 mod = __import__("test_unc_path") 736 except ImportError as e: 737 self.fail("could not import 'test_unc_path' from %r: %r" 738 % (unc, e)) 739 self.assertEqual(mod.testdata, 'test_unc_path') 740 self.assertTrue(mod.__file__.startswith(unc), mod.__file__) 741 unload("test_unc_path") 742 743 744class RelativeImportTests(unittest.TestCase): 745 746 def tearDown(self): 747 unload("test.relimport") 748 setUp = tearDown 749 750 def test_relimport_star(self): 751 # This will import * from .test_import. 752 from .. import relimport 753 self.assertTrue(hasattr(relimport, "RelativeImportTests")) 754 755 def test_issue3221(self): 756 # Note for mergers: the 'absolute' tests from the 2.x branch 757 # are missing in Py3k because implicit relative imports are 758 # a thing of the past 759 # 760 # Regression test for http://bugs.python.org/issue3221. 761 def check_relative(): 762 exec("from . import relimport", ns) 763 764 # Check relative import OK with __package__ and __name__ correct 765 ns = dict(__package__='test', __name__='test.notarealmodule') 766 check_relative() 767 768 # Check relative import OK with only __name__ wrong 769 ns = dict(__package__='test', __name__='notarealpkg.notarealmodule') 770 check_relative() 771 772 # Check relative import fails with only __package__ wrong 773 ns = dict(__package__='foo', __name__='test.notarealmodule') 774 self.assertRaises(ModuleNotFoundError, check_relative) 775 776 # Check relative import fails with __package__ and __name__ wrong 777 ns = dict(__package__='foo', __name__='notarealpkg.notarealmodule') 778 self.assertRaises(ModuleNotFoundError, check_relative) 779 780 # Check relative import fails with package set to a non-string 781 ns = dict(__package__=object()) 782 self.assertRaises(TypeError, check_relative) 783 784 def test_parentless_import_shadowed_by_global(self): 785 # Test as if this were done from the REPL where this error most commonly occurs (bpo-37409). 786 script_helper.assert_python_failure('-W', 'ignore', '-c', 787 "foo = 1; from . import foo") 788 789 def test_absolute_import_without_future(self): 790 # If explicit relative import syntax is used, then do not try 791 # to perform an absolute import in the face of failure. 792 # Issue #7902. 793 with self.assertRaises(ImportError): 794 from .os import sep 795 self.fail("explicit relative import triggered an " 796 "implicit absolute import") 797 798 def test_import_from_non_package(self): 799 path = os.path.join(os.path.dirname(__file__), 'data', 'package2') 800 with uncache('submodule1', 'submodule2'), DirsOnSysPath(path): 801 with self.assertRaises(ImportError): 802 import submodule1 803 self.assertNotIn('submodule1', sys.modules) 804 self.assertNotIn('submodule2', sys.modules) 805 806 def test_import_from_unloaded_package(self): 807 with uncache('package2', 'package2.submodule1', 'package2.submodule2'), \ 808 DirsOnSysPath(os.path.join(os.path.dirname(__file__), 'data')): 809 import package2.submodule1 810 package2.submodule1.submodule2 811 812 813class OverridingImportBuiltinTests(unittest.TestCase): 814 def test_override_builtin(self): 815 # Test that overriding builtins.__import__ can bypass sys.modules. 816 import os 817 818 def foo(): 819 import os 820 return os 821 self.assertEqual(foo(), os) # Quick sanity check. 822 823 with swap_attr(builtins, "__import__", lambda *x: 5): 824 self.assertEqual(foo(), 5) 825 826 # Test what happens when we shadow __import__ in globals(); this 827 # currently does not impact the import process, but if this changes, 828 # other code will need to change, so keep this test as a tripwire. 829 with swap_item(globals(), "__import__", lambda *x: 5): 830 self.assertEqual(foo(), os) 831 832 833class PycacheTests(unittest.TestCase): 834 # Test the various PEP 3147/488-related behaviors. 835 836 def _clean(self): 837 forget(TESTFN) 838 rmtree('__pycache__') 839 unlink(self.source) 840 841 def setUp(self): 842 self.source = TESTFN + '.py' 843 self._clean() 844 with open(self.source, 'w') as fp: 845 print('# This is a test file written by test_import.py', file=fp) 846 sys.path.insert(0, os.curdir) 847 importlib.invalidate_caches() 848 849 def tearDown(self): 850 assert sys.path[0] == os.curdir, 'Unexpected sys.path[0]' 851 del sys.path[0] 852 self._clean() 853 854 @skip_if_dont_write_bytecode 855 def test_import_pyc_path(self): 856 self.assertFalse(os.path.exists('__pycache__')) 857 __import__(TESTFN) 858 self.assertTrue(os.path.exists('__pycache__')) 859 pyc_path = importlib.util.cache_from_source(self.source) 860 self.assertTrue(os.path.exists(pyc_path), 861 'bytecode file {!r} for {!r} does not ' 862 'exist'.format(pyc_path, TESTFN)) 863 864 @unittest.skipUnless(os.name == 'posix', 865 "test meaningful only on posix systems") 866 @unittest.skipIf(hasattr(os, 'geteuid') and os.geteuid() == 0, 867 "due to varying filesystem permission semantics (issue #11956)") 868 @skip_if_dont_write_bytecode 869 def test_unwritable_directory(self): 870 # When the umask causes the new __pycache__ directory to be 871 # unwritable, the import still succeeds but no .pyc file is written. 872 with temp_umask(0o222): 873 __import__(TESTFN) 874 self.assertTrue(os.path.exists('__pycache__')) 875 pyc_path = importlib.util.cache_from_source(self.source) 876 self.assertFalse(os.path.exists(pyc_path), 877 'bytecode file {!r} for {!r} ' 878 'exists'.format(pyc_path, TESTFN)) 879 880 @skip_if_dont_write_bytecode 881 def test_missing_source(self): 882 # With PEP 3147 cache layout, removing the source but leaving the pyc 883 # file does not satisfy the import. 884 __import__(TESTFN) 885 pyc_file = importlib.util.cache_from_source(self.source) 886 self.assertTrue(os.path.exists(pyc_file)) 887 os.remove(self.source) 888 forget(TESTFN) 889 importlib.invalidate_caches() 890 self.assertRaises(ImportError, __import__, TESTFN) 891 892 @skip_if_dont_write_bytecode 893 def test_missing_source_legacy(self): 894 # Like test_missing_source() except that for backward compatibility, 895 # when the pyc file lives where the py file would have been (and named 896 # without the tag), it is importable. The __file__ of the imported 897 # module is the pyc location. 898 __import__(TESTFN) 899 # pyc_file gets removed in _clean() via tearDown(). 900 pyc_file = make_legacy_pyc(self.source) 901 os.remove(self.source) 902 unload(TESTFN) 903 importlib.invalidate_caches() 904 m = __import__(TESTFN) 905 try: 906 self.assertEqual(m.__file__, 907 os.path.join(os.curdir, os.path.relpath(pyc_file))) 908 finally: 909 os.remove(pyc_file) 910 911 def test___cached__(self): 912 # Modules now also have an __cached__ that points to the pyc file. 913 m = __import__(TESTFN) 914 pyc_file = importlib.util.cache_from_source(TESTFN + '.py') 915 self.assertEqual(m.__cached__, os.path.join(os.curdir, pyc_file)) 916 917 @skip_if_dont_write_bytecode 918 def test___cached___legacy_pyc(self): 919 # Like test___cached__() except that for backward compatibility, 920 # when the pyc file lives where the py file would have been (and named 921 # without the tag), it is importable. The __cached__ of the imported 922 # module is the pyc location. 923 __import__(TESTFN) 924 # pyc_file gets removed in _clean() via tearDown(). 925 pyc_file = make_legacy_pyc(self.source) 926 os.remove(self.source) 927 unload(TESTFN) 928 importlib.invalidate_caches() 929 m = __import__(TESTFN) 930 self.assertEqual(m.__cached__, 931 os.path.join(os.curdir, os.path.relpath(pyc_file))) 932 933 @skip_if_dont_write_bytecode 934 def test_package___cached__(self): 935 # Like test___cached__ but for packages. 936 def cleanup(): 937 rmtree('pep3147') 938 unload('pep3147.foo') 939 unload('pep3147') 940 os.mkdir('pep3147') 941 self.addCleanup(cleanup) 942 # Touch the __init__.py 943 with open(os.path.join('pep3147', '__init__.py'), 'w'): 944 pass 945 with open(os.path.join('pep3147', 'foo.py'), 'w'): 946 pass 947 importlib.invalidate_caches() 948 m = __import__('pep3147.foo') 949 init_pyc = importlib.util.cache_from_source( 950 os.path.join('pep3147', '__init__.py')) 951 self.assertEqual(m.__cached__, os.path.join(os.curdir, init_pyc)) 952 foo_pyc = importlib.util.cache_from_source(os.path.join('pep3147', 'foo.py')) 953 self.assertEqual(sys.modules['pep3147.foo'].__cached__, 954 os.path.join(os.curdir, foo_pyc)) 955 956 def test_package___cached___from_pyc(self): 957 # Like test___cached__ but ensuring __cached__ when imported from a 958 # PEP 3147 pyc file. 959 def cleanup(): 960 rmtree('pep3147') 961 unload('pep3147.foo') 962 unload('pep3147') 963 os.mkdir('pep3147') 964 self.addCleanup(cleanup) 965 # Touch the __init__.py 966 with open(os.path.join('pep3147', '__init__.py'), 'w'): 967 pass 968 with open(os.path.join('pep3147', 'foo.py'), 'w'): 969 pass 970 importlib.invalidate_caches() 971 m = __import__('pep3147.foo') 972 unload('pep3147.foo') 973 unload('pep3147') 974 importlib.invalidate_caches() 975 m = __import__('pep3147.foo') 976 init_pyc = importlib.util.cache_from_source( 977 os.path.join('pep3147', '__init__.py')) 978 self.assertEqual(m.__cached__, os.path.join(os.curdir, init_pyc)) 979 foo_pyc = importlib.util.cache_from_source(os.path.join('pep3147', 'foo.py')) 980 self.assertEqual(sys.modules['pep3147.foo'].__cached__, 981 os.path.join(os.curdir, foo_pyc)) 982 983 def test_recompute_pyc_same_second(self): 984 # Even when the source file doesn't change timestamp, a change in 985 # source size is enough to trigger recomputation of the pyc file. 986 __import__(TESTFN) 987 unload(TESTFN) 988 with open(self.source, 'a') as fp: 989 print("x = 5", file=fp) 990 m = __import__(TESTFN) 991 self.assertEqual(m.x, 5) 992 993 994class TestSymbolicallyLinkedPackage(unittest.TestCase): 995 package_name = 'sample' 996 tagged = package_name + '-tagged' 997 998 def setUp(self): 999 test.support.rmtree(self.tagged) 1000 test.support.rmtree(self.package_name) 1001 self.orig_sys_path = sys.path[:] 1002 1003 # create a sample package; imagine you have a package with a tag and 1004 # you want to symbolically link it from its untagged name. 1005 os.mkdir(self.tagged) 1006 self.addCleanup(test.support.rmtree, self.tagged) 1007 init_file = os.path.join(self.tagged, '__init__.py') 1008 test.support.create_empty_file(init_file) 1009 assert os.path.exists(init_file) 1010 1011 # now create a symlink to the tagged package 1012 # sample -> sample-tagged 1013 os.symlink(self.tagged, self.package_name, target_is_directory=True) 1014 self.addCleanup(test.support.unlink, self.package_name) 1015 importlib.invalidate_caches() 1016 1017 self.assertEqual(os.path.isdir(self.package_name), True) 1018 1019 assert os.path.isfile(os.path.join(self.package_name, '__init__.py')) 1020 1021 def tearDown(self): 1022 sys.path[:] = self.orig_sys_path 1023 1024 # regression test for issue6727 1025 @unittest.skipUnless( 1026 not hasattr(sys, 'getwindowsversion') 1027 or sys.getwindowsversion() >= (6, 0), 1028 "Windows Vista or later required") 1029 @test.support.skip_unless_symlink 1030 def test_symlinked_dir_importable(self): 1031 # make sure sample can only be imported from the current directory. 1032 sys.path[:] = ['.'] 1033 assert os.path.exists(self.package_name) 1034 assert os.path.exists(os.path.join(self.package_name, '__init__.py')) 1035 1036 # Try to import the package 1037 importlib.import_module(self.package_name) 1038 1039 1040@cpython_only 1041class ImportlibBootstrapTests(unittest.TestCase): 1042 # These tests check that importlib is bootstrapped. 1043 1044 def test_frozen_importlib(self): 1045 mod = sys.modules['_frozen_importlib'] 1046 self.assertTrue(mod) 1047 1048 def test_frozen_importlib_is_bootstrap(self): 1049 from importlib import _bootstrap 1050 mod = sys.modules['_frozen_importlib'] 1051 self.assertIs(mod, _bootstrap) 1052 self.assertEqual(mod.__name__, 'importlib._bootstrap') 1053 self.assertEqual(mod.__package__, 'importlib') 1054 self.assertTrue(mod.__file__.endswith('_bootstrap.py'), mod.__file__) 1055 1056 def test_frozen_importlib_external_is_bootstrap_external(self): 1057 from importlib import _bootstrap_external 1058 mod = sys.modules['_frozen_importlib_external'] 1059 self.assertIs(mod, _bootstrap_external) 1060 self.assertEqual(mod.__name__, 'importlib._bootstrap_external') 1061 self.assertEqual(mod.__package__, 'importlib') 1062 self.assertTrue(mod.__file__.endswith('_bootstrap_external.py'), mod.__file__) 1063 1064 def test_there_can_be_only_one(self): 1065 # Issue #15386 revealed a tricky loophole in the bootstrapping 1066 # This test is technically redundant, since the bug caused importing 1067 # this test module to crash completely, but it helps prove the point 1068 from importlib import machinery 1069 mod = sys.modules['_frozen_importlib'] 1070 self.assertIs(machinery.ModuleSpec, mod.ModuleSpec) 1071 1072 1073@cpython_only 1074class GetSourcefileTests(unittest.TestCase): 1075 1076 """Test importlib._bootstrap_external._get_sourcefile() as used by the C API. 1077 1078 Because of the peculiarities of the need of this function, the tests are 1079 knowingly whitebox tests. 1080 1081 """ 1082 1083 def test_get_sourcefile(self): 1084 # Given a valid bytecode path, return the path to the corresponding 1085 # source file if it exists. 1086 with mock.patch('importlib._bootstrap_external._path_isfile') as _path_isfile: 1087 _path_isfile.return_value = True; 1088 path = TESTFN + '.pyc' 1089 expect = TESTFN + '.py' 1090 self.assertEqual(_get_sourcefile(path), expect) 1091 1092 def test_get_sourcefile_no_source(self): 1093 # Given a valid bytecode path without a corresponding source path, 1094 # return the original bytecode path. 1095 with mock.patch('importlib._bootstrap_external._path_isfile') as _path_isfile: 1096 _path_isfile.return_value = False; 1097 path = TESTFN + '.pyc' 1098 self.assertEqual(_get_sourcefile(path), path) 1099 1100 def test_get_sourcefile_bad_ext(self): 1101 # Given a path with an invalid bytecode extension, return the 1102 # bytecode path passed as the argument. 1103 path = TESTFN + '.bad_ext' 1104 self.assertEqual(_get_sourcefile(path), path) 1105 1106 1107class ImportTracebackTests(unittest.TestCase): 1108 1109 def setUp(self): 1110 os.mkdir(TESTFN) 1111 self.old_path = sys.path[:] 1112 sys.path.insert(0, TESTFN) 1113 1114 def tearDown(self): 1115 sys.path[:] = self.old_path 1116 rmtree(TESTFN) 1117 1118 def create_module(self, mod, contents, ext=".py"): 1119 fname = os.path.join(TESTFN, mod + ext) 1120 with open(fname, "w") as f: 1121 f.write(contents) 1122 self.addCleanup(unload, mod) 1123 importlib.invalidate_caches() 1124 return fname 1125 1126 def assert_traceback(self, tb, files): 1127 deduped_files = [] 1128 while tb: 1129 code = tb.tb_frame.f_code 1130 fn = code.co_filename 1131 if not deduped_files or fn != deduped_files[-1]: 1132 deduped_files.append(fn) 1133 tb = tb.tb_next 1134 self.assertEqual(len(deduped_files), len(files), deduped_files) 1135 for fn, pat in zip(deduped_files, files): 1136 self.assertIn(pat, fn) 1137 1138 def test_nonexistent_module(self): 1139 try: 1140 # assertRaises() clears __traceback__ 1141 import nonexistent_xyzzy 1142 except ImportError as e: 1143 tb = e.__traceback__ 1144 else: 1145 self.fail("ImportError should have been raised") 1146 self.assert_traceback(tb, [__file__]) 1147 1148 def test_nonexistent_module_nested(self): 1149 self.create_module("foo", "import nonexistent_xyzzy") 1150 try: 1151 import foo 1152 except ImportError as e: 1153 tb = e.__traceback__ 1154 else: 1155 self.fail("ImportError should have been raised") 1156 self.assert_traceback(tb, [__file__, 'foo.py']) 1157 1158 def test_exec_failure(self): 1159 self.create_module("foo", "1/0") 1160 try: 1161 import foo 1162 except ZeroDivisionError as e: 1163 tb = e.__traceback__ 1164 else: 1165 self.fail("ZeroDivisionError should have been raised") 1166 self.assert_traceback(tb, [__file__, 'foo.py']) 1167 1168 def test_exec_failure_nested(self): 1169 self.create_module("foo", "import bar") 1170 self.create_module("bar", "1/0") 1171 try: 1172 import foo 1173 except ZeroDivisionError as e: 1174 tb = e.__traceback__ 1175 else: 1176 self.fail("ZeroDivisionError should have been raised") 1177 self.assert_traceback(tb, [__file__, 'foo.py', 'bar.py']) 1178 1179 # A few more examples from issue #15425 1180 def test_syntax_error(self): 1181 self.create_module("foo", "invalid syntax is invalid") 1182 try: 1183 import foo 1184 except SyntaxError as e: 1185 tb = e.__traceback__ 1186 else: 1187 self.fail("SyntaxError should have been raised") 1188 self.assert_traceback(tb, [__file__]) 1189 1190 def _setup_broken_package(self, parent, child): 1191 pkg_name = "_parent_foo" 1192 self.addCleanup(unload, pkg_name) 1193 pkg_path = os.path.join(TESTFN, pkg_name) 1194 os.mkdir(pkg_path) 1195 # Touch the __init__.py 1196 init_path = os.path.join(pkg_path, '__init__.py') 1197 with open(init_path, 'w') as f: 1198 f.write(parent) 1199 bar_path = os.path.join(pkg_path, 'bar.py') 1200 with open(bar_path, 'w') as f: 1201 f.write(child) 1202 importlib.invalidate_caches() 1203 return init_path, bar_path 1204 1205 def test_broken_submodule(self): 1206 init_path, bar_path = self._setup_broken_package("", "1/0") 1207 try: 1208 import _parent_foo.bar 1209 except ZeroDivisionError as e: 1210 tb = e.__traceback__ 1211 else: 1212 self.fail("ZeroDivisionError should have been raised") 1213 self.assert_traceback(tb, [__file__, bar_path]) 1214 1215 def test_broken_from(self): 1216 init_path, bar_path = self._setup_broken_package("", "1/0") 1217 try: 1218 from _parent_foo import bar 1219 except ZeroDivisionError as e: 1220 tb = e.__traceback__ 1221 else: 1222 self.fail("ImportError should have been raised") 1223 self.assert_traceback(tb, [__file__, bar_path]) 1224 1225 def test_broken_parent(self): 1226 init_path, bar_path = self._setup_broken_package("1/0", "") 1227 try: 1228 import _parent_foo.bar 1229 except ZeroDivisionError as e: 1230 tb = e.__traceback__ 1231 else: 1232 self.fail("ZeroDivisionError should have been raised") 1233 self.assert_traceback(tb, [__file__, init_path]) 1234 1235 def test_broken_parent_from(self): 1236 init_path, bar_path = self._setup_broken_package("1/0", "") 1237 try: 1238 from _parent_foo import bar 1239 except ZeroDivisionError as e: 1240 tb = e.__traceback__ 1241 else: 1242 self.fail("ZeroDivisionError should have been raised") 1243 self.assert_traceback(tb, [__file__, init_path]) 1244 1245 @cpython_only 1246 def test_import_bug(self): 1247 # We simulate a bug in importlib and check that it's not stripped 1248 # away from the traceback. 1249 self.create_module("foo", "") 1250 importlib = sys.modules['_frozen_importlib_external'] 1251 if 'load_module' in vars(importlib.SourceLoader): 1252 old_exec_module = importlib.SourceLoader.exec_module 1253 else: 1254 old_exec_module = None 1255 try: 1256 def exec_module(*args): 1257 1/0 1258 importlib.SourceLoader.exec_module = exec_module 1259 try: 1260 import foo 1261 except ZeroDivisionError as e: 1262 tb = e.__traceback__ 1263 else: 1264 self.fail("ZeroDivisionError should have been raised") 1265 self.assert_traceback(tb, [__file__, '<frozen importlib', __file__]) 1266 finally: 1267 if old_exec_module is None: 1268 del importlib.SourceLoader.exec_module 1269 else: 1270 importlib.SourceLoader.exec_module = old_exec_module 1271 1272 @unittest.skipUnless(TESTFN_UNENCODABLE, 'need TESTFN_UNENCODABLE') 1273 def test_unencodable_filename(self): 1274 # Issue #11619: The Python parser and the import machinery must not 1275 # encode filenames, especially on Windows 1276 pyname = script_helper.make_script('', TESTFN_UNENCODABLE, 'pass') 1277 self.addCleanup(unlink, pyname) 1278 name = pyname[:-3] 1279 script_helper.assert_python_ok("-c", "mod = __import__(%a)" % name, 1280 __isolated=False) 1281 1282 1283class CircularImportTests(unittest.TestCase): 1284 1285 """See the docstrings of the modules being imported for the purpose of the 1286 test.""" 1287 1288 def tearDown(self): 1289 """Make sure no modules pre-exist in sys.modules which are being used to 1290 test.""" 1291 for key in list(sys.modules.keys()): 1292 if key.startswith('test.test_import.data.circular_imports'): 1293 del sys.modules[key] 1294 1295 def test_direct(self): 1296 try: 1297 import test.test_import.data.circular_imports.basic 1298 except ImportError: 1299 self.fail('circular import through relative imports failed') 1300 1301 def test_indirect(self): 1302 try: 1303 import test.test_import.data.circular_imports.indirect 1304 except ImportError: 1305 self.fail('relative import in module contributing to circular ' 1306 'import failed') 1307 1308 def test_subpackage(self): 1309 try: 1310 import test.test_import.data.circular_imports.subpackage 1311 except ImportError: 1312 self.fail('circular import involving a subpackage failed') 1313 1314 def test_rebinding(self): 1315 try: 1316 import test.test_import.data.circular_imports.rebinding as rebinding 1317 except ImportError: 1318 self.fail('circular import with rebinding of module attribute failed') 1319 from test.test_import.data.circular_imports.subpkg import util 1320 self.assertIs(util.util, rebinding.util) 1321 1322 def test_binding(self): 1323 try: 1324 import test.test_import.data.circular_imports.binding 1325 except ImportError: 1326 self.fail('circular import with binding a submodule to a name failed') 1327 1328 def test_crossreference1(self): 1329 import test.test_import.data.circular_imports.use 1330 import test.test_import.data.circular_imports.source 1331 1332 def test_crossreference2(self): 1333 with self.assertRaises(AttributeError) as cm: 1334 import test.test_import.data.circular_imports.source 1335 errmsg = str(cm.exception) 1336 self.assertIn('test.test_import.data.circular_imports.source', errmsg) 1337 self.assertIn('spam', errmsg) 1338 self.assertIn('partially initialized module', errmsg) 1339 self.assertIn('circular import', errmsg) 1340 1341 def test_circular_from_import(self): 1342 with self.assertRaises(ImportError) as cm: 1343 import test.test_import.data.circular_imports.from_cycle1 1344 self.assertIn( 1345 "cannot import name 'b' from partially initialized module " 1346 "'test.test_import.data.circular_imports.from_cycle1' " 1347 "(most likely due to a circular import)", 1348 str(cm.exception), 1349 ) 1350 1351 def test_unwritable_module(self): 1352 self.addCleanup(unload, "test.test_import.data.unwritable") 1353 self.addCleanup(unload, "test.test_import.data.unwritable.x") 1354 1355 import test.test_import.data.unwritable as unwritable 1356 with self.assertWarns(ImportWarning): 1357 from test.test_import.data.unwritable import x 1358 1359 self.assertNotEqual(type(unwritable), ModuleType) 1360 self.assertEqual(type(x), ModuleType) 1361 with self.assertRaises(AttributeError): 1362 unwritable.x = 42 1363 1364 1365if __name__ == '__main__': 1366 # Test needs to be a package, so we can do relative imports. 1367 unittest.main() 1368