mirror of
https://github.com/python/cpython.git
synced 2025-07-28 21:55:21 +00:00
Issue #6816: expose the zipfile and directory execution mechanism to Python code via the runpy module. Also consolidated some script execution functionality in the test harness into a helper module and removed some implementation details from the runpy module documentation.
This commit is contained in:
parent
51200277b2
commit
49868cb686
8 changed files with 563 additions and 241 deletions
|
@ -5,34 +5,12 @@ import os
|
|||
import os.path
|
||||
import sys
|
||||
import test.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.test_support.verbose
|
||||
|
||||
# XXX ncoghlan: Should we consider moving these to test_support?
|
||||
from 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
|
||||
|
||||
@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
|
||||
|
@ -60,63 +38,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.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.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 +61,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
|
||||
|
@ -161,7 +88,7 @@ class CmdLineTest(unittest.TestCase):
|
|||
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
|
||||
|
@ -176,7 +103,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 +115,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 +167,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 +176,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 +187,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 +196,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")
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue