def _check_relative_imports(self, depth, run_name=None): contents = r"""\ from __future__ import absolute_import from . import sibling from ..uncle.cousin import nephew """ pkg_dir, mod_fname, mod_name = ( self._make_pkg(contents, depth)) try: self._add_relative_modules(pkg_dir, contents, depth) pkg_name = mod_name.rpartition('.')[0] if verbose: print("Running from source:", mod_name) d1 = run_module(mod_name, run_name=run_name) # Read from source self.assertIn("__package__", d1) self.assertTrue(d1["__package__"] == pkg_name) self.assertIn("sibling", d1) self.assertIn("nephew", d1) del d1 # Ensure __loader__ entry doesn't keep file open __import__(mod_name) os.remove(mod_fname) make_legacy_pyc(mod_fname) unload(mod_name) # In case the loader caches paths if verbose: print("Running from compiled:", mod_name) d2 = run_module(mod_name, run_name=run_name) # Read from bytecode self.assertIn("__package__", d2) self.assertTrue(d2["__package__"] == pkg_name) self.assertIn("sibling", d2) self.assertIn("nephew", d2) del d2 # Ensure __loader__ entry doesn't keep file open finally: self._del_pkg(pkg_dir, depth, mod_name) if verbose: print("Module executed successfully")
def test_execute_bit_not_copied(self): # Issue 6070: under posix .pyc files got their execute bit set if # the .py file had the execute bit set, but they aren't executable. oldmask = os.umask(0o22) sys.path.insert(0, os.curdir) try: fname = TESTFN + os.extsep + "py" f = open(fname, 'w').close() os.chmod(fname, (stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)) __import__(TESTFN) fn = fname + 'c' if not os.path.exists(fn): fn = fname + 'o' if not os.path.exists(fn): self.fail("__import__ did not result in creation of " "either a .pyc or .pyo file") s = os.stat(fn) self.assertEqual(stat.S_IMODE(s.st_mode), stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH) finally: os.umask(oldmask) remove_files(TESTFN) unload(TESTFN) del sys.path[0]
def test_pyc_always_writable(self): # Initially read-only .pyc files on Windows used to cause problems # with later updates, see issue #6074 for details with _ready_to_import() as (name, path): # Write a Python file, make it read-only and import it with open(path, 'w') as f: f.write("x = 'original'\n") # Tweak the mtime of the source to ensure pyc gets updated later s = os.stat(path) os.utime(path, (s.st_atime, s.st_mtime-100000000)) os.chmod(path, 0o400) m = __import__(name) self.assertEqual(m.x, 'original') # Change the file and then reimport it os.chmod(path, 0o600) with open(path, 'w') as f: f.write("x = 'rewritten'\n") unload(name) importlib.invalidate_caches() m = __import__(name) self.assertEqual(m.x, 'rewritten') # Now delete the source file and check the pyc was rewritten unlink(path) unload(name) importlib.invalidate_caches() bytecode_only = path + "c" os.rename(importlib.util.cache_from_source(path), bytecode_only) m = __import__(name) self.assertEqual(m.x, 'rewritten')
def test_package___cached___from_pyc(self): # Like test___cached__ but ensuring __cached__ when imported from a # PEP 3147 pyc file. def cleanup(): rmtree("pep3147") unload("pep3147.foo") unload("pep3147") os.mkdir("pep3147") self.addCleanup(cleanup) # Touch the __init__.py with open(os.path.join("pep3147", "__init__.py"), "w"): pass with open(os.path.join("pep3147", "foo.py"), "w"): pass importlib.invalidate_caches() m = __import__("pep3147.foo") unload("pep3147.foo") unload("pep3147") importlib.invalidate_caches() m = __import__("pep3147.foo") init_pyc = imp.cache_from_source(os.path.join("pep3147", "__init__.py")) self.assertEqual(m.__cached__, os.path.join(os.curdir, init_pyc)) foo_pyc = imp.cache_from_source(os.path.join("pep3147", "foo.py")) self.assertEqual(sys.modules["pep3147.foo"].__cached__, os.path.join(os.curdir, foo_pyc))
def test_package___file__(self): try: m = __import__('pep3147') except ImportError: pass else: self.fail("pep3147 module already exists: %r" % (m,)) # Test that a package's __file__ points to the right source directory. os.mkdir('pep3147') sys.path.insert(0, os.curdir) def cleanup(): if sys.path[0] == os.curdir: del sys.path[0] shutil.rmtree('pep3147') self.addCleanup(cleanup) # Touch the __init__.py file. support.create_empty_file('pep3147/__init__.py') importlib.invalidate_caches() expected___file__ = os.sep.join(('.', 'pep3147', '__init__.py')) m = __import__('pep3147') self.assertEqual(m.__file__, expected___file__, (m.__file__, m.__path__, sys.path, sys.path_importer_cache)) # Ensure we load the pyc file. support.unload('pep3147') m = __import__('pep3147') support.unload('pep3147') self.assertEqual(m.__file__, expected___file__, (m.__file__, m.__path__, sys.path, sys.path_importer_cache))
def runtest_inner(ns, test, display_failure=True): support.unload(test) test_time = 0.0 refleak = False # True if the test leaked references. try: if test.startswith('test.') or ns.testdir: abstest = test else: # Always import it from the test package abstest = 'test.' + test with saved_test_environment(test, ns.verbose, ns.quiet, pgo=ns.pgo) as environment: start_time = time.time() the_module = importlib.import_module(abstest) # If the test has a test_main, that will run the appropriate # tests. If not, use normal unittest test loading. test_runner = getattr(the_module, "test_main", None) if test_runner is None: def test_runner(): loader = unittest.TestLoader() tests = loader.loadTestsFromModule(the_module) for error in loader.errors: print(error, file=sys.stderr) if loader.errors: raise Exception("errors while loading tests") support.run_unittest(tests) test_runner() if ns.huntrleaks: refleak = dash_R(the_module, test, test_runner, ns.huntrleaks) test_time = time.time() - start_time except support.ResourceDenied as msg: if not ns.quiet and not ns.pgo: print(test, "skipped --", msg, flush=True) return RESOURCE_DENIED, test_time except unittest.SkipTest as msg: if not ns.quiet and not ns.pgo: print(test, "skipped --", msg, flush=True) return SKIPPED, test_time except KeyboardInterrupt: raise except support.TestFailed as msg: if not ns.pgo: if display_failure: print("test", test, "failed --", msg, file=sys.stderr, flush=True) else: print("test", test, "failed", file=sys.stderr, flush=True) return FAILED, test_time except: msg = traceback.format_exc() if not ns.pgo: print("test", test, "crashed --", msg, file=sys.stderr, flush=True) return FAILED, test_time else: if refleak: return FAILED, test_time if environment.changed: return ENV_CHANGED, test_time return PASSED, test_time
def test_trailing_slash(self): with open(os.path.join(self.path, 'test_trailing_slash.py'), 'w') as f: f.write("testdata = 'test_trailing_slash'") sys.path.append(self.path+'/') mod = __import__("test_trailing_slash") self.assertEqual(mod.testdata, 'test_trailing_slash') unload("test_trailing_slash")
def test_package___cached___from_pyc(self): # Like test___cached__ but ensuring __cached__ when imported from a # PEP 3147 pyc file. def cleanup(): rmtree('pep3147') unload('pep3147.foo') unload('pep3147') os.mkdir('pep3147') self.addCleanup(cleanup) # Touch the __init__.py with open(os.path.join('pep3147', '__init__.py'), 'w'): pass with open(os.path.join('pep3147', 'foo.py'), 'w'): pass importlib.invalidate_caches() m = __import__('pep3147.foo') unload('pep3147.foo') unload('pep3147') importlib.invalidate_caches() m = __import__('pep3147.foo') init_pyc = importlib.util.cache_from_source( os.path.join('pep3147', '__init__.py')) self.assertEqual(m.__cached__, os.path.join(os.curdir, init_pyc)) foo_pyc = importlib.util.cache_from_source(os.path.join('pep3147', 'foo.py')) self.assertEqual(sys.modules['pep3147.foo'].__cached__, os.path.join(os.curdir, foo_pyc))
def test_UNC_path(self): with open(os.path.join(self.path, 'test_unc_path.py'), 'w') as f: f.write("testdata = 'test_unc_path'") importlib.invalidate_caches() # Create the UNC path, like \\myhost\c$\foo\bar. path = os.path.abspath(self.path) import socket hn = socket.gethostname() drive = path[0] unc = "\\\\%s\\%s$"%(hn, drive) unc += path[2:] try: os.listdir(unc) except OSError as e: if e.errno in (errno.EPERM, errno.EACCES): # See issue #15338 self.skipTest("cannot access administrative share %r" % (unc,)) raise sys.path.insert(0, unc) try: mod = __import__("test_unc_path") except ImportError as e: self.fail("could not import 'test_unc_path' from %r: %r" % (unc, e)) self.assertEqual(mod.testdata, 'test_unc_path') self.assertTrue(mod.__file__.startswith(unc), mod.__file__) unload("test_unc_path")
def test_trailing_slash(self): with open(os.path.join(self.path, "test_trailing_slash.py"), "w") as f: f.write("testdata = 'test_trailing_slash'") sys.path.append(self.path + "/") mod = __import__("test_trailing_slash") self.assertEqual(mod.testdata, "test_trailing_slash") unload("test_trailing_slash")
def _check_package(self, depth): pkg_dir, mod_fname, mod_name = self._make_pkg("x=1\n", depth, "__main__") pkg_name, _, _ = mod_name.rpartition(".") forget(mod_name) try: if verbose: print("Running from source:", pkg_name) d1 = run_module(pkg_name) # Read from source self.assertIn("x", d1) self.assertTrue(d1["x"] == 1) del d1 # Ensure __loader__ entry doesn't keep file open __import__(mod_name) os.remove(mod_fname) make_legacy_pyc(mod_fname) unload(mod_name) # In case loader caches paths if verbose: print("Running from compiled:", pkg_name) d2 = run_module(pkg_name) # Read from bytecode self.assertIn("x", d2) self.assertTrue(d2["x"] == 1) del d2 # Ensure __loader__ entry doesn't keep file open finally: self._del_pkg(pkg_dir, depth, pkg_name) if verbose: print("Package executed successfully")
def _check_package(self, depth, alter_sys=False): pkg_dir, mod_fname, mod_name = ( self._make_pkg(example_source, depth, "__main__")) pkg_name = mod_name.rpartition(".")[0] forget(mod_name) expected_ns = example_namespace.copy() expected_ns.update({ "__name__": mod_name, "__file__": mod_fname, "__package__": pkg_name, }) if alter_sys: expected_ns.update({ "run_argv0": mod_fname, "run_name_in_sys_modules": True, "module_in_sys_modules": True, }) def create_ns(init_globals): return run_module(pkg_name, init_globals, alter_sys=alter_sys) try: if verbose > 1: print("Running from source:", pkg_name) self.check_code_execution(create_ns, expected_ns) importlib.invalidate_caches() __import__(mod_name) os.remove(mod_fname) make_legacy_pyc(mod_fname) unload(mod_name) # In case loader caches paths if verbose > 1: print("Running from compiled:", pkg_name) importlib.invalidate_caches() self._fix_ns_for_legacy_pyc(expected_ns, alter_sys) self.check_code_execution(create_ns, expected_ns) finally: self._del_pkg(pkg_dir, depth, pkg_name) if verbose > 1: print("Package executed successfully")
def run_tests_sequential(self): if self.ns.trace: import trace self.tracer = trace.Trace(trace=False, count=True) save_modules = sys.modules.keys() print("Run tests sequentially") previous_test = None for test_index, test in enumerate(self.tests, 1): start_time = time.monotonic() text = test if previous_test: text = '%s -- %s' % (text, previous_test) self.display_progress(test_index, text) if self.tracer: # If we're tracing code coverage, then we don't exit with status # if on a false return value from main. cmd = ('result = runtest(self.ns, test); ' 'self.accumulate_result(test, result)') self.tracer.runctx(cmd, globals=globals(), locals=vars()) else: try: result = runtest(self.ns, test) except KeyboardInterrupt: self.accumulate_result(test, (INTERRUPTED, None)) self.interrupted = True break else: self.accumulate_result(test, result) test_time = time.monotonic() - start_time if test_time >= PROGRESS_MIN_TIME: previous_test = '%s took %.0f sec' % (test, test_time) else: previous_test = None if self.ns.findleaks: gc.collect() if gc.garbage: print("Warning: test created", len(gc.garbage), end=' ') print("uncollectable object(s).") # move the uncollectable objects somewhere so we don't see # them again self.found_garbage.extend(gc.garbage) del gc.garbage[:] # Unload the newly imported modules (best effort finalization) for module in sys.modules.keys(): if module not in save_modules and module.startswith("test."): support.unload(module) if previous_test: print(previous_test)
def tearDown(self): sys.path[:] = self.sys_path if self.orig_module is not None: sys.modules[self.module_name] = self.orig_module else: unload(self.module_name) unlink(self.file_name) unlink(self.compiled_name) rmtree(self.dir_name)
def test_recompute_pyc_same_second(self): # Even when the source file doesn't change timestamp, a change in # source size is enough to trigger recomputation of the pyc file. __import__(TESTFN) unload(TESTFN) with open(self.source, 'a') as fp: print("x = 5", file=fp) m = __import__(TESTFN) self.assertEqual(m.x, 5)
def test_stacklevel_import(self): # Issue #24305: With stacklevel=2, module-level warnings should work. support.unload('test.test_warnings.data.import_warning') with warnings_state(self.module): with original_warnings.catch_warnings(record=True, module=self.module) as w: self.module.simplefilter('always') import test.test_warnings.data.import_warning self.assertEqual(len(w), 1) self.assertEqual(w[0].filename, __file__)
def tearDown(self): # Get everything back to normal support.unload('xx') sys.path = self.sys_path[0] sys.path[:] = self.sys_path[1] import site site.USER_BASE = self.old_user_base from distutils.command import build_ext build_ext.USER_BASE = self.old_user_base super(BuildExtTestCase, self).tearDown()
def test___cached___legacy_pyc(self): # Like test___cached__() except that for backward compatibility, # when the pyc file lives where the py file would have been (and named # without the tag), it is importable. The __cached__ of the imported # module is the pyc location. __import__(TESTFN) # pyc_file gets removed in _clean() via tearDown(). pyc_file = make_legacy_pyc(self.source) os.remove(self.source) unload(TESTFN) m = __import__(TESTFN) self.assertEqual(m.__cached__, os.path.join(os.curdir, os.path.relpath(pyc_file)))
def _test_UNC_path(self): with open(os.path.join(self.path, 'test_trailing_slash.py'), 'w') as f: f.write("testdata = 'test_trailing_slash'") # Create the UNC path, like \\myhost\c$\foo\bar. path = os.path.abspath(self.path) import socket hn = socket.gethostname() drive = path[0] unc = "\\\\%s\\%s$" % (hn, drive) unc += path[2:] sys.path.append(path) mod = __import__("test_trailing_slash") self.assertEqual(mod.testdata, 'test_trailing_slash') unload("test_trailing_slash")
def test_package___cached___from_pyc(self): # Like test___cached__ but ensuring __cached__ when imported from a # PEP 3147 pyc file. def cleanup(): rmtree('pep3147') os.mkdir('pep3147') self.addCleanup(cleanup) unload('pep3147.foo') unload('pep3147') # Touch the __init__.py with open(os.path.join('pep3147', '__init__.py'), 'w'): pass with open(os.path.join('pep3147', 'foo.py'), 'w'): pass m = __import__('pep3147.foo') unload('pep3147.foo') unload('pep3147') m = __import__('pep3147.foo') init_pyc = imp.cache_from_source(os.path.join('pep3147', '__init__.py')) self.assertEqual(m.__cached__, os.path.join(os.curdir, init_pyc)) foo_pyc = imp.cache_from_source(os.path.join('pep3147', 'foo.py')) self.assertEqual(sys.modules['pep3147.foo'].__cached__, os.path.join(os.curdir, foo_pyc))
def test___cached___legacy_pyc(self): # Like test___cached__() except that for backward compatibility, # when the pyc file lives where the py file would have been (and named # without the tag), it is importable. The __cached__ of the imported # module is the pyc location. __import__(TESTFN) # pyc_file gets removed in _clean() via tearDown(). pyc_file = make_legacy_pyc(self.source) os.remove(self.source) unload(TESTFN) importlib.invalidate_caches() m = __import__(TESTFN) self.assertEqual(m.__cached__, os.path.join(os.curdir, os.path.relpath(pyc_file)))
def _test_UNC_path(self): with open(os.path.join(self.path, 'test_trailing_slash.py'), 'w') as f: f.write("testdata = 'test_trailing_slash'") # Create the UNC path, like \\myhost\c$\foo\bar. path = os.path.abspath(self.path) import socket hn = socket.gethostname() drive = path[0] unc = "\\\\%s\\%s$"%(hn, drive) unc += path[2:] sys.path.append(path) mod = __import__("test_trailing_slash") self.assertEqual(mod.testdata, 'test_trailing_slash') unload("test_trailing_slash")
def _check_module(self, depth, alter_sys=False, *, namespace=False, parent_namespaces=False): pkg_dir, mod_fname, mod_name, mod_spec = self._make_pkg( example_source, depth, namespace=namespace, parent_namespaces=parent_namespaces) forget(mod_name) expected_ns = example_namespace.copy() expected_ns.update({ '__name__': mod_name, '__file__': mod_fname, '__cached__': mod_spec.cached, '__package__': mod_name.rpartition('.')[0], '__spec__': mod_spec }) if alter_sys: expected_ns.update({ 'run_argv0': mod_fname, 'run_name_in_sys_modules': True, 'module_in_sys_modules': True }) def create_ns(init_globals): return run_module(mod_name, init_globals, alter_sys=alter_sys) try: if verbose > 1: print('Running from source:', mod_name) self.check_code_execution(create_ns, expected_ns) importlib.invalidate_caches() __import__(mod_name) os.remove(mod_fname) if not sys.dont_write_bytecode: make_legacy_pyc(mod_fname) unload(mod_name) importlib.invalidate_caches() if verbose > 1: print('Running from compiled:', mod_name) self._fix_ns_for_legacy_pyc(expected_ns, alter_sys) self.check_code_execution(create_ns, expected_ns) finally: self._del_pkg(pkg_dir) if verbose > 1: print('Module executed successfully')
def run_tests_sequential(self): if self.ns.trace: import trace self.tracer = trace.Trace(trace=False, count=True) save_modules = sys.modules.keys() print("Run tests sequentially") previous_test = None for test_index, test_name in enumerate(self.tests, 1): start_time = time.monotonic() text = test_name if previous_test: text = '%s -- %s' % (text, previous_test) self.display_progress(test_index, text) if self.tracer: # If we're tracing code coverage, then we don't exit with status # if on a false return value from main. cmd = ('result = runtest(self.ns, test_name); ' 'self.accumulate_result(result)') ns = dict(locals()) self.tracer.runctx(cmd, globals=globals(), locals=ns) result = ns['result'] else: result = runtest(self.ns, test_name) self.accumulate_result(result) if result.result == INTERRUPTED: break previous_test = format_test_result(result) test_time = time.monotonic() - start_time if test_time >= PROGRESS_MIN_TIME: previous_test = "%s in %s" % (previous_test, format_duration(test_time)) elif result[0] == PASSED: # be quiet: say nothing if the test passed shortly previous_test = None # Unload the newly imported modules (best effort finalization) for module in sys.modules.keys(): if module not in save_modules and module.startswith("test."): support.unload(module) if previous_test: print(previous_test)
def test_module_not_package_but_side_effects(self): name = 'mod' subname = name + '.b' def module_injection(): sys.modules[subname] = 'total bunk' mock_spec = util.mock_spec('mod', module_code={'mod': module_injection}) with mock_spec as mock: with util.import_state(meta_path=[mock]): try: submodule = self.__import__(subname) finally: support.unload(subname)
def test_module_not_package_but_side_effects(self): # If a module injects something into sys.modules as a side-effect, then # pick up on that fact. name = 'mod' subname = name + '.b' def module_injection(): sys.modules[subname] = 'total bunk' mock_spec = util.mock_spec('mod', module_code={'mod': module_injection}) with mock_spec as mock: with util.import_state(meta_path=[mock]): try: submodule = self.__import__(subname) finally: support.unload(subname)
def test_module_not_package_but_side_effects(self): # If a module injects something into sys.modules as a side-effect, then # pick up on that fact. name = 'mod' subname = name + '.b' def module_injection(): sys.modules[subname] = 'total bunk' mock_modules = util.mock_modules('mod', module_code={'mod': module_injection}) with mock_modules as mock: with util.import_state(meta_path=[mock]): try: submodule = import_util.import_(subname) finally: support.unload(subname)
def run_tests_sequential(self): if self.ns.trace: import trace self.tracer = trace.Trace(trace=False, count=True) save_modules = sys.modules.keys() print('Run tests sequentially') previous_test = None for test_index, test in enumerate(self.tests, 1): start_time = time.monotonic() text = test if previous_test: text = '%s -- %s' % (text, previous_test) self.display_progress(test_index, text) if self.tracer: cmd = ( 'result = runtest(self.ns, test); self.accumulate_result(test, result)' ) ns = dict(locals()) self.tracer.runctx(cmd, globals=globals(), locals=ns) result = ns['result'] else: try: result = runtest(self.ns, test) except KeyboardInterrupt: self.interrupted = True self.accumulate_result(test, (INTERRUPTED, None)) break else: self.accumulate_result(test, result) previous_test = format_test_result(test, result[0]) test_time = time.monotonic() - start_time if test_time >= PROGRESS_MIN_TIME: previous_test = '%s in %s' % (previous_test, format_duration(test_time)) elif result[0] == PASSED: previous_test = None if self.ns.findleaks: gc.collect() if gc.garbage: print('Warning: test created', len(gc.garbage), end=' ') print('uncollectable object(s).') self.found_garbage.extend(gc.garbage) del gc.garbage[:] for module in sys.modules.keys(): if module not in save_modules and module.startswith('test.'): support.unload(module) if previous_test: print(previous_test)
def test_module_not_package_but_side_effects(self): # If a module injects something into sys.modules as a side-effect, then # pick up on that fact. name = "mod" subname = name + ".b" def module_injection(): sys.modules[subname] = "total bunk" mock_modules = util.mock_modules("mod", module_code={"mod": module_injection}) with mock_modules as mock: with util.import_state(meta_path=[mock]): try: submodule = import_util.import_(subname) finally: support.unload(subname)
def _runtest_inner2(ns, test_name): # Load the test function, run the test function, handle huntrleaks # and findleaks to detect leaks abstest = get_abs_module(ns, test_name) # remove the module from sys.module to reload it if it was already imported support.unload(abstest) the_module = importlib.import_module(abstest) # If the test has a test_main, that will run the appropriate # tests. If not, use normal unittest test loading. test_runner = getattr(the_module, "test_main", None) if test_runner is None: test_runner = functools.partial(_test_module, the_module) try: if ns.huntrleaks: # Return True if the test leaked references refleak = dash_R(ns, test_name, test_runner) else: test_runner() refleak = False finally: cleanup_test_droppings(test_name, ns.verbose) if ns.findleaks: import gc support.gc_collect() if gc.garbage: import gc gc.garbage = [1] print_warning(f"{test_name} created {len(gc.garbage)} " f"uncollectable object(s).") # move the uncollectable objects somewhere, # so we don't see them again found_garbage.extend(gc.garbage) gc.garbage.clear() support.environment_altered = True post_test_cleanup() return refleak
def test_UNC_path(self): with open(os.path.join(self.path, "test_trailing_slash.py"), "w") as f: f.write("testdata = 'test_trailing_slash'") importlib.invalidate_caches() # Create the UNC path, like \\myhost\c$\foo\bar. path = os.path.abspath(self.path) import socket hn = socket.gethostname() drive = path[0] unc = "\\\\%s\\%s$" % (hn, drive) unc += path[2:] sys.path.append(unc) try: mod = __import__("test_trailing_slash") self.assertEqual(mod.testdata, "test_trailing_slash") unload("test_trailing_slash") finally: sys.path.remove(unc)
def _check_relative_imports(self, depth, run_name=None): contents = """\\ from __future__ import absolute_import from . import sibling from ..uncle.cousin import nephew """ pkg_dir, mod_fname, mod_name, mod_spec = self._make_pkg( contents, depth) if run_name is None: expected_name = mod_name else: expected_name = run_name try: self._add_relative_modules(pkg_dir, contents, depth) pkg_name = mod_name.rpartition('.')[0] if verbose > 1: print('Running from source:', mod_name) d1 = run_module(mod_name, run_name=run_name) self.assertEqual(d1['__name__'], expected_name) self.assertEqual(d1['__package__'], pkg_name) self.assertIn('sibling', d1) self.assertIn('nephew', d1) del d1 importlib.invalidate_caches() __import__(mod_name) os.remove(mod_fname) if not sys.dont_write_bytecode: make_legacy_pyc(mod_fname) unload(mod_name) if verbose > 1: print('Running from compiled:', mod_name) importlib.invalidate_caches() d2 = run_module(mod_name, run_name=run_name) self.assertEqual(d2['__name__'], expected_name) self.assertEqual(d2['__package__'], pkg_name) self.assertIn('sibling', d2) self.assertIn('nephew', d2) del d2 finally: self._del_pkg(pkg_dir) if verbose > 1: print('Module executed successfully')
def test_package___cached__(self): # Like test___cached__ but for packages. def cleanup(): rmtree('pep3147') os.mkdir('pep3147') self.addCleanup(cleanup) # Touch the __init__.py with open(os.path.join('pep3147', '__init__.py'), 'w'): pass with open(os.path.join('pep3147', 'foo.py'), 'w'): pass unload('pep3147.foo') unload('pep3147') m = __import__('pep3147.foo') init_pyc = imp.cache_from_source( os.path.join('pep3147', '__init__.py')) self.assertEqual(m.__cached__, os.path.join(os.curdir, init_pyc)) foo_pyc = imp.cache_from_source(os.path.join('pep3147', 'foo.py')) self.assertEqual(sys.modules['pep3147.foo'].__cached__, os.path.join(os.curdir, foo_pyc))
def test_file_parse(self): unload(TESTFN) filename = TESTFN + '.py' f = open(filename, 'w', encoding='cp1252') sys.path.insert(0, os.curdir) try: with f: f.write('# -*- coding: cp1252 -*-\n') f.write("'''A short string\n") f.write("'''\n") f.write("'A very long string %s'\n" % ('X' * 1000)) importlib.invalidate_caches() __import__(TESTFN) finally: del sys.path[0] unlink(filename) unlink(filename + 'c') unlink(filename + 'o') unload(TESTFN) rmtree('__pycache__')
def _check_relative_imports(self, depth, run_name=None): contents = r"""\ from __future__ import absolute_import from . import sibling from ..uncle.cousin import nephew """ pkg_dir, mod_fname, mod_name, mod_spec = self._make_pkg(contents, depth) if run_name is None: expected_name = mod_name else: expected_name = run_name try: self._add_relative_modules(pkg_dir, contents, depth) pkg_name = mod_name.rpartition(".")[0] if verbose > 1: print("Running from source:", mod_name) d1 = run_module(mod_name, run_name=run_name) # Read from source self.assertEqual(d1["__name__"], expected_name) self.assertEqual(d1["__package__"], pkg_name) self.assertIn("sibling", d1) self.assertIn("nephew", d1) del d1 # Ensure __loader__ entry doesn't keep file open importlib.invalidate_caches() __import__(mod_name) os.remove(mod_fname) if not sys.dont_write_bytecode: make_legacy_pyc(mod_fname) unload(mod_name) # In case the loader caches paths if verbose > 1: print("Running from compiled:", mod_name) importlib.invalidate_caches() d2 = run_module(mod_name, run_name=run_name) # Read from bytecode self.assertEqual(d2["__name__"], expected_name) self.assertEqual(d2["__package__"], pkg_name) self.assertIn("sibling", d2) self.assertIn("nephew", d2) del d2 # Ensure __loader__ entry doesn't keep file open finally: self._del_pkg(pkg_dir) if verbose > 1: print("Module executed successfully")
def _check_module(self, depth): pkg_dir, mod_fname, mod_name = (self._make_pkg("x=1\n", depth)) forget(mod_name) try: if verbose: print("Running from source:", mod_name) d1 = run_module(mod_name) # Read from source self.assertIn("x", d1) self.assertEqual(d1["x"], 1) del d1 # Ensure __loader__ entry doesn't keep file open __import__(mod_name) os.remove(mod_fname) make_legacy_pyc(mod_fname) unload(mod_name) # In case loader caches paths if verbose: print("Running from compiled:", mod_name) d2 = run_module(mod_name) # Read from bytecode self.assertIn("x", d2) self.assertEqual(d2["x"], 1) del d2 # Ensure __loader__ entry doesn't keep file open finally: self._del_pkg(pkg_dir, depth, mod_name) if verbose: print("Module executed successfully")
def test_creation_mode(self): mask = 0o022 with temp_umask(mask): sys.path.insert(0, os.curdir) try: fname = TESTFN + os.extsep + "py" create_empty_file(fname) fn = imp.cache_from_source(fname) unlink(fn) importlib.invalidate_caches() __import__(TESTFN) if not os.path.exists(fn): self.fail("__import__ did not result in creation of " "either a .pyc or .pyo file") s = os.stat(fn) # Check that the umask is respected, and the executable bits # aren't set. self.assertEqual(stat.S_IMODE(s.st_mode), 0o666 & ~mask) finally: del sys.path[0] remove_files(TESTFN) unload(TESTFN)
def _test_UNC_path(self): with open(os.path.join(self.path, 'test_trailing_slash.py'), 'w') as f: f.write("testdata = 'test_trailing_slash'") # Create the UNC path, like \\myhost\c$\foo\bar. path = os.path.abspath(self.path) import socket hn = socket.gethostname() drive = path[0] unc = "\\\\%s\\%s$"%(hn, drive) unc += path[2:] try: os.listdir(unc) except OSError as e: if e.errno in (errno.EPERM, errno.EACCES): # See issue #15338 self.skipTest("cannot access administrative share %r" % (unc,)) raise sys.path.append(path) mod = __import__("test_trailing_slash") self.assertEqual(mod.testdata, 'test_trailing_slash') unload("test_trailing_slash")
def test_file_parse(self): # issue1134: all encodings outside latin-1 and utf-8 fail on # multiline strings and long lines (>512 columns) unload(TESTFN) sys.path.insert(0, os.curdir) filename = TESTFN + ".py" f = open(filename, "w") try: f.write("# -*- coding: cp1252 -*-\n") f.write("'''A short string\n") f.write("'''\n") f.write("'A very long string %s'\n" % ("X" * 1000)) f.close() __import__(TESTFN) finally: f.close() unlink(filename) unlink(filename + "c") unload(TESTFN) del sys.path[0]
def test_rewrite_pyc_with_read_only_source(self): # Issue 6074: a long time ago on posix, and more recently on Windows, # a read only source file resulted in a read only pyc file, which # led to problems with updating it later sys.path.insert(0, os.curdir) fname = TESTFN + os.extsep + "py" try: # Write a Python file, make it read-only and import it with open(fname, 'w') as f: f.write("x = 'original'\n") # Tweak the mtime of the source to ensure pyc gets updated later s = os.stat(fname) os.utime(fname, (s.st_atime, s.st_mtime-100000000)) os.chmod(fname, 0o400) m1 = __import__(TESTFN) self.assertEqual(m1.x, 'original') # Change the file and then reimport it os.chmod(fname, 0o600) with open(fname, 'w') as f: f.write("x = 'rewritten'\n") unload(TESTFN) m2 = __import__(TESTFN) self.assertEqual(m2.x, 'rewritten') # Now delete the source file and check the pyc was rewritten unlink(fname) unload(TESTFN) m3 = __import__(TESTFN) self.assertEqual(m3.x, 'rewritten') finally: chmod_files(TESTFN) remove_files(TESTFN) unload(TESTFN) del sys.path[0]
def test_failing_reload(self): # A failing reload should leave the module object in sys.modules. source = TESTFN + os.extsep + "py" with open(source, "w") as f: print("a = 1", file=f) print("b = 2", file=f) sys.path.insert(0, os.curdir) try: mod = __import__(TESTFN) self.assertIn(TESTFN, sys.modules) self.assertEqual(mod.a, 1, "module has wrong attribute values") self.assertEqual(mod.b, 2, "module has wrong attribute values") # On WinXP, just replacing the .py file wasn't enough to # convince reload() to reparse it. Maybe the timestamp didn't # move enough. We force it to get reparsed by removing the # compiled file too. remove_files(TESTFN) # Now damage the module. with open(source, "w") as f: print("a = 10", file=f) print("b = 20//0", file=f) self.assertRaises(ZeroDivisionError, imp.reload, mod) # But we still expect the module to be in sys.modules. mod = sys.modules.get(TESTFN) self.assertIsNot(mod, None, "expected module to be in sys.modules") # We should have replaced a w/ 10, but the old b value should # stick. self.assertEqual(mod.a, 10, "module has wrong attribute values") self.assertEqual(mod.b, 2, "module has wrong attribute values") finally: del sys.path[0] remove_files(TESTFN) unload(TESTFN)
def test_rewrite_pyc_with_read_only_source(self): # Issue 6074: a long time ago on posix, and more recently on Windows, # a read only source file resulted in a read only pyc file, which # led to problems with updating it later sys.path.insert(0, os.curdir) fname = TESTFN + os.extsep + "py" try: # Write a Python file, make it read-only and import it with open(fname, 'w') as f: f.write("x = 'original'\n") # Tweak the mtime of the source to ensure pyc gets updated later s = os.stat(fname) os.utime(fname, (s.st_atime, s.st_mtime - 100000000)) os.chmod(fname, 0o400) m1 = __import__(TESTFN) self.assertEqual(m1.x, 'original') # Change the file and then reimport it os.chmod(fname, 0o600) with open(fname, 'w') as f: f.write("x = 'rewritten'\n") unload(TESTFN) m2 = __import__(TESTFN) self.assertEqual(m2.x, 'rewritten') # Now delete the source file and check the pyc was rewritten unlink(fname) unload(TESTFN) m3 = __import__(TESTFN) self.assertEqual(m3.x, 'rewritten') finally: chmod_files(TESTFN) remove_files(TESTFN) unload(TESTFN) del sys.path[0]
def _check_module(self, depth, alter_sys=False, *, namespace=False, parent_namespaces=False): pkg_dir, mod_fname, mod_name, mod_spec = self._make_pkg( example_source, depth, namespace=namespace, parent_namespaces=parent_namespaces ) forget(mod_name) expected_ns = example_namespace.copy() expected_ns.update( { "__name__": mod_name, "__file__": mod_fname, "__cached__": mod_spec.cached, "__package__": mod_name.rpartition(".")[0], "__spec__": mod_spec, } ) if alter_sys: expected_ns.update({"run_argv0": mod_fname, "run_name_in_sys_modules": True, "module_in_sys_modules": True}) def create_ns(init_globals): return run_module(mod_name, init_globals, alter_sys=alter_sys) try: if verbose > 1: print("Running from source:", mod_name) self.check_code_execution(create_ns, expected_ns) importlib.invalidate_caches() __import__(mod_name) os.remove(mod_fname) if not sys.dont_write_bytecode: make_legacy_pyc(mod_fname) unload(mod_name) # In case loader caches paths importlib.invalidate_caches() if verbose > 1: print("Running from compiled:", mod_name) self._fix_ns_for_legacy_pyc(expected_ns, alter_sys) self.check_code_execution(create_ns, expected_ns) finally: self._del_pkg(pkg_dir) if verbose > 1: print("Module executed successfully")
def _check_relative_imports(self, depth, run_name=None): contents = r"""\ from __future__ import absolute_import from . import sibling from ..uncle.cousin import nephew """ pkg_dir, mod_fname, mod_name, mod_spec = (self._make_pkg( contents, depth)) if run_name is None: expected_name = mod_name else: expected_name = run_name try: self._add_relative_modules(pkg_dir, contents, depth) pkg_name = mod_name.rpartition('.')[0] if verbose > 1: print("Running from source:", mod_name) d1 = run_module(mod_name, run_name=run_name) # Read from source self.assertEqual(d1["__name__"], expected_name) self.assertEqual(d1["__package__"], pkg_name) self.assertIn("sibling", d1) self.assertIn("nephew", d1) del d1 # Ensure __loader__ entry doesn't keep file open importlib.invalidate_caches() __import__(mod_name) os.remove(mod_fname) if not sys.dont_write_bytecode: make_legacy_pyc(mod_fname) unload(mod_name) # In case the loader caches paths if verbose > 1: print("Running from compiled:", mod_name) importlib.invalidate_caches() d2 = run_module(mod_name, run_name=run_name) # Read from bytecode self.assertEqual(d2["__name__"], expected_name) self.assertEqual(d2["__package__"], pkg_name) self.assertIn("sibling", d2) self.assertIn("nephew", d2) del d2 # Ensure __loader__ entry doesn't keep file open finally: self._del_pkg(pkg_dir) if verbose > 1: print("Module executed successfully")
def _check_package(self, depth, alter_sys=False, *, namespace=False, parent_namespaces=False): pkg_dir, mod_fname, mod_name, mod_spec = ( self._make_pkg(example_source, depth, "__main__", namespace=namespace, parent_namespaces=parent_namespaces)) pkg_name = mod_name.rpartition(".")[0] forget(mod_name) expected_ns = example_namespace.copy() expected_ns.update({ "__name__": mod_name, "__file__": mod_fname, "__cached__": importlib.util.cache_from_source(mod_fname), "__package__": pkg_name, "__spec__": mod_spec, }) if alter_sys: expected_ns.update({ "run_argv0": mod_fname, "run_name_in_sys_modules": True, "module_in_sys_modules": True, }) def create_ns(init_globals): return run_module(pkg_name, init_globals, alter_sys=alter_sys) try: if verbose > 1: print("Running from source:", pkg_name) self.check_code_execution(create_ns, expected_ns) importlib.invalidate_caches() __import__(mod_name) os.remove(mod_fname) if not sys.dont_write_bytecode: make_legacy_pyc(mod_fname) unload(mod_name) # In case loader caches paths if verbose > 1: print("Running from compiled:", pkg_name) importlib.invalidate_caches() self._fix_ns_for_legacy_pyc(expected_ns, alter_sys) self.check_code_execution(create_ns, expected_ns) finally: self._del_pkg(pkg_dir) if verbose > 1: print("Package executed successfully")
def run_tests_sequential(self): if self.ns.trace: import trace self.tracer = trace.Trace(trace=False, count=True) save_modules = sys.modules.keys() for test_index, test in enumerate(self.tests, 1): self.display_progress(test_index, test) if self.tracer: # If we're tracing code coverage, then we don't exit with status # if on a false return value from main. cmd = ('result = runtest(self.ns, test); ' 'self.accumulate_result(test, result)') self.tracer.runctx(cmd, globals=globals(), locals=vars()) else: try: result = runtest(self.ns, test) except KeyboardInterrupt: self.accumulate_result(test, (INTERRUPTED, None)) self.interrupted = True break else: self.accumulate_result(test, result) if self.ns.findleaks: gc.collect() if gc.garbage: print("Warning: test created", len(gc.garbage), end=' ') print("uncollectable object(s).") # move the uncollectable objects somewhere so we don't see # them again self.found_garbage.extend(gc.garbage) del gc.garbage[:] # Unload the newly imported modules (best effort finalization) for module in sys.modules.keys(): if module not in save_modules and module.startswith("test."): support.unload(module)
def test_failing_reload(self): source = TESTFN + os.extsep + 'py' with open(source, 'w') as f: f.write('a = 1\nb=2\n') sys.path.insert(0, os.curdir) try: mod = __import__(TESTFN) self.assertIn(TESTFN, sys.modules) self.assertEqual(mod.a, 1, 'module has wrong attribute values') self.assertEqual(mod.b, 2, 'module has wrong attribute values') remove_files(TESTFN) with open(source, 'w') as f: f.write('a = 10\nb=20//0\n') self.assertRaises(ZeroDivisionError, importlib.reload, mod) mod = sys.modules.get(TESTFN) self.assertIsNotNone(mod, 'expected module to be in sys.modules') self.assertEqual(mod.a, 10, 'module has wrong attribute values') self.assertEqual(mod.b, 2, 'module has wrong attribute values') finally: del sys.path[0] remove_files(TESTFN) unload(TESTFN)
def test_with_extension(ext): # The extension is normally ".py", perhaps ".pyw". source = TESTFN + ext pyo = TESTFN + os.extsep + "pyo" if is_jython: pyc = TESTFN + "$py.class" else: pyc = TESTFN + os.extsep + "pyc" with open(source, "w") as f: print(("# This tests Python's ability to import a", ext, "file."), file=f) a = random.randrange(1000) b = random.randrange(1000) print("a =", a, file=f) print("b =", b, file=f) try: mod = __import__(TESTFN) except ImportError as err: self.fail("import from %s failed: %s" % (ext, err)) else: self.assertEqual( mod.a, a, "module loaded (%s) but contents invalid" % mod) self.assertEqual( mod.b, b, "module loaded (%s) but contents invalid" % mod) finally: unlink(source) try: imp.reload(mod) except ImportError as err: self.fail("import from .pyc/.pyo failed: %s" % err) finally: unlink(pyc) unlink(pyo) unload(TESTFN)
def test_file_parse(self): # issue1134: all encodings outside latin-1 and utf-8 fail on # multiline strings and long lines (>512 columns) unload(TESTFN) filename = TESTFN + ".py" f = open(filename, "w", encoding="cp1252") sys.path.insert(0, os.curdir) try: with f: f.write("# -*- coding: cp1252 -*-\n") f.write("'''A short string\n") f.write("'''\n") f.write("'A very long string %s'\n" % ("X" * 1000)) importlib.invalidate_caches() __import__(TESTFN) finally: del sys.path[0] unlink(filename) unlink(filename + "c") unlink(filename + "o") unload(TESTFN) rmtree('__pycache__')
def test_pyc_always_writable(self): with _ready_to_import() as (name, path): with open(path, 'w') as f: f.write("x = 'original'\n") s = os.stat(path) os.utime(path, (s.st_atime, s.st_mtime - 100000000)) os.chmod(path, 256) m = __import__(name) self.assertEqual(m.x, 'original') os.chmod(path, 384) with open(path, 'w') as f: f.write("x = 'rewritten'\n") unload(name) importlib.invalidate_caches() m = __import__(name) self.assertEqual(m.x, 'rewritten') unlink(path) unload(name) importlib.invalidate_caches() bytecode_only = path + 'c' os.rename(importlib.util.cache_from_source(path), bytecode_only) m = __import__(name) self.assertEqual(m.x, 'rewritten')
def test_execute_bit_not_copied(self): # Issue 6070: under posix .pyc files got their execute bit set if # the .py file had the execute bit set, but they aren't executable. with temp_umask(0o022): sys.path.insert(0, os.curdir) try: fname = TESTFN + os.extsep + "py" open(fname, 'w').close() os.chmod(fname, (stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)) fn = imp.cache_from_source(fname) unlink(fn) __import__(TESTFN) if not os.path.exists(fn): self.fail("__import__ did not result in creation of " "either a .pyc or .pyo file") s = os.stat(fn) self.assertEqual(stat.S_IMODE(s.st_mode), stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH) finally: del sys.path[0] remove_files(TESTFN) unload(TESTFN)
def test_unload(self): import sched self.assertIn("sched", sys.modules) support.unload("sched") self.assertNotIn("sched", sys.modules)
def testBlocker(self): mname = "exceptions" # an arbitrary harmless builtin module support.unload(mname) sys.meta_path.append(ImportBlocker(mname)) self.assertRaises(ImportError, __import__, mname)
def runtest_inner(ns, test, display_failure=True): support.unload(test) test_time = 0.0 refleak = False # True if the test leaked references. try: abstest = get_abs_module(ns, test) clear_caches() with saved_test_environment(test, ns.verbose, ns.quiet, pgo=ns.pgo) as environment: start_time = time.time() the_module = importlib.import_module(abstest) # If the test has a test_main, that will run the appropriate # tests. If not, use normal unittest test loading. test_runner = getattr(the_module, "test_main", None) if test_runner is None: def test_runner(): loader = unittest.TestLoader() tests = loader.loadTestsFromModule(the_module) for error in loader.errors: print(error, file=sys.stderr) if loader.errors: raise Exception("errors while loading tests") support.run_unittest(tests) test_runner() if ns.huntrleaks: refleak = dash_R(the_module, test, test_runner, ns.huntrleaks) test_time = time.time() - start_time post_test_cleanup() except support.ResourceDenied as msg: if not ns.quiet and not ns.pgo: print(test, "skipped --", msg, flush=True) return RESOURCE_DENIED, test_time except unittest.SkipTest as msg: if not ns.quiet and not ns.pgo: print(test, "skipped --", msg, flush=True) return SKIPPED, test_time except KeyboardInterrupt: raise except support.TestFailed as msg: if not ns.pgo: if display_failure: print("test", test, "failed --", msg, file=sys.stderr, flush=True) else: print("test", test, "failed", file=sys.stderr, flush=True) return FAILED, test_time except: msg = traceback.format_exc() if not ns.pgo: print("test", test, "crashed --", msg, file=sys.stderr, flush=True) return FAILED, test_time else: if refleak: return FAILED, test_time if environment.changed: return ENV_CHANGED, test_time return PASSED, test_time
def cleanup(): rmtree('pep3147') unload('pep3147.foo') unload('pep3147')
def tearDown(self): unload("test.relimport")