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 f6e58aefde2e57e4cb11ea7743955da53a3f1e80)
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 @@
 
 
 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 @@
     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 @@
         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 8dee5b9..f867014 100644
--- a/Lib/test/support/__init__.py
+++ b/Lib/test/support/__init__.py
@@ -2532,6 +2532,27 @@
     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.
 
@@ -2543,7 +2564,7 @@
 
     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.
@@ -2552,21 +2573,18 @@
             # 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,
@@ -2617,10 +2635,10 @@
             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)
@@ -3097,7 +3115,6 @@
         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 @@
             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)