diff options
author | Antoine Pitrou <solipsis@pitrou.net> | 2015-04-13 17:48:19 (GMT) |
---|---|---|
committer | Antoine Pitrou <solipsis@pitrou.net> | 2015-04-13 17:48:19 (GMT) |
commit | cb46f0ecb05ef3ccd3f53ced7f60748c0b3c710a (patch) | |
tree | bd7bf53350b0acbd12721bcfba898d6f6072fc1c /Lib/test/script_helper.py | |
parent | 9c680b07285867844927871ddcbf60c93e786e1f (diff) | |
parent | 25f85d4bd58d86d3e6ce99cb9f270e96bf5ba08f (diff) | |
download | cpython-cb46f0ecb05ef3ccd3f53ced7f60748c0b3c710a.zip cpython-cb46f0ecb05ef3ccd3f53ced7f60748c0b3c710a.tar.gz cpython-cb46f0ecb05ef3ccd3f53ced7f60748c0b3c710a.tar.bz2 |
Issue #23309: Avoid a deadlock at shutdown if a daemon thread is aborted
while it is holding a lock to a buffered I/O object, and the main thread
tries to use the same I/O object (typically stdout or stderr). A fatal
error is emitted instead.
Diffstat (limited to 'Lib/test/script_helper.py')
-rw-r--r-- | Lib/test/script_helper.py | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/Lib/test/script_helper.py b/Lib/test/script_helper.py index 8743dba..7ac19bf 100644 --- a/Lib/test/script_helper.py +++ b/Lib/test/script_helper.py @@ -1,6 +1,7 @@ # Common utility functions used by various script execution tests # e.g. test_cmd_line, test_cmd_line_script and test_runpy +import collections import importlib import sys import os @@ -50,8 +51,12 @@ def interpreter_requires_environment(): return __cached_interp_requires_environment +_PythonRunResult = collections.namedtuple("_PythonRunResult", + ("rc", "out", "err")) + + # Executing the interpreter in a subprocess -def _assert_python(expected_success, *args, **env_vars): +def run_python_until_end(*args, **env_vars): env_required = interpreter_requires_environment() if '__isolated' in env_vars: isolated = env_vars.pop('__isolated') @@ -85,9 +90,14 @@ def _assert_python(expected_success, *args, **env_vars): p.stderr.close() rc = p.returncode err = strip_python_stderr(err) - if (rc and expected_success) or (not rc and not expected_success): + return _PythonRunResult(rc, out, err), cmd_line + +def _assert_python(expected_success, *args, **env_vars): + res, cmd_line = run_python_until_end(*args, **env_vars) + if (res.rc and expected_success) or (not res.rc and not expected_success): # Limit to 80 lines to ASCII characters maxlen = 80 * 100 + out, err = res.out, res.err if len(out) > maxlen: out = b'(... truncated stdout ...)' + out[-maxlen:] if len(err) > maxlen: @@ -106,10 +116,10 @@ def _assert_python(expected_success, *args, **env_vars): "---\n" "%s\n" "---" - % (rc, cmd_line, + % (res.rc, cmd_line, out, err)) - return rc, out, err + return res def assert_python_ok(*args, **env_vars): """ |