bpo-40826: Fix test_repl.test_close_stdin() on Windows (GH-20779)
test_repl.test_close_stdin() now calls support.suppress_msvcrt_asserts() to fix the test on Windows. * Move suppress_msvcrt_asserts() from test.libregrtest.setup to test.support. Make its verbose parameter optional: verbose=False by default. * Add msvcrt.GetErrorMode(). * SuppressCrashReport now uses GetErrorMode() and SetErrorMode() of the msvcrt module, rather than using ctypes. * Remove also an unused variable (deadline) in wait_process().
This commit is contained in:
parent
d36cf5f1d2
commit
f6e58aefde
|
@ -350,9 +350,9 @@ def test_socket():
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
from test.libregrtest.setup import suppress_msvcrt_asserts
|
from test.support import suppress_msvcrt_asserts
|
||||||
|
|
||||||
suppress_msvcrt_asserts(False)
|
suppress_msvcrt_asserts()
|
||||||
|
|
||||||
test = sys.argv[1]
|
test = sys.argv[1]
|
||||||
globals()[test]()
|
globals()[test]()
|
||||||
|
|
|
@ -69,7 +69,7 @@ def setup_tests(ns):
|
||||||
if ns.threshold is not None:
|
if ns.threshold is not None:
|
||||||
gc.set_threshold(ns.threshold)
|
gc.set_threshold(ns.threshold)
|
||||||
|
|
||||||
suppress_msvcrt_asserts(ns.verbose and ns.verbose >= 2)
|
support.suppress_msvcrt_asserts(ns.verbose and ns.verbose >= 2)
|
||||||
|
|
||||||
support.use_resources = ns.use_resources
|
support.use_resources = ns.use_resources
|
||||||
|
|
||||||
|
@ -93,31 +93,6 @@ def setup_tests(ns):
|
||||||
support.LONG_TIMEOUT = min(support.LONG_TIMEOUT, ns.timeout)
|
support.LONG_TIMEOUT = min(support.LONG_TIMEOUT, ns.timeout)
|
||||||
|
|
||||||
|
|
||||||
def suppress_msvcrt_asserts(verbose):
|
|
||||||
try:
|
|
||||||
import msvcrt
|
|
||||||
except ImportError:
|
|
||||||
return
|
|
||||||
|
|
||||||
msvcrt.SetErrorMode(msvcrt.SEM_FAILCRITICALERRORS|
|
|
||||||
msvcrt.SEM_NOALIGNMENTFAULTEXCEPT|
|
|
||||||
msvcrt.SEM_NOGPFAULTERRORBOX|
|
|
||||||
msvcrt.SEM_NOOPENFILEERRORBOX)
|
|
||||||
try:
|
|
||||||
msvcrt.CrtSetReportMode
|
|
||||||
except AttributeError:
|
|
||||||
# release build
|
|
||||||
return
|
|
||||||
|
|
||||||
for m in [msvcrt.CRT_WARN, msvcrt.CRT_ERROR, msvcrt.CRT_ASSERT]:
|
|
||||||
if verbose:
|
|
||||||
msvcrt.CrtSetReportMode(m, msvcrt.CRTDBG_MODE_FILE)
|
|
||||||
msvcrt.CrtSetReportFile(m, msvcrt.CRTDBG_FILE_STDERR)
|
|
||||||
else:
|
|
||||||
msvcrt.CrtSetReportMode(m, 0)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def replace_stdout():
|
def replace_stdout():
|
||||||
"""Set stdout encoder error handler to backslashreplace (as stderr error
|
"""Set stdout encoder error handler to backslashreplace (as stderr error
|
||||||
handler) to avoid UnicodeEncodeError when printing a traceback"""
|
handler) to avoid UnicodeEncodeError when printing a traceback"""
|
||||||
|
|
|
@ -1899,6 +1899,27 @@ def check__all__(test_case, module, name_of_module=None, extra=(),
|
||||||
test_case.assertCountEqual(module.__all__, expected)
|
test_case.assertCountEqual(module.__all__, expected)
|
||||||
|
|
||||||
|
|
||||||
|
def suppress_msvcrt_asserts(verbose=False):
|
||||||
|
try:
|
||||||
|
import msvcrt
|
||||||
|
except ImportError:
|
||||||
|
return
|
||||||
|
|
||||||
|
msvcrt.SetErrorMode(msvcrt.SEM_FAILCRITICALERRORS
|
||||||
|
| msvcrt.SEM_NOALIGNMENTFAULTEXCEPT
|
||||||
|
| msvcrt.SEM_NOGPFAULTERRORBOX
|
||||||
|
| msvcrt.SEM_NOOPENFILEERRORBOX)
|
||||||
|
|
||||||
|
# CrtSetReportMode() is only available in debug build
|
||||||
|
if hasattr(msvcrt, 'CrtSetReportMode'):
|
||||||
|
for m in [msvcrt.CRT_WARN, msvcrt.CRT_ERROR, msvcrt.CRT_ASSERT]:
|
||||||
|
if verbose:
|
||||||
|
msvcrt.CrtSetReportMode(m, msvcrt.CRTDBG_MODE_FILE)
|
||||||
|
msvcrt.CrtSetReportFile(m, msvcrt.CRTDBG_FILE_STDERR)
|
||||||
|
else:
|
||||||
|
msvcrt.CrtSetReportMode(m, 0)
|
||||||
|
|
||||||
|
|
||||||
class SuppressCrashReport:
|
class SuppressCrashReport:
|
||||||
"""Try to prevent a crash report from popping up.
|
"""Try to prevent a crash report from popping up.
|
||||||
|
|
||||||
|
@ -1910,30 +1931,25 @@ class SuppressCrashReport:
|
||||||
|
|
||||||
def __enter__(self):
|
def __enter__(self):
|
||||||
"""On Windows, disable Windows Error Reporting dialogs using
|
"""On Windows, disable Windows Error Reporting dialogs using
|
||||||
SetErrorMode.
|
SetErrorMode() and CrtSetReportMode().
|
||||||
|
|
||||||
On UNIX, try to save the previous core file size limit, then set
|
On UNIX, try to save the previous core file size limit, then set
|
||||||
soft limit to 0.
|
soft limit to 0.
|
||||||
"""
|
"""
|
||||||
if sys.platform.startswith('win'):
|
if sys.platform.startswith('win'):
|
||||||
# see http://msdn.microsoft.com/en-us/library/windows/desktop/ms680621.aspx
|
# see http://msdn.microsoft.com/en-us/library/windows/desktop/ms680621.aspx
|
||||||
# GetErrorMode is not available on Windows XP and Windows Server 2003,
|
|
||||||
# but SetErrorMode returns the previous value, so we can use that
|
|
||||||
import ctypes
|
|
||||||
self._k32 = ctypes.windll.kernel32
|
|
||||||
SEM_NOGPFAULTERRORBOX = 0x02
|
|
||||||
self.old_value = self._k32.SetErrorMode(SEM_NOGPFAULTERRORBOX)
|
|
||||||
self._k32.SetErrorMode(self.old_value | SEM_NOGPFAULTERRORBOX)
|
|
||||||
|
|
||||||
# Suppress assert dialogs in debug builds
|
|
||||||
# (see http://bugs.python.org/issue23314)
|
|
||||||
try:
|
try:
|
||||||
import msvcrt
|
import msvcrt
|
||||||
msvcrt.CrtSetReportMode
|
except ImportError:
|
||||||
except (AttributeError, ImportError):
|
return
|
||||||
# no msvcrt or a release build
|
|
||||||
pass
|
self.old_value = msvcrt.GetErrorMode()
|
||||||
else:
|
|
||||||
|
msvcrt.SetErrorMode(self.old_value | msvcrt.SEM_NOGPFAULTERRORBOX)
|
||||||
|
|
||||||
|
# bpo-23314: Suppress assert dialogs in debug builds.
|
||||||
|
# CrtSetReportMode() is only available in debug build.
|
||||||
|
if hasattr(msvcrt, 'CrtSetReportMode'):
|
||||||
self.old_modes = {}
|
self.old_modes = {}
|
||||||
for report_type in [msvcrt.CRT_WARN,
|
for report_type in [msvcrt.CRT_WARN,
|
||||||
msvcrt.CRT_ERROR,
|
msvcrt.CRT_ERROR,
|
||||||
|
@ -1985,10 +2001,10 @@ class SuppressCrashReport:
|
||||||
return
|
return
|
||||||
|
|
||||||
if sys.platform.startswith('win'):
|
if sys.platform.startswith('win'):
|
||||||
self._k32.SetErrorMode(self.old_value)
|
import msvcrt
|
||||||
|
msvcrt.SetErrorMode(self.old_value)
|
||||||
|
|
||||||
if self.old_modes:
|
if self.old_modes:
|
||||||
import msvcrt
|
|
||||||
for report_type, (old_mode, old_file) in self.old_modes.items():
|
for report_type, (old_mode, old_file) in self.old_modes.items():
|
||||||
msvcrt.CrtSetReportMode(report_type, old_mode)
|
msvcrt.CrtSetReportMode(report_type, old_mode)
|
||||||
msvcrt.CrtSetReportFile(report_type, old_file)
|
msvcrt.CrtSetReportFile(report_type, old_file)
|
||||||
|
@ -2332,7 +2348,6 @@ def wait_process(pid, *, exitcode, timeout=None):
|
||||||
if timeout is None:
|
if timeout is None:
|
||||||
timeout = SHORT_TIMEOUT
|
timeout = SHORT_TIMEOUT
|
||||||
t0 = time.monotonic()
|
t0 = time.monotonic()
|
||||||
deadline = t0 + timeout
|
|
||||||
sleep = 0.001
|
sleep = 0.001
|
||||||
max_sleep = 0.1
|
max_sleep = 0.1
|
||||||
while True:
|
while True:
|
||||||
|
|
|
@ -98,7 +98,11 @@ class TestInteractiveInterpreter(unittest.TestCase):
|
||||||
print("before close")
|
print("before close")
|
||||||
os.close(0)
|
os.close(0)
|
||||||
''')
|
''')
|
||||||
process = spawn_repl()
|
prepare_repl = dedent('''
|
||||||
|
from test.support import suppress_msvcrt_asserts
|
||||||
|
suppress_msvcrt_asserts()
|
||||||
|
''')
|
||||||
|
process = spawn_repl('-c', prepare_repl)
|
||||||
output = process.communicate(user_input)[0]
|
output = process.communicate(user_input)[0]
|
||||||
self.assertEqual(process.returncode, 0)
|
self.assertEqual(process.returncode, 0)
|
||||||
self.assertIn('before close', output)
|
self.assertIn('before close', output)
|
||||||
|
|
|
@ -590,6 +590,24 @@ exit:
|
||||||
|
|
||||||
#endif /* defined(_DEBUG) */
|
#endif /* defined(_DEBUG) */
|
||||||
|
|
||||||
|
PyDoc_STRVAR(msvcrt_GetErrorMode__doc__,
|
||||||
|
"GetErrorMode($module, /)\n"
|
||||||
|
"--\n"
|
||||||
|
"\n"
|
||||||
|
"Wrapper around GetErrorMode.");
|
||||||
|
|
||||||
|
#define MSVCRT_GETERRORMODE_METHODDEF \
|
||||||
|
{"GetErrorMode", (PyCFunction)msvcrt_GetErrorMode, METH_NOARGS, msvcrt_GetErrorMode__doc__},
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
msvcrt_GetErrorMode_impl(PyObject *module);
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
msvcrt_GetErrorMode(PyObject *module, PyObject *Py_UNUSED(ignored))
|
||||||
|
{
|
||||||
|
return msvcrt_GetErrorMode_impl(module);
|
||||||
|
}
|
||||||
|
|
||||||
PyDoc_STRVAR(msvcrt_SetErrorMode__doc__,
|
PyDoc_STRVAR(msvcrt_SetErrorMode__doc__,
|
||||||
"SetErrorMode($module, mode, /)\n"
|
"SetErrorMode($module, mode, /)\n"
|
||||||
"--\n"
|
"--\n"
|
||||||
|
@ -629,4 +647,4 @@ exit:
|
||||||
#ifndef MSVCRT_SET_ERROR_MODE_METHODDEF
|
#ifndef MSVCRT_SET_ERROR_MODE_METHODDEF
|
||||||
#define MSVCRT_SET_ERROR_MODE_METHODDEF
|
#define MSVCRT_SET_ERROR_MODE_METHODDEF
|
||||||
#endif /* !defined(MSVCRT_SET_ERROR_MODE_METHODDEF) */
|
#endif /* !defined(MSVCRT_SET_ERROR_MODE_METHODDEF) */
|
||||||
/*[clinic end generated code: output=ab3b5ce5c1447f0e input=a9049054013a1b77]*/
|
/*[clinic end generated code: output=20dfbc768edce7c0 input=a9049054013a1b77]*/
|
||||||
|
|
|
@ -482,6 +482,25 @@ msvcrt_set_error_mode_impl(PyObject *module, int mode)
|
||||||
}
|
}
|
||||||
#endif /* _DEBUG */
|
#endif /* _DEBUG */
|
||||||
|
|
||||||
|
/*[clinic input]
|
||||||
|
msvcrt.GetErrorMode
|
||||||
|
|
||||||
|
Wrapper around GetErrorMode.
|
||||||
|
[clinic start generated code]*/
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
msvcrt_GetErrorMode_impl(PyObject *module)
|
||||||
|
/*[clinic end generated code: output=3103fc6145913591 input=5a7fb083b6dd71fd]*/
|
||||||
|
{
|
||||||
|
unsigned int res;
|
||||||
|
|
||||||
|
_Py_BEGIN_SUPPRESS_IPH
|
||||||
|
res = GetErrorMode();
|
||||||
|
_Py_END_SUPPRESS_IPH
|
||||||
|
|
||||||
|
return PyLong_FromUnsignedLong(res);
|
||||||
|
}
|
||||||
|
|
||||||
/*[clinic input]
|
/*[clinic input]
|
||||||
msvcrt.SetErrorMode
|
msvcrt.SetErrorMode
|
||||||
|
|
||||||
|
@ -520,6 +539,7 @@ static struct PyMethodDef msvcrt_functions[] = {
|
||||||
MSVCRT_GETCHE_METHODDEF
|
MSVCRT_GETCHE_METHODDEF
|
||||||
MSVCRT_PUTCH_METHODDEF
|
MSVCRT_PUTCH_METHODDEF
|
||||||
MSVCRT_UNGETCH_METHODDEF
|
MSVCRT_UNGETCH_METHODDEF
|
||||||
|
MSVCRT_GETERRORMODE_METHODDEF
|
||||||
MSVCRT_SETERRORMODE_METHODDEF
|
MSVCRT_SETERRORMODE_METHODDEF
|
||||||
MSVCRT_CRTSETREPORTFILE_METHODDEF
|
MSVCRT_CRTSETREPORTFILE_METHODDEF
|
||||||
MSVCRT_CRTSETREPORTMODE_METHODDEF
|
MSVCRT_CRTSETREPORTMODE_METHODDEF
|
||||||
|
|
Loading…
Reference in New Issue