cpython/Lib/test/script_helper.py

127 lines
4.2 KiB
Python
Raw Normal View History

# 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
Merged revisions 87136,87221,87256,87337-87338,87571,87839,88164 via svnmerge from svn+ssh://pythondev@svn.python.org/python/branches/py3k ........ r87136 | r.david.murray | 2010-12-08 17:53:00 -0500 (Wed, 08 Dec 2010) | 6 lines Have script_helper._assert_python strip refcount strings from stderr. This makes the output of the function and those that depend on it independent of whether or not they are being run under a debug build. ........ r87221 | r.david.murray | 2010-12-13 19:55:46 -0500 (Mon, 13 Dec 2010) | 4 lines #10699: fix docstring for tzset: it does not take a parameter Thanks to Garrett Cooper for the fix. ........ r87256 | r.david.murray | 2010-12-14 21:19:14 -0500 (Tue, 14 Dec 2010) | 2 lines #10705: document what the values of debuglevel are and mean. ........ r87337 | r.david.murray | 2010-12-17 11:11:40 -0500 (Fri, 17 Dec 2010) | 2 lines #10559: provide instructions for accessing sys.argv when first mentioned. ........ r87338 | r.david.murray | 2010-12-17 11:29:07 -0500 (Fri, 17 Dec 2010) | 2 lines #10454: clarify the compileall docs and help messages. [compileall.py changes not backported.] ........ r87571 | r.david.murray | 2010-12-29 14:06:48 -0500 (Wed, 29 Dec 2010) | 2 lines Fix same typo in docs. ........ r87839 | r.david.murray | 2011-01-07 16:57:25 -0500 (Fri, 07 Jan 2011) | 9 lines Fix formatting of values with embedded newlines when rfc2047 encoding Before this patch if a value being encoded had an embedded newline, the line following the newline would have no leading whitespace, and the whitespace it did have was encoded into the word. Now the existing whitespace gets turned into a blank, the way it does in other header reformatting, and the _continuation_ws gets added at the beginning of the encoded line. ........ r88164 | r.david.murray | 2011-01-24 14:34:58 -0500 (Mon, 24 Jan 2011) | 12 lines #10960: fix 'stat' links, link to lstat from stat, general tidy of stat doc. Original patch by Michal Nowikowski, with some additions and wording fixes by me. I changed the wording from 'Performs a stat system call' to 'Performs the equivalent of a stat system call', since on Windows there are no stat/lstat system calls involved. I also extended Michal's breakout of the attributes into a list to the other paragraphs, and rearranged the order of the paragraphs in the 'stat' docs to make it flow better and put it in what I think is a more logical/useful order. ........
2011-02-10 23:13:19 -04:00
import re
import os.path
import tempfile
import subprocess
import py_compile
import contextlib
import shutil
import zipfile
Merged revisions 87136,87221,87256,87337-87338,87571,87839,88164 via svnmerge from svn+ssh://pythondev@svn.python.org/python/branches/py3k ........ r87136 | r.david.murray | 2010-12-08 17:53:00 -0500 (Wed, 08 Dec 2010) | 6 lines Have script_helper._assert_python strip refcount strings from stderr. This makes the output of the function and those that depend on it independent of whether or not they are being run under a debug build. ........ r87221 | r.david.murray | 2010-12-13 19:55:46 -0500 (Mon, 13 Dec 2010) | 4 lines #10699: fix docstring for tzset: it does not take a parameter Thanks to Garrett Cooper for the fix. ........ r87256 | r.david.murray | 2010-12-14 21:19:14 -0500 (Tue, 14 Dec 2010) | 2 lines #10705: document what the values of debuglevel are and mean. ........ r87337 | r.david.murray | 2010-12-17 11:11:40 -0500 (Fri, 17 Dec 2010) | 2 lines #10559: provide instructions for accessing sys.argv when first mentioned. ........ r87338 | r.david.murray | 2010-12-17 11:29:07 -0500 (Fri, 17 Dec 2010) | 2 lines #10454: clarify the compileall docs and help messages. [compileall.py changes not backported.] ........ r87571 | r.david.murray | 2010-12-29 14:06:48 -0500 (Wed, 29 Dec 2010) | 2 lines Fix same typo in docs. ........ r87839 | r.david.murray | 2011-01-07 16:57:25 -0500 (Fri, 07 Jan 2011) | 9 lines Fix formatting of values with embedded newlines when rfc2047 encoding Before this patch if a value being encoded had an embedded newline, the line following the newline would have no leading whitespace, and the whitespace it did have was encoded into the word. Now the existing whitespace gets turned into a blank, the way it does in other header reformatting, and the _continuation_ws gets added at the beginning of the encoded line. ........ r88164 | r.david.murray | 2011-01-24 14:34:58 -0500 (Mon, 24 Jan 2011) | 12 lines #10960: fix 'stat' links, link to lstat from stat, general tidy of stat doc. Original patch by Michal Nowikowski, with some additions and wording fixes by me. I changed the wording from 'Performs a stat system call' to 'Performs the equivalent of a stat system call', since on Windows there are no stat/lstat system calls involved. I also extended Michal's breakout of the attributes into a list to the other paragraphs, and rearranged the order of the paragraphs in the 'stat' docs to make it flow better and put it in what I think is a more logical/useful order. ........
2011-02-10 23:13:19 -04:00
from test.support import strip_python_stderr
# Executing the interpreter in a subprocess
def _assert_python(expected_success, *args, **env_vars):
cmd_line = [sys.executable]
if not env_vars:
cmd_line.append('-E')
cmd_line.extend(args)
# Need to preserve the original environment, for in-place testing of
# shared library builds.
env = os.environ.copy()
env.update(env_vars)
p = subprocess.Popen(cmd_line, stdin=subprocess.PIPE,
stdout=subprocess.PIPE, stderr=subprocess.PIPE,
env=env)
try:
out, err = p.communicate()
finally:
subprocess._cleanup()
p.stdout.close()
p.stderr.close()
rc = p.returncode
Merged revisions 87136,87221,87256,87337-87338,87571,87839,88164 via svnmerge from svn+ssh://pythondev@svn.python.org/python/branches/py3k ........ r87136 | r.david.murray | 2010-12-08 17:53:00 -0500 (Wed, 08 Dec 2010) | 6 lines Have script_helper._assert_python strip refcount strings from stderr. This makes the output of the function and those that depend on it independent of whether or not they are being run under a debug build. ........ r87221 | r.david.murray | 2010-12-13 19:55:46 -0500 (Mon, 13 Dec 2010) | 4 lines #10699: fix docstring for tzset: it does not take a parameter Thanks to Garrett Cooper for the fix. ........ r87256 | r.david.murray | 2010-12-14 21:19:14 -0500 (Tue, 14 Dec 2010) | 2 lines #10705: document what the values of debuglevel are and mean. ........ r87337 | r.david.murray | 2010-12-17 11:11:40 -0500 (Fri, 17 Dec 2010) | 2 lines #10559: provide instructions for accessing sys.argv when first mentioned. ........ r87338 | r.david.murray | 2010-12-17 11:29:07 -0500 (Fri, 17 Dec 2010) | 2 lines #10454: clarify the compileall docs and help messages. [compileall.py changes not backported.] ........ r87571 | r.david.murray | 2010-12-29 14:06:48 -0500 (Wed, 29 Dec 2010) | 2 lines Fix same typo in docs. ........ r87839 | r.david.murray | 2011-01-07 16:57:25 -0500 (Fri, 07 Jan 2011) | 9 lines Fix formatting of values with embedded newlines when rfc2047 encoding Before this patch if a value being encoded had an embedded newline, the line following the newline would have no leading whitespace, and the whitespace it did have was encoded into the word. Now the existing whitespace gets turned into a blank, the way it does in other header reformatting, and the _continuation_ws gets added at the beginning of the encoded line. ........ r88164 | r.david.murray | 2011-01-24 14:34:58 -0500 (Mon, 24 Jan 2011) | 12 lines #10960: fix 'stat' links, link to lstat from stat, general tidy of stat doc. Original patch by Michal Nowikowski, with some additions and wording fixes by me. I changed the wording from 'Performs a stat system call' to 'Performs the equivalent of a stat system call', since on Windows there are no stat/lstat system calls involved. I also extended Michal's breakout of the attributes into a list to the other paragraphs, and rearranged the order of the paragraphs in the 'stat' docs to make it flow better and put it in what I think is a more logical/useful order. ........
2011-02-10 23:13:19 -04:00
err = strip_python_stderr(err)
if (rc and expected_success) or (not rc and not expected_success):
raise AssertionError(
"Process return code is %d, "
"stderr follows:\n%s" % (rc, err.decode('ascii', 'ignore')))
return rc, out, err
def assert_python_ok(*args, **env_vars):
"""
Assert that running the interpreter with `args` and optional environment
variables `env_vars` is ok and return a (return code, stdout, stderr) tuple.
"""
return _assert_python(True, *args, **env_vars)
def assert_python_failure(*args, **env_vars):
"""
Assert that running the interpreter with `args` and optional environment
variables `env_vars` fails and return a (return code, stdout, stderr) tuple.
"""
return _assert_python(False, *args, **env_vars)
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.
p.wait()
subprocess._cleanup()
return 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)
# The script should be encoded to UTF-8, the default string encoding
script_file = open(script_name, 'w', encoding='utf-8')
script_file.write(source)
script_file.close()
return script_name
def make_pkg(pkg_dir, init_source=''):
os.mkdir(pkg_dir)
make_script(pkg_dir, '__init__', init_source)
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 = py_compile(init_name, doraise=True)
script_name = py_compile(script_name, doraise=True)
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.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)