aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Lib/test/test_runpy.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/test/test_runpy.py')
-rw-r--r--Lib/test/test_runpy.py137
1 files changed, 104 insertions, 33 deletions
diff --git a/Lib/test/test_runpy.py b/Lib/test/test_runpy.py
index 868662d10bb..d10e40fc8d2 100644
--- a/Lib/test/test_runpy.py
+++ b/Lib/test/test_runpy.py
@@ -21,12 +21,12 @@ class RunModuleCodeTest(unittest.TestCase):
"# Check the sys module\n"
"import sys\n"
"run_argv0 = sys.argv[0]\n"
- "if __name__ in sys.modules:\n"
- " run_name = sys.modules[__name__].__name__\n"
+ "run_name_in_sys_modules = __name__ in sys.modules\n"
+ "if run_name_in_sys_modules:\n"
+ " module_in_sys_modules = globals() is sys.modules[__name__].__dict__\n"
"# Check nested operation\n"
"import runpy\n"
- "nested = runpy._run_module_code('x=1\\n', mod_name='<run>',\n"
- " alter_sys=True)\n"
+ "nested = runpy._run_module_code('x=1\\n', mod_name='<run>')\n"
)
@@ -37,34 +37,44 @@ class RunModuleCodeTest(unittest.TestCase):
loader = "Now you're just being silly"
d1 = dict(initial=initial)
saved_argv0 = sys.argv[0]
- d2 = _run_module_code(self.test_source,
- d1,
- name,
- file,
- loader,
- True)
- self.failUnless("result" not in d1)
- self.failUnless(d2["initial"] is initial)
- self.assertEqual(d2["result"], self.expected_result)
- self.assertEqual(d2["nested"]["x"], 1)
- self.failUnless(d2["__name__"] is name)
- self.failUnless(d2["run_name"] is name)
- self.failUnless(d2["__file__"] is file)
- self.failUnless(d2["run_argv0"] is file)
- self.failUnless(d2["__loader__"] is loader)
- self.failUnless(sys.argv[0] is saved_argv0)
- self.failUnless(name not in sys.modules)
+ try:
+ d2 = _run_module_code(self.test_source,
+ d1,
+ name,
+ file,
+ loader,
+ alter_sys=True)
+ self.failUnless("result" not in d1)
+ self.failUnless(d2["initial"] is initial)
+ self.assertEqual(d2["result"], self.expected_result)
+ self.assertEqual(d2["nested"]["x"], 1)
+ self.assertEqual(d2["nested"]["__name__"], "<run>")
+ self.failUnless(d2["__name__"] is name)
+ self.failUnless(d2["__file__"] is file)
+ self.failUnless(d2["__loader__"] is loader)
+ self.failUnless(d2["run_argv0"] is file)
+ self.failUnless(d2["run_name_in_sys_modules"])
+ self.failUnless(d2["module_in_sys_modules"])
+ self.failUnless(sys.argv[0] is not saved_argv0)
+ self.failUnless(name in sys.modules)
+ finally:
+ sys.argv[0] = saved_argv0
+ if name in sys.modules:
+ del sys.modules[name]
def test_run_module_code_defaults(self):
saved_argv0 = sys.argv[0]
d = _run_module_code(self.test_source)
self.assertEqual(d["result"], self.expected_result)
+ self.failUnless(d["nested"]["x"] == 1)
+ self.failUnless(d["nested"]["__name__"] == "<run>")
self.failUnless(d["__name__"] is None)
self.failUnless(d["__file__"] is None)
self.failUnless(d["__loader__"] is None)
self.failUnless(d["run_argv0"] is saved_argv0)
- self.failUnless("run_name" not in d)
+ self.failUnless(not d["run_name_in_sys_modules"])
self.failUnless(sys.argv[0] is saved_argv0)
+ self.failUnless(None not in sys.modules)
class RunModuleTest(unittest.TestCase):
@@ -77,19 +87,29 @@ class RunModuleTest(unittest.TestCase):
self.fail("Expected import error for " + mod_name)
def test_invalid_names(self):
+ # Builtin module
self.expect_import_error("sys")
+ # Non-existent modules
self.expect_import_error("sys.imp.eric")
self.expect_import_error("os.path.half")
self.expect_import_error("a.bee")
self.expect_import_error(".howard")
self.expect_import_error("..eaten")
+ # Package
+ self.expect_import_error("logging")
def test_library_module(self):
run_module("runpy")
+ def _add_pkg_dir(self, pkg_dir):
+ os.mkdir(pkg_dir)
+ pkg_fname = os.path.join(pkg_dir, "__init__"+os.extsep+"py")
+ pkg_file = open(pkg_fname, "w")
+ pkg_file.close()
+ return pkg_fname
+
def _make_pkg(self, source, depth):
pkg_name = "__runpy_pkg__"
- init_fname = "__init__"+os.extsep+"py"
test_fname = "runpy_test"+os.extsep+"py"
pkg_dir = sub_dir = tempfile.mkdtemp()
if verbose: print(" Package tree in:", sub_dir)
@@ -97,11 +117,8 @@ class RunModuleTest(unittest.TestCase):
if verbose: print(" Updated sys.path:", sys.path[0])
for i in range(depth):
sub_dir = os.path.join(sub_dir, pkg_name)
- os.mkdir(sub_dir)
+ pkg_fname = self._add_pkg_dir(sub_dir)
if verbose: print(" Next level in:", sub_dir)
- pkg_fname = os.path.join(sub_dir, init_fname)
- pkg_file = open(pkg_fname, "w")
- pkg_file.close()
if verbose: print(" Created:", pkg_fname)
mod_fname = os.path.join(sub_dir, test_fname)
mod_file = open(mod_fname, "w")
@@ -112,13 +129,9 @@ class RunModuleTest(unittest.TestCase):
return pkg_dir, mod_fname, mod_name
def _del_pkg(self, top, depth, mod_name):
- for i in range(depth+1): # Don't forget the module itself
- parts = mod_name.rsplit(".", i)
- entry = parts[0]
- try:
+ for entry in list(sys.modules):
+ if entry.startswith("__runpy_pkg__"):
del sys.modules[entry]
- except KeyError as ex:
- if verbose: print(ex) # Persist with cleaning up
if verbose: print(" Removed sys.modules entries")
del sys.path[0]
if verbose: print(" Removed sys.path entry")
@@ -146,23 +159,81 @@ class RunModuleTest(unittest.TestCase):
try:
if verbose: print("Running from source:", mod_name)
d1 = run_module(mod_name) # Read from source
+ self.failUnless("x" in d1)
self.assertEqual(d1["x"], 1)
del d1 # Ensure __loader__ entry doesn't keep file open
__import__(mod_name)
os.remove(mod_fname)
if verbose: print("Running from compiled:", mod_name)
d2 = run_module(mod_name) # Read from bytecode
+ self.failUnless("x" in 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 _add_relative_modules(self, base_dir, depth):
+ if depth <= 1:
+ raise ValueError("Relative module test needs depth > 1")
+ pkg_name = "__runpy_pkg__"
+ module_dir = base_dir
+ for i in range(depth):
+ parent_dir = module_dir
+ module_dir = os.path.join(module_dir, pkg_name)
+ # Add sibling module
+ sibling_fname = os.path.join(module_dir, "sibling"+os.extsep+"py")
+ sibling_file = open(sibling_fname, "w")
+ sibling_file.close()
+ if verbose: print(" Added sibling module:", sibling_fname)
+ # Add nephew module
+ uncle_dir = os.path.join(parent_dir, "uncle")
+ self._add_pkg_dir(uncle_dir)
+ if verbose: print(" Added uncle package:", uncle_dir)
+ cousin_dir = os.path.join(uncle_dir, "cousin")
+ self._add_pkg_dir(cousin_dir)
+ if verbose: print(" Added cousin package:", cousin_dir)
+ nephew_fname = os.path.join(cousin_dir, "nephew"+os.extsep+"py")
+ nephew_file = open(nephew_fname, "w")
+ nephew_file.close()
+ if verbose: print(" Added nephew module:", nephew_fname)
+
+ 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 = (
+ self._make_pkg(contents, depth))
+ try:
+ self._add_relative_modules(pkg_dir, depth)
+ if verbose: print("Running from source:", mod_name)
+ d1 = run_module(mod_name) # Read from source
+ self.failUnless("sibling" in d1)
+ self.failUnless("nephew" in d1)
+ del d1 # Ensure __loader__ entry doesn't keep file open
+ __import__(mod_name)
+ os.remove(mod_fname)
+ if verbose: print("Running from compiled:", mod_name)
+ d2 = run_module(mod_name) # Read from bytecode
+ self.failUnless("sibling" in d2)
+ self.failUnless("nephew" in 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_run_module(self):
for depth in range(4):
if verbose: print("Testing package depth:", depth)
self._check_module(depth)
+ def test_explicit_relative_import(self):
+ for depth in range(2, 5):
+ if verbose: print("Testing relative imports at depth:", depth)
+ self._check_relative_imports(depth)
+
def test_main():
run_unittest(RunModuleCodeTest)