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