summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@python.org>2020-06-10 16:49:23 (GMT)
committerGitHub <noreply@github.com>2020-06-10 16:49:23 (GMT)
commitf6e58aefde2e57e4cb11ea7743955da53a3f1e80 (patch)
treeae5a760fc2db639f50d8a08e600267b865ac852c
parentd36cf5f1d20ce9f111a8fc997104785086e8eee6 (diff)
downloadcpython-f6e58aefde2e57e4cb11ea7743955da53a3f1e80.zip
cpython-f6e58aefde2e57e4cb11ea7743955da53a3f1e80.tar.gz
cpython-f6e58aefde2e57e4cb11ea7743955da53a3f1e80.tar.bz2
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().
-rw-r--r--Lib/test/audit-tests.py4
-rw-r--r--Lib/test/libregrtest/setup.py27
-rw-r--r--Lib/test/support/__init__.py53
-rw-r--r--Lib/test/test_repl.py6
-rw-r--r--PC/clinic/msvcrtmodule.c.h20
-rw-r--r--PC/msvcrtmodule.c20
6 files changed, 81 insertions, 49 deletions
diff --git a/Lib/test/audit-tests.py b/Lib/test/audit-tests.py
index b90c4b8..a58395b 100644
--- a/Lib/test/audit-tests.py
+++ b/Lib/test/audit-tests.py
@@ -350,9 +350,9 @@ def test_socket():
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]
globals()[test]()
diff --git a/Lib/test/libregrtest/setup.py b/Lib/test/libregrtest/setup.py
index ce81496..1f264c1 100644
--- a/Lib/test/libregrtest/setup.py
+++ b/Lib/test/libregrtest/setup.py
@@ -69,7 +69,7 @@ def setup_tests(ns):
if ns.threshold is not None:
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
@@ -93,31 +93,6 @@ def setup_tests(ns):
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():
"""Set stdout encoder error handler to backslashreplace (as stderr error
handler) to avoid UnicodeEncodeError when printing a traceback"""
diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py
index 3a5f7b5..83b2173 100644
--- a/Lib/test/support/__init__.py
+++ b/Lib/test/support/__init__.py
@@ -1899,6 +1899,27 @@ def check__all__(test_case, module, name_of_module=None, extra=(),
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:
"""Try to prevent a crash report from popping up.
@@ -1910,30 +1931,25 @@ class SuppressCrashReport:
def __enter__(self):
"""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
soft limit to 0.
"""
if sys.platform.startswith('win'):
# 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:
import msvcrt
- msvcrt.CrtSetReportMode
- except (AttributeError, ImportError):
- # no msvcrt or a release build
- pass
- else:
+ except ImportError:
+ return
+
+ self.old_value = msvcrt.GetErrorMode()
+
+ 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 = {}
for report_type in [msvcrt.CRT_WARN,
msvcrt.CRT_ERROR,
@@ -1985,10 +2001,10 @@ class SuppressCrashReport:
return
if sys.platform.startswith('win'):
- self._k32.SetErrorMode(self.old_value)
+ import msvcrt
+ msvcrt.SetErrorMode(self.old_value)
if self.old_modes:
- import msvcrt
for report_type, (old_mode, old_file) in self.old_modes.items():
msvcrt.CrtSetReportMode(report_type, old_mode)
msvcrt.CrtSetReportFile(report_type, old_file)
@@ -2332,7 +2348,6 @@ def wait_process(pid, *, exitcode, timeout=None):
if timeout is None:
timeout = SHORT_TIMEOUT
t0 = time.monotonic()
- deadline = t0 + timeout
sleep = 0.001
max_sleep = 0.1
while True:
diff --git a/Lib/test/test_repl.py b/Lib/test/test_repl.py
index 563f188..03bf8d8 100644
--- a/Lib/test/test_repl.py
+++ b/Lib/test/test_repl.py
@@ -98,7 +98,11 @@ class TestInteractiveInterpreter(unittest.TestCase):
print("before close")
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]
self.assertEqual(process.returncode, 0)
self.assertIn('before close', output)
diff --git a/PC/clinic/msvcrtmodule.c.h b/PC/clinic/msvcrtmodule.c.h
index 9701e8a..1ac82cb 100644
--- a/PC/clinic/msvcrtmodule.c.h
+++ b/PC/clinic/msvcrtmodule.c.h
@@ -590,6 +590,24 @@ exit:
#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__,
"SetErrorMode($module, mode, /)\n"
"--\n"
@@ -629,4 +647,4 @@ exit:
#ifndef MSVCRT_SET_ERROR_MODE_METHODDEF
#define 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]*/
diff --git a/PC/msvcrtmodule.c b/PC/msvcrtmodule.c
index faceb03..b7ff20a 100644
--- a/PC/msvcrtmodule.c
+++ b/PC/msvcrtmodule.c
@@ -483,6 +483,25 @@ msvcrt_set_error_mode_impl(PyObject *module, int mode)
#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]
msvcrt.SetErrorMode
mode: unsigned_int(bitwise=True)
@@ -520,6 +539,7 @@ static struct PyMethodDef msvcrt_functions[] = {
MSVCRT_GETCHE_METHODDEF
MSVCRT_PUTCH_METHODDEF
MSVCRT_UNGETCH_METHODDEF
+ MSVCRT_GETERRORMODE_METHODDEF
MSVCRT_SETERRORMODE_METHODDEF
MSVCRT_CRTSETREPORTFILE_METHODDEF
MSVCRT_CRTSETREPORTMODE_METHODDEF