Skip to content

Commit

Permalink
bpo-40826: Fix test_repl.test_close_stdin() on Windows (pythonGH-20779)…
Browse files Browse the repository at this point in the history
… (pythonGH-20785) (pythonGH-20787)

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.
* SuppressCrashReport now uses SetErrorMode() of the msvcrt module,
  rather than using ctypes.
* Remove also an unused variable (deadline) in wait_process().

(cherry picked from commit f6e58ae)
(cherry picked from commit 4a4f660)
  • Loading branch information
vstinner committed Jun 10, 2020
1 parent 663836e commit c7a6c7b
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 45 deletions.
4 changes: 2 additions & 2 deletions Lib/test/audit-tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -350,9 +350,9 @@ def hook(event, args):


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]()
27 changes: 1 addition & 26 deletions Lib/test/libregrtest/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,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

Expand All @@ -78,31 +78,6 @@ def _test_audit_hook(name, args):
sys.addaudithook(_test_audit_hook)


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"""
Expand Down
50 changes: 34 additions & 16 deletions Lib/test/support/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2825,6 +2825,27 @@ def test__all__(self):
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.
Expand All @@ -2836,7 +2857,7 @@ 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.
Expand All @@ -2845,21 +2866,18 @@ def __enter__(self):
# 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.SetErrorMode(msvcrt.SEM_NOGPFAULTERRORBOX)

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,
Expand Down Expand Up @@ -2905,10 +2923,10 @@ def __exit__(self, *ignore_exc):
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)
Expand Down
6 changes: 5 additions & 1 deletion Lib/test/test_repl.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,11 @@ def test_close_stdin(self):
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)
Expand Down

0 comments on commit c7a6c7b

Please sign in to comment.