summaryrefslogtreecommitdiffstats
path: root/Lib/test/script_helper.py
diff options
context:
space:
mode:
authorAntoine Pitrou <solipsis@pitrou.net>2015-04-13 17:48:19 (GMT)
committerAntoine Pitrou <solipsis@pitrou.net>2015-04-13 17:48:19 (GMT)
commitcb46f0ecb05ef3ccd3f53ced7f60748c0b3c710a (patch)
treebd7bf53350b0acbd12721bcfba898d6f6072fc1c /Lib/test/script_helper.py
parent9c680b07285867844927871ddcbf60c93e786e1f (diff)
parent25f85d4bd58d86d3e6ce99cb9f270e96bf5ba08f (diff)
downloadcpython-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.py18
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):
"""