Skip to content

Commit 4a4f660

Browse files
authored
bpo-40826: Fix test_repl.test_close_stdin() on Windows (GH-20779) (GH-20785)
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)
1 parent 9419158 commit 4a4f660

File tree

4 files changed

+42
-46
lines changed

4 files changed

+42
-46
lines changed

Lib/test/audit-tests.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -350,9 +350,9 @@ def hook(event, args):
350350

351351

352352
if __name__ == "__main__":
353-
from test.libregrtest.setup import suppress_msvcrt_asserts
353+
from test.support import suppress_msvcrt_asserts
354354

355-
suppress_msvcrt_asserts(False)
355+
suppress_msvcrt_asserts()
356356

357357
test = sys.argv[1]
358358
globals()[test]()

Lib/test/libregrtest/setup.py

Lines changed: 1 addition & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ def setup_tests(ns):
6969
if ns.threshold is not None:
7070
gc.set_threshold(ns.threshold)
7171

72-
suppress_msvcrt_asserts(ns.verbose and ns.verbose >= 2)
72+
support.suppress_msvcrt_asserts(ns.verbose and ns.verbose >= 2)
7373

7474
support.use_resources = ns.use_resources
7575

@@ -93,31 +93,6 @@ def _test_audit_hook(name, args):
9393
support.LONG_TIMEOUT = min(support.LONG_TIMEOUT, ns.timeout)
9494

9595

96-
def suppress_msvcrt_asserts(verbose):
97-
try:
98-
import msvcrt
99-
except ImportError:
100-
return
101-
102-
msvcrt.SetErrorMode(msvcrt.SEM_FAILCRITICALERRORS|
103-
msvcrt.SEM_NOALIGNMENTFAULTEXCEPT|
104-
msvcrt.SEM_NOGPFAULTERRORBOX|
105-
msvcrt.SEM_NOOPENFILEERRORBOX)
106-
try:
107-
msvcrt.CrtSetReportMode
108-
except AttributeError:
109-
# release build
110-
return
111-
112-
for m in [msvcrt.CRT_WARN, msvcrt.CRT_ERROR, msvcrt.CRT_ASSERT]:
113-
if verbose:
114-
msvcrt.CrtSetReportMode(m, msvcrt.CRTDBG_MODE_FILE)
115-
msvcrt.CrtSetReportFile(m, msvcrt.CRTDBG_FILE_STDERR)
116-
else:
117-
msvcrt.CrtSetReportMode(m, 0)
118-
119-
120-
12196
def replace_stdout():
12297
"""Set stdout encoder error handler to backslashreplace (as stderr error
12398
handler) to avoid UnicodeEncodeError when printing a traceback"""

Lib/test/support/__init__.py

Lines changed: 34 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2532,6 +2532,27 @@ def test__all__(self):
25322532
test_case.assertCountEqual(module.__all__, expected)
25332533

25342534

2535+
def suppress_msvcrt_asserts(verbose=False):
2536+
try:
2537+
import msvcrt
2538+
except ImportError:
2539+
return
2540+
2541+
msvcrt.SetErrorMode(msvcrt.SEM_FAILCRITICALERRORS
2542+
| msvcrt.SEM_NOALIGNMENTFAULTEXCEPT
2543+
| msvcrt.SEM_NOGPFAULTERRORBOX
2544+
| msvcrt.SEM_NOOPENFILEERRORBOX)
2545+
2546+
# CrtSetReportMode() is only available in debug build
2547+
if hasattr(msvcrt, 'CrtSetReportMode'):
2548+
for m in [msvcrt.CRT_WARN, msvcrt.CRT_ERROR, msvcrt.CRT_ASSERT]:
2549+
if verbose:
2550+
msvcrt.CrtSetReportMode(m, msvcrt.CRTDBG_MODE_FILE)
2551+
msvcrt.CrtSetReportFile(m, msvcrt.CRTDBG_FILE_STDERR)
2552+
else:
2553+
msvcrt.CrtSetReportMode(m, 0)
2554+
2555+
25352556
class SuppressCrashReport:
25362557
"""Try to prevent a crash report from popping up.
25372558
@@ -2543,7 +2564,7 @@ class SuppressCrashReport:
25432564

25442565
def __enter__(self):
25452566
"""On Windows, disable Windows Error Reporting dialogs using
2546-
SetErrorMode.
2567+
SetErrorMode() and CrtSetReportMode().
25472568
25482569
On UNIX, try to save the previous core file size limit, then set
25492570
soft limit to 0.
@@ -2552,21 +2573,18 @@ def __enter__(self):
25522573
# see http://msdn.microsoft.com/en-us/library/windows/desktop/ms680621.aspx
25532574
# GetErrorMode is not available on Windows XP and Windows Server 2003,
25542575
# but SetErrorMode returns the previous value, so we can use that
2555-
import ctypes
2556-
self._k32 = ctypes.windll.kernel32
2557-
SEM_NOGPFAULTERRORBOX = 0x02
2558-
self.old_value = self._k32.SetErrorMode(SEM_NOGPFAULTERRORBOX)
2559-
self._k32.SetErrorMode(self.old_value | SEM_NOGPFAULTERRORBOX)
2560-
2561-
# Suppress assert dialogs in debug builds
2562-
# (see http://bugs.python.org/issue23314)
25632576
try:
25642577
import msvcrt
2565-
msvcrt.CrtSetReportMode
2566-
except (AttributeError, ImportError):
2567-
# no msvcrt or a release build
2568-
pass
2569-
else:
2578+
except ImportError:
2579+
return
2580+
2581+
self.old_value = msvcrt.SetErrorMode(msvcrt.SEM_NOGPFAULTERRORBOX)
2582+
2583+
msvcrt.SetErrorMode(self.old_value | msvcrt.SEM_NOGPFAULTERRORBOX)
2584+
2585+
# bpo-23314: Suppress assert dialogs in debug builds.
2586+
# CrtSetReportMode() is only available in debug build.
2587+
if hasattr(msvcrt, 'CrtSetReportMode'):
25702588
self.old_modes = {}
25712589
for report_type in [msvcrt.CRT_WARN,
25722590
msvcrt.CRT_ERROR,
@@ -2617,10 +2635,10 @@ def __exit__(self, *ignore_exc):
26172635
return
26182636

26192637
if sys.platform.startswith('win'):
2620-
self._k32.SetErrorMode(self.old_value)
2638+
import msvcrt
2639+
msvcrt.SetErrorMode(self.old_value)
26212640

26222641
if self.old_modes:
2623-
import msvcrt
26242642
for report_type, (old_mode, old_file) in self.old_modes.items():
26252643
msvcrt.CrtSetReportMode(report_type, old_mode)
26262644
msvcrt.CrtSetReportFile(report_type, old_file)
@@ -3097,7 +3115,6 @@ def wait_process(pid, *, exitcode, timeout=None):
30973115
if timeout is None:
30983116
timeout = SHORT_TIMEOUT
30993117
t0 = time.monotonic()
3100-
deadline = t0 + timeout
31013118
sleep = 0.001
31023119
max_sleep = 0.1
31033120
while True:

Lib/test/test_repl.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,11 @@ def test_close_stdin(self):
9898
print("before close")
9999
os.close(0)
100100
''')
101-
process = spawn_repl()
101+
prepare_repl = dedent('''
102+
from test.support import suppress_msvcrt_asserts
103+
suppress_msvcrt_asserts()
104+
''')
105+
process = spawn_repl('-c', prepare_repl)
102106
output = process.communicate(user_input)[0]
103107
self.assertEqual(process.returncode, 0)
104108
self.assertIn('before close', output)

0 commit comments

Comments
 (0)