ยปCore Development>Code coverage>Lib/test/test_import/__init__.py

Python code coverage for Lib/test/test_import/__init__.py

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