diff options
Diffstat (limited to 'Lib/test')
-rwxr-xr-x | Lib/test/regrtest.py | 19 | ||||
-rw-r--r-- | Lib/test/script_helper.py | 119 | ||||
-rw-r--r-- | Lib/test/test_cmd_line.py | 46 | ||||
-rw-r--r-- | Lib/test/test_cmd_line_script.py | 130 | ||||
-rw-r--r-- | Lib/test/test_runpy.py | 162 | ||||
-rw-r--r-- | Lib/test/test_zipimport_support.py | 44 |
6 files changed, 348 insertions, 172 deletions
diff --git a/Lib/test/regrtest.py b/Lib/test/regrtest.py index df8a7b0..d4f228a 100755 --- a/Lib/test/regrtest.py +++ b/Lib/test/regrtest.py @@ -957,6 +957,12 @@ def dash_R(the_module, test, indirect_test, huntrleaks): fs = warnings.filters[:] ps = copyreg.dispatch_table.copy() pic = sys.path_importer_cache.copy() + try: + import zipimport + except ImportError: + zdc = None # Run unmodified on platforms without zipimport support + else: + zdc = zipimport._zip_directory_cache.copy() abcs = {} for abc in [getattr(_abcoll, a) for a in _abcoll.__all__]: if not isabstract(abc): @@ -978,13 +984,13 @@ def dash_R(the_module, test, indirect_test, huntrleaks): print("beginning", repcount, "repetitions", file=sys.stderr) print(("1234567890"*(repcount//10 + 1))[:repcount], file=sys.stderr) sys.stderr.flush() - dash_R_cleanup(fs, ps, pic, abcs) + dash_R_cleanup(fs, ps, pic, zdc, abcs) for i in range(repcount): rc = sys.gettotalrefcount() run_the_test() sys.stderr.write('.') sys.stderr.flush() - dash_R_cleanup(fs, ps, pic, abcs) + dash_R_cleanup(fs, ps, pic, zdc, abcs) if i >= nwarmup: deltas.append(sys.gettotalrefcount() - rc - 2) print(file=sys.stderr) @@ -998,7 +1004,7 @@ def dash_R(the_module, test, indirect_test, huntrleaks): return True return False -def dash_R_cleanup(fs, ps, pic, abcs): +def dash_R_cleanup(fs, ps, pic, zdc, abcs): import gc, copyreg import _strptime, linecache import urllib.parse, urllib.request, mimetypes, doctest @@ -1017,6 +1023,13 @@ def dash_R_cleanup(fs, ps, pic, abcs): copyreg.dispatch_table.update(ps) sys.path_importer_cache.clear() sys.path_importer_cache.update(pic) + try: + import zipimport + except ImportError: + pass # Run unmodified on platforms without zipimport support + else: + zipimport._zip_directory_cache.clear() + zipimport._zip_directory_cache.update(zdc) # clear type cache sys._clear_type_cache() diff --git a/Lib/test/script_helper.py b/Lib/test/script_helper.py new file mode 100644 index 0000000..af5252c --- /dev/null +++ b/Lib/test/script_helper.py @@ -0,0 +1,119 @@ +# Common utility functions used by various script execution tests +# e.g. test_cmd_line, test_cmd_line_script and test_runpy + +import sys +import os +import os.path +import tempfile +import subprocess +import py_compile +import contextlib +import shutil +import zipfile + +# Executing the interpreter in a subprocess +def python_exit_code(*args): + cmd_line = [sys.executable, '-E'] + cmd_line.extend(args) + with open(os.devnull, 'w') as devnull: + return subprocess.call(cmd_line, stdout=devnull, + stderr=subprocess.STDOUT) + +def spawn_python(*args): + cmd_line = [sys.executable, '-E'] + cmd_line.extend(args) + return subprocess.Popen(cmd_line, stdin=subprocess.PIPE, + stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + +def kill_python(p): + p.stdin.close() + data = p.stdout.read() + p.stdout.close() + # try to cleanup the child so we don't appear to leak when running + # with regrtest -R. This should be a no-op on Windows. + subprocess._cleanup() + return data + +def run_python(*args): + if __debug__: + p = spawn_python(*args) + else: + p = spawn_python('-O', *args) + stdout_data = kill_python(p) + return p.wait(), stdout_data + +# Script creation utilities +@contextlib.contextmanager +def temp_dir(): + dirname = tempfile.mkdtemp() + dirname = os.path.realpath(dirname) + try: + yield dirname + finally: + shutil.rmtree(dirname) + +def make_script(script_dir, script_basename, source): + script_filename = script_basename+os.extsep+'py' + script_name = os.path.join(script_dir, script_filename) + script_file = open(script_name, 'w') + script_file.write(source) + script_file.close() + return script_name + +def compile_script(script_name): + py_compile.compile(script_name, doraise=True) + if __debug__: + compiled_name = script_name + 'c' + else: + compiled_name = script_name + 'o' + return compiled_name + +def make_zip_script(zip_dir, zip_basename, script_name, name_in_zip=None): + zip_filename = zip_basename+os.extsep+'zip' + zip_name = os.path.join(zip_dir, zip_filename) + zip_file = zipfile.ZipFile(zip_name, 'w') + if name_in_zip is None: + name_in_zip = os.path.basename(script_name) + zip_file.write(script_name, name_in_zip) + zip_file.close() + #if test.test_support.verbose: + # zip_file = zipfile.ZipFile(zip_name, 'r') + # print 'Contents of %r:' % zip_name + # zip_file.printdir() + # zip_file.close() + return zip_name, os.path.join(zip_name, name_in_zip) + +def make_pkg(pkg_dir): + os.mkdir(pkg_dir) + make_script(pkg_dir, '__init__', '') + +def make_zip_pkg(zip_dir, zip_basename, pkg_name, script_basename, + source, depth=1, compiled=False): + unlink = [] + init_name = make_script(zip_dir, '__init__', '') + unlink.append(init_name) + init_basename = os.path.basename(init_name) + script_name = make_script(zip_dir, script_basename, source) + unlink.append(script_name) + if compiled: + init_name = compile_script(init_name) + script_name = compile_script(script_name) + unlink.extend((init_name, script_name)) + pkg_names = [os.sep.join([pkg_name]*i) for i in range(1, depth+1)] + script_name_in_zip = os.path.join(pkg_names[-1], os.path.basename(script_name)) + zip_filename = zip_basename+os.extsep+'zip' + zip_name = os.path.join(zip_dir, zip_filename) + zip_file = zipfile.ZipFile(zip_name, 'w') + for name in pkg_names: + init_name_in_zip = os.path.join(name, init_basename) + zip_file.write(init_name, init_name_in_zip) + zip_file.write(script_name, script_name_in_zip) + zip_file.close() + for name in unlink: + os.unlink(name) + #if test.test_support.verbose: + # zip_file = zipfile.ZipFile(zip_name, 'r') + # print 'Contents of %r:' % zip_name + # zip_file.printdir() + # zip_file.close() + return zip_name, os.path.join(zip_name, script_name_in_zip) diff --git a/Lib/test/test_cmd_line.py b/Lib/test/test_cmd_line.py index b4a1f9f..852a7aa 100644 --- a/Lib/test/test_cmd_line.py +++ b/Lib/test/test_cmd_line.py @@ -6,44 +6,41 @@ import os import test.support, unittest import os import sys -import subprocess +from test.script_helper import spawn_python, kill_python, python_exit_code + +# XXX (ncoghlan): there are assorted gratuitous inconsistencies between the +# support code in the Py3k version and the 2.x version that unnecessarily +# complicate test suite merges. See issue 7331 -def _spawn_python(*args): +# spawn_python normally enforces use of -E to avoid environmental effects +# but one test checks PYTHONPATH behaviour explicitly +# XXX (ncoghlan): Give script_helper.spawn_python an option to switch +# off the -E flag that is normally inserted automatically +import subprocess +def _spawn_python_with_env(*args): cmd_line = [sys.executable] - # When testing -S, we need PYTHONPATH to work (see test_site_flag()) - if '-S' not in args: - cmd_line.append('-E') cmd_line.extend(args) return subprocess.Popen(cmd_line, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) -def _kill_python(p): - return _kill_python_and_exit_code(p)[0] +# XXX (ncoghlan): Move to script_helper and make consistent with run_python def _kill_python_and_exit_code(p): - p.stdin.close() - data = p.stdout.read() - p.stdout.close() - # try to cleanup the child so we don't appear to leak when running - # with regrtest -R. This should be a no-op on Windows. - subprocess._cleanup() + data = kill_python(p) returncode = p.wait() return data, returncode class CmdLineTest(unittest.TestCase): def start_python(self, *args): - return self.start_python_and_exit_code(*args)[0] + p = spawn_python(*args) + return kill_python(p) def start_python_and_exit_code(self, *args): - p = _spawn_python(*args) + p = spawn_python(*args) return _kill_python_and_exit_code(p) def exit_code(self, *args): - cmd_line = [sys.executable, '-E'] - cmd_line.extend(args) - with open(os.devnull, 'w') as devnull: - return subprocess.call(cmd_line, stdout=devnull, - stderr=subprocess.STDOUT) + return python_exit_code(*args) def test_directories(self): self.assertNotEqual(self.exit_code('.'), 0) @@ -107,10 +104,10 @@ class CmdLineTest(unittest.TestCase): # -m and -i need to play well together # Runs the timeit module and checks the __main__ # namespace has been populated appropriately - p = _spawn_python('-i', '-m', 'timeit', '-n', '1') + p = spawn_python('-i', '-m', 'timeit', '-n', '1') p.stdin.write(b'Timer\n') p.stdin.write(b'exit()\n') - data = _kill_python(p) + data = kill_python(p) self.assertTrue(data.find(b'1 loop') != -1) self.assertTrue(data.find(b'__main__.Timer') != -1) @@ -154,7 +151,7 @@ class CmdLineTest(unittest.TestCase): def test_unbuffered_input(self): # sys.stdin still works with '-u' code = ("import sys; sys.stdout.write(sys.stdin.read(1))") - p = _spawn_python('-u', '-c', code) + p = spawn_python('-u', '-c', code) p.stdin.write(b'x') p.stdin.flush() data, rc = _kill_python_and_exit_code(p) @@ -166,7 +163,8 @@ class CmdLineTest(unittest.TestCase): path1 = "ABCDE" * 100 path2 = "FGHIJ" * 100 env['PYTHONPATH'] = path1 + os.pathsep + path2 - p = _spawn_python('-S', '-c', 'import sys; print(sys.path)') + p = _spawn_python_with_env('-S', '-c', + 'import sys; print(sys.path)') stdout, _ = p.communicate() self.assertTrue(path1.encode('ascii') in stdout) self.assertTrue(path2.encode('ascii') in stdout) diff --git a/Lib/test/test_cmd_line_script.py b/Lib/test/test_cmd_line_script.py index 7114681..e6d6ffb 100644 --- a/Lib/test/test_cmd_line_script.py +++ b/Lib/test/test_cmd_line_script.py @@ -5,35 +5,12 @@ import os import os.path import sys import test.support -import tempfile -import subprocess -import py_compile -import contextlib -import shutil -import zipfile +from test.script_helper import (spawn_python, kill_python, run_python, + temp_dir, make_script, compile_script, + make_pkg, make_zip_script, make_zip_pkg) verbose = test.support.verbose -# XXX ncoghlan: Should we consider moving these to support? -from test.test_cmd_line import _spawn_python, _kill_python - -def _run_python(*args): - if __debug__: - p = _spawn_python(*args) - else: - p = _spawn_python('-O', *args) - stdout_data = _kill_python(p) - return p.wait(), stdout_data.decode() - -@contextlib.contextmanager -def temp_dir(): - dirname = tempfile.mkdtemp() - dirname = os.path.realpath(dirname) - try: - yield dirname - finally: - shutil.rmtree(dirname) - test_source = """\ # Script may be run with optimisation enabled, so don't rely on assert # statements being executed @@ -60,63 +37,12 @@ print('sys.argv[0]==%r' % sys.argv[0]) """ def _make_test_script(script_dir, script_basename, source=test_source): - script_filename = script_basename+os.path.extsep+'py' - script_name = os.path.join(script_dir, script_filename) - script_file = open(script_name, 'w') - script_file.write(source) - script_file.close() - return script_name - -def _compile_test_script(script_name): - py_compile.compile(script_name, doraise=True) - if __debug__: - compiled_name = script_name + 'c' - else: - compiled_name = script_name + 'o' - return compiled_name - -def _make_test_zip(zip_dir, zip_basename, script_name, name_in_zip=None): - zip_filename = zip_basename+os.path.extsep+"zip" - zip_name = os.path.join(zip_dir, zip_filename) - zip_file = zipfile.ZipFile(zip_name, 'w') - if name_in_zip is None: - name_in_zip = os.path.basename(script_name) - zip_file.write(script_name, name_in_zip) - zip_file.close() - #if verbose: - # zip_file = zipfile.ZipFile(zip_name, 'r') - # print("Contents of %r:" % zip_name) - # zip_file.printdir() - # zip_file.close() - return zip_name, os.path.join(zip_name, name_in_zip) - -def _make_test_pkg(pkg_dir): - os.mkdir(pkg_dir) - _make_test_script(pkg_dir, '__init__', '') + return make_script(script_dir, script_basename, source) def _make_test_zip_pkg(zip_dir, zip_basename, pkg_name, script_basename, source=test_source, depth=1): - init_name = _make_test_script(zip_dir, '__init__', '') - init_basename = os.path.basename(init_name) - script_name = _make_test_script(zip_dir, script_basename, source) - pkg_names = [os.sep.join([pkg_name]*i) for i in range(1, depth+1)] - script_name_in_zip = os.path.join(pkg_names[-1], os.path.basename(script_name)) - zip_filename = zip_basename+os.extsep+'zip' - zip_name = os.path.join(zip_dir, zip_filename) - zip_file = zipfile.ZipFile(zip_name, 'w') - for name in pkg_names: - init_name_in_zip = os.path.join(name, init_basename) - zip_file.write(init_name, init_name_in_zip) - zip_file.write(script_name, script_name_in_zip) - zip_file.close() - os.unlink(init_name) - os.unlink(script_name) - #if verbose: - # zip_file = zipfile.ZipFile(zip_name, 'r') - # print('Contents of %r:' % zip_name) - # zip_file.printdir() - # zip_file.close() - return zip_name, os.path.join(zip_name, script_name_in_zip) + return make_zip_pkg(zip_dir, zip_basename, pkg_name, script_basename, + source, depth) # There's no easy way to pass the script directory in to get # -m to work (avoiding that is the whole point of making @@ -134,14 +60,14 @@ def _make_launch_script(script_dir, script_basename, module_name, path=None): else: path = repr(path) source = launch_source % (path, module_name) - return _make_test_script(script_dir, script_basename, source) + return make_script(script_dir, script_basename, source) class CmdLineTest(unittest.TestCase): def _check_script(self, script_name, expected_file, expected_argv0, expected_package, *cmd_line_switches): run_args = cmd_line_switches + (script_name,) - exit_code, data = _run_python(*run_args) + exit_code, data = run_python(*run_args) if verbose: print("Output from test script %r:" % script_name) print(data) @@ -154,19 +80,19 @@ class CmdLineTest(unittest.TestCase): print(printed_file) print(printed_package) print(printed_argv0) - self.assertTrue(printed_file in data) - self.assertTrue(printed_package in data) - self.assertTrue(printed_argv0 in data) + self.assertTrue(printed_file.encode('utf-8') in data) + self.assertTrue(printed_package.encode('utf-8') in data) + self.assertTrue(printed_argv0.encode('utf-8') in data) def _check_import_error(self, script_name, expected_msg, *cmd_line_switches): run_args = cmd_line_switches + (script_name,) - exit_code, data = _run_python(*run_args) + exit_code, data = run_python(*run_args) if verbose: print('Output from test script %r:' % script_name) print(data) print('Expected output: %r' % expected_msg) - self.assertTrue(expected_msg in data) + self.assertTrue(expected_msg.encode('utf-8') in data) def test_basic_script(self): with temp_dir() as script_dir: @@ -176,7 +102,7 @@ class CmdLineTest(unittest.TestCase): def test_script_compiled(self): with temp_dir() as script_dir: script_name = _make_test_script(script_dir, 'script') - compiled_name = _compile_test_script(script_name) + compiled_name = compile_script(script_name) os.remove(script_name) self._check_script(compiled_name, compiled_name, compiled_name, None) @@ -188,39 +114,39 @@ class CmdLineTest(unittest.TestCase): def test_directory_compiled(self): with temp_dir() as script_dir: script_name = _make_test_script(script_dir, '__main__') - compiled_name = _compile_test_script(script_name) + compiled_name = compile_script(script_name) os.remove(script_name) self._check_script(script_dir, compiled_name, script_dir, '') def test_directory_error(self): with temp_dir() as script_dir: - msg = "can't find '__main__.py' in %r" % script_dir + msg = "can't find '__main__' module in %r" % script_dir self._check_import_error(script_dir, msg) def test_zipfile(self): with temp_dir() as script_dir: script_name = _make_test_script(script_dir, '__main__') - zip_name, run_name = _make_test_zip(script_dir, 'test_zip', script_name) + zip_name, run_name = make_zip_script(script_dir, 'test_zip', script_name) self._check_script(zip_name, run_name, zip_name, '') def test_zipfile_compiled(self): with temp_dir() as script_dir: script_name = _make_test_script(script_dir, '__main__') - compiled_name = _compile_test_script(script_name) - zip_name, run_name = _make_test_zip(script_dir, 'test_zip', compiled_name) + compiled_name = compile_script(script_name) + zip_name, run_name = make_zip_script(script_dir, 'test_zip', compiled_name) self._check_script(zip_name, run_name, zip_name, '') def test_zipfile_error(self): with temp_dir() as script_dir: script_name = _make_test_script(script_dir, 'not_main') - zip_name, run_name = _make_test_zip(script_dir, 'test_zip', script_name) - msg = "can't find '__main__.py' in %r" % zip_name + zip_name, run_name = make_zip_script(script_dir, 'test_zip', script_name) + msg = "can't find '__main__' module in %r" % zip_name self._check_import_error(zip_name, msg) def test_module_in_package(self): with temp_dir() as script_dir: pkg_dir = os.path.join(script_dir, 'test_pkg') - _make_test_pkg(pkg_dir) + make_pkg(pkg_dir) script_name = _make_test_script(pkg_dir, 'script') launch_name = _make_launch_script(script_dir, 'launch', 'test_pkg.script') self._check_script(launch_name, script_name, script_name, 'test_pkg') @@ -240,7 +166,7 @@ class CmdLineTest(unittest.TestCase): def test_package(self): with temp_dir() as script_dir: pkg_dir = os.path.join(script_dir, 'test_pkg') - _make_test_pkg(pkg_dir) + make_pkg(pkg_dir) script_name = _make_test_script(pkg_dir, '__main__') launch_name = _make_launch_script(script_dir, 'launch', 'test_pkg') self._check_script(launch_name, script_name, @@ -249,9 +175,9 @@ class CmdLineTest(unittest.TestCase): def test_package_compiled(self): with temp_dir() as script_dir: pkg_dir = os.path.join(script_dir, 'test_pkg') - _make_test_pkg(pkg_dir) + make_pkg(pkg_dir) script_name = _make_test_script(pkg_dir, '__main__') - compiled_name = _compile_test_script(script_name) + compiled_name = compile_script(script_name) os.remove(script_name) launch_name = _make_launch_script(script_dir, 'launch', 'test_pkg') self._check_script(launch_name, compiled_name, @@ -260,7 +186,7 @@ class CmdLineTest(unittest.TestCase): def test_package_error(self): with temp_dir() as script_dir: pkg_dir = os.path.join(script_dir, 'test_pkg') - _make_test_pkg(pkg_dir) + make_pkg(pkg_dir) msg = ("'test_pkg' is a package and cannot " "be directly executed") launch_name = _make_launch_script(script_dir, 'launch', 'test_pkg') @@ -269,9 +195,9 @@ class CmdLineTest(unittest.TestCase): def test_package_recursion(self): with temp_dir() as script_dir: pkg_dir = os.path.join(script_dir, 'test_pkg') - _make_test_pkg(pkg_dir) + make_pkg(pkg_dir) main_dir = os.path.join(pkg_dir, '__main__') - _make_test_pkg(main_dir) + make_pkg(main_dir) msg = ("Cannot use package as __main__ module; " "'test_pkg' is a package and cannot " "be directly executed") diff --git a/Lib/test/test_runpy.py b/Lib/test/test_runpy.py index 43141e5..bd22814 100644 --- a/Lib/test/test_runpy.py +++ b/Lib/test/test_runpy.py @@ -5,8 +5,11 @@ import os.path import sys import tempfile from test.support import verbose, run_unittest, forget -from runpy import _run_code, _run_module_code, run_module +from test.script_helper import (temp_dir, make_script, compile_script, + make_pkg, make_zip_script, make_zip_pkg) + +from runpy import _run_code, _run_module_code, run_module, run_path # Note: This module can't safely test _run_module_as_main as it # runs its tests in the current process, which would mess with the # real __main__ module (usually test.regrtest) @@ -15,6 +18,7 @@ from runpy import _run_code, _run_module_code, run_module # Set up the test code and expected results class RunModuleCodeTest(unittest.TestCase): + """Unit tests for runpy._run_code and runpy._run_module_code""" expected_result = ["Top level assignment", "Lower level reference"] test_source = ( @@ -37,14 +41,14 @@ class RunModuleCodeTest(unittest.TestCase): def test_run_code(self): saved_argv0 = sys.argv[0] d = _run_code(self.test_source, {}) - self.assertTrue(d["result"] == self.expected_result) - self.assertTrue(d["__name__"] is None) - self.assertTrue(d["__file__"] is None) - self.assertTrue(d["__loader__"] is None) - self.assertTrue(d["__package__"] is None) - self.assertTrue(d["run_argv0"] is saved_argv0) - self.assertTrue("run_name" not in d) - self.assertTrue(sys.argv[0] is saved_argv0) + self.assertEqual(d["result"], self.expected_result) + self.assertIs(d["__name__"], None) + self.assertIs(d["__file__"], None) + self.assertIs(d["__loader__"], None) + self.assertIs(d["__package__"], None) + self.assertIs(d["run_argv0"], saved_argv0) + self.assertNotIn("run_name", d) + self.assertIs(sys.argv[0], saved_argv0) def test_run_module_code(self): initial = object() @@ -60,22 +64,23 @@ class RunModuleCodeTest(unittest.TestCase): file, loader, package) - self.assertTrue("result" not in d1) - self.assertTrue(d2["initial"] is initial) + self.assertNotIn("result", d1) + self.assertIs(d2["initial"], initial) self.assertEqual(d2["result"], self.expected_result) self.assertEqual(d2["nested"]["x"], 1) - self.assertTrue(d2["__name__"] is name) + self.assertIs(d2["__name__"], name) self.assertTrue(d2["run_name_in_sys_modules"]) self.assertTrue(d2["module_in_sys_modules"]) - self.assertTrue(d2["__file__"] is file) - self.assertTrue(d2["run_argv0"] is file) - self.assertTrue(d2["__loader__"] is loader) - self.assertTrue(d2["__package__"] is package) - self.assertTrue(sys.argv[0] is saved_argv0) - self.assertTrue(name not in sys.modules) + self.assertIs(d2["__file__"], file) + self.assertIs(d2["run_argv0"], file) + self.assertIs(d2["__loader__"], loader) + self.assertIs(d2["__package__"], package) + self.assertIs(sys.argv[0], saved_argv0) + self.assertNotIn(name, sys.modules) class RunModuleTest(unittest.TestCase): + """Unit tests for runpy.run_module""" def expect_import_error(self, mod_name): try: @@ -245,9 +250,126 @@ from ..uncle.cousin import nephew self._check_relative_imports(depth, "__main__") +class RunPathTest(unittest.TestCase): + """Unit tests for runpy.run_path""" + # Based on corresponding tests in test_cmd_line_script + + test_source = """\ +# Script may be run with optimisation enabled, so don't rely on assert +# statements being executed +def assertEqual(lhs, rhs): + if lhs != rhs: + raise AssertionError('%r != %r' % (lhs, rhs)) +def assertIs(lhs, rhs): + if lhs is not rhs: + raise AssertionError('%r is not %r' % (lhs, rhs)) +# Check basic code execution +result = ['Top level assignment'] +def f(): + result.append('Lower level reference') +f() +assertEqual(result, ['Top level assignment', 'Lower level reference']) +# Check the sys module +import sys +assertIs(globals(), sys.modules[__name__].__dict__) +argv0 = sys.argv[0] +""" + + def _make_test_script(self, script_dir, script_basename, source=None): + if source is None: + source = self.test_source + return make_script(script_dir, script_basename, source) + + def _check_script(self, script_name, expected_name, expected_file, + expected_argv0, expected_package): + result = run_path(script_name) + self.assertEqual(result["__name__"], expected_name) + self.assertEqual(result["__file__"], expected_file) + self.assertIn("argv0", result) + self.assertEqual(result["argv0"], expected_argv0) + self.assertEqual(result["__package__"], expected_package) + + def _check_import_error(self, script_name, msg): + # Double backslashes to handle path separators on Windows + msg = msg.replace("\\", "\\\\") + self.assertRaisesRegexp(ImportError, msg, run_path, script_name) + + def test_basic_script(self): + with temp_dir() as script_dir: + mod_name = 'script' + script_name = self._make_test_script(script_dir, mod_name) + self._check_script(script_name, "<run_path>", script_name, + script_name, None) + + def test_script_compiled(self): + with temp_dir() as script_dir: + mod_name = 'script' + script_name = self._make_test_script(script_dir, mod_name) + compiled_name = compile_script(script_name) + os.remove(script_name) + self._check_script(compiled_name, "<run_path>", compiled_name, + compiled_name, None) + + def test_directory(self): + with temp_dir() as script_dir: + mod_name = '__main__' + script_name = self._make_test_script(script_dir, mod_name) + self._check_script(script_dir, "<run_path>", script_name, + script_dir, '') + + def test_directory_compiled(self): + with temp_dir() as script_dir: + mod_name = '__main__' + script_name = self._make_test_script(script_dir, mod_name) + compiled_name = compile_script(script_name) + os.remove(script_name) + self._check_script(script_dir, "<run_path>", compiled_name, + script_dir, '') + + def test_directory_error(self): + with temp_dir() as script_dir: + mod_name = 'not_main' + script_name = self._make_test_script(script_dir, mod_name) + msg = "can't find '__main__' module in %r" % script_dir + self._check_import_error(script_dir, msg) + + def test_zipfile(self): + with temp_dir() as script_dir: + mod_name = '__main__' + script_name = self._make_test_script(script_dir, mod_name) + zip_name, fname = make_zip_script(script_dir, 'test_zip', script_name) + self._check_script(zip_name, "<run_path>", fname, zip_name, '') + + def test_zipfile_compiled(self): + with temp_dir() as script_dir: + mod_name = '__main__' + script_name = self._make_test_script(script_dir, mod_name) + compiled_name = compile_script(script_name) + zip_name, fname = make_zip_script(script_dir, 'test_zip', compiled_name) + self._check_script(zip_name, "<run_path>", fname, zip_name, '') + + def test_zipfile_error(self): + with temp_dir() as script_dir: + mod_name = 'not_main' + script_name = self._make_test_script(script_dir, mod_name) + zip_name, fname = make_zip_script(script_dir, 'test_zip', script_name) + msg = "can't find '__main__' module in %r" % zip_name + self._check_import_error(zip_name, msg) + + def test_main_recursion_error(self): + with temp_dir() as script_dir, temp_dir() as dummy_dir: + mod_name = '__main__' + source = ("import runpy\n" + "runpy.run_path(%r)\n") % dummy_dir + script_name = self._make_test_script(script_dir, mod_name, source) + zip_name, fname = make_zip_script(script_dir, 'test_zip', script_name) + msg = "recursion depth exceeded" + self.assertRaisesRegexp(RuntimeError, msg, run_path, zip_name) + + + def test_main(): - run_unittest(RunModuleCodeTest) - run_unittest(RunModuleTest) + run_unittest(RunModuleCodeTest, RunModuleTest, RunPathTest) if __name__ == "__main__": test_main() diff --git a/Lib/test/test_zipimport_support.py b/Lib/test/test_zipimport_support.py index 94a65fc..3a99eb7 100644 --- a/Lib/test/test_zipimport_support.py +++ b/Lib/test/test_zipimport_support.py @@ -14,6 +14,9 @@ import doctest import inspect import linecache import pdb +from test.script_helper import (spawn_python, kill_python, run_python, + temp_dir, make_script, compile_script, + make_pkg, make_zip_script, make_zip_pkg) verbose = test.support.verbose @@ -29,11 +32,6 @@ verbose = test.support.verbose # Retrieve some helpers from other test cases from test import test_doctest, sample_doctest from test.test_importhooks import ImportHooksBaseTestCase -from test.test_cmd_line_script import temp_dir, _run_python, \ - _spawn_python, _kill_python, \ - _make_test_script, \ - _compile_test_script, \ - _make_test_zip, _make_test_pkg def _run_object_doctest(obj, module): @@ -78,10 +76,10 @@ class ZipSupportTests(ImportHooksBaseTestCase): def test_inspect_getsource_issue4223(self): test_src = "def foo(): pass\n" with temp_dir() as d: - init_name = _make_test_script(d, '__init__', test_src) + init_name = make_script(d, '__init__', test_src) name_in_zip = os.path.join('zip_pkg', os.path.basename(init_name)) - zip_name, run_name = _make_test_zip(d, 'test_zip', + zip_name, run_name = make_zip_script(d, 'test_zip', init_name, name_in_zip) os.remove(init_name) sys.path.insert(0, zip_name) @@ -106,9 +104,9 @@ class ZipSupportTests(ImportHooksBaseTestCase): sample_src = sample_src.replace("test.test_doctest", "test_zipped_doctest") with temp_dir() as d: - script_name = _make_test_script(d, 'test_zipped_doctest', + script_name = make_script(d, 'test_zipped_doctest', test_src) - zip_name, run_name = _make_test_zip(d, 'test_zip', + zip_name, run_name = make_zip_script(d, 'test_zip', script_name) z = zipfile.ZipFile(zip_name, 'a') z.writestr("sample_zipped_doctest.py", sample_src) @@ -180,23 +178,23 @@ class ZipSupportTests(ImportHooksBaseTestCase): """) pattern = 'File "%s", line 2, in %s' with temp_dir() as d: - script_name = _make_test_script(d, 'script', test_src) - exit_code, data = _run_python(script_name) + script_name = make_script(d, 'script', test_src) + exit_code, data = run_python(script_name) expected = pattern % (script_name, "__main__.Test") if verbose: print ("Expected line", expected) print ("Got stdout:") print (data) - self.assertTrue(expected in data) - zip_name, run_name = _make_test_zip(d, "test_zip", + self.assertTrue(expected.encode('utf-8') in data) + zip_name, run_name = make_zip_script(d, "test_zip", script_name, '__main__.py') - exit_code, data = _run_python(zip_name) + exit_code, data = run_python(zip_name) expected = pattern % (run_name, "__main__.Test") if verbose: print ("Expected line", expected) print ("Got stdout:") print (data) - self.assertTrue(expected in data) + self.assertTrue(expected.encode('utf-8') in data) def test_pdb_issue4201(self): test_src = textwrap.dedent("""\ @@ -207,17 +205,17 @@ class ZipSupportTests(ImportHooksBaseTestCase): pdb.runcall(f) """) with temp_dir() as d: - script_name = _make_test_script(d, 'script', test_src) - p = _spawn_python(script_name) + script_name = make_script(d, 'script', test_src) + p = spawn_python(script_name) p.stdin.write(b'l\n') - data = _kill_python(p).decode() - self.assertTrue(script_name in data) - zip_name, run_name = _make_test_zip(d, "test_zip", + data = kill_python(p) + self.assertTrue(script_name.encode('utf-8') in data) + zip_name, run_name = make_zip_script(d, "test_zip", script_name, '__main__.py') - p = _spawn_python(zip_name) + p = spawn_python(zip_name) p.stdin.write(b'l\n') - data = _kill_python(p).decode() - self.assertTrue(run_name in data) + data = kill_python(p) + self.assertTrue(run_name.encode('utf-8') in data) def test_main(): |