Issue #12400: regrtest -W doesn't rerun the tests twice anymore, but captures
the output and displays it on failure instead. regrtest -v doesn't print the
error twice anymore if there is only one error.
diff --git a/Lib/test/regrtest.py b/Lib/test/regrtest.py
index 08c9916..2929001 100755
--- a/Lib/test/regrtest.py
+++ b/Lib/test/regrtest.py
@@ -25,7 +25,7 @@
 
 -v/--verbose    -- run tests in verbose mode with output to stdout
 -w/--verbose2   -- re-run failed tests in verbose mode
--W/--verbose3   -- re-run failed tests in verbose mode immediately
+-W/--verbose3   -- display test output on failure
 -d/--debug      -- print traceback for failed tests
 -q/--quiet      -- no output unless one or more tests fail
 -S/--slow       -- print the slowest 10 tests
@@ -781,17 +781,27 @@
         PASSED           test passed
     """
 
-    support.verbose = verbose  # Tell tests to be moderately quiet
     if use_resources is not None:
         support.use_resources = use_resources
     try:
-        result = runtest_inner(test, verbose, quiet, huntrleaks, debug)
-        if result[0] == FAILED and rerun_failed:
-            cleanup_test_droppings(test, verbose)
-            sys.stdout.flush()
-            sys.stderr.flush()
-            print("Re-running test {} in verbose mode".format(test))
-            runtest(test, True, quiet, huntrleaks, debug)
+        if rerun_failed:
+            support.verbose = True
+            orig_stderr = sys.stderr
+            with support.captured_stdout() as stream:
+                try:
+                    sys.stderr = stream
+                    result = runtest_inner(test, verbose, quiet, huntrleaks,
+                                           debug, display_failure=False)
+                    if result[0] == FAILED:
+                        output = stream.getvalue()
+                        orig_stderr.write(output)
+                        orig_stderr.flush()
+                finally:
+                    sys.stderr = orig_stderr
+        else:
+            support.verbose = verbose  # Tell tests to be moderately quiet
+            result = runtest_inner(test, verbose, quiet, huntrleaks, debug,
+                                   display_failure=not verbose)
         return result
     finally:
         cleanup_test_droppings(test, verbose)
@@ -960,7 +970,8 @@
         return False
 
 
-def runtest_inner(test, verbose, quiet, huntrleaks=False, debug=False):
+def runtest_inner(test, verbose, quiet,
+                  huntrleaks=False, debug=False, display_failure=True):
     support.unload(test)
     if verbose:
         capture_stdout = None
@@ -1002,7 +1013,10 @@
     except KeyboardInterrupt:
         raise
     except support.TestFailed as msg:
-        print("test", test, "failed --", msg, file=sys.stderr)
+        if display_failure:
+            print("test", test, "failed --", msg, file=sys.stderr)
+        else:
+            print("test", test, "failed", file=sys.stderr)
         sys.stderr.flush()
         return FAILED, test_time
     except:
diff --git a/Misc/NEWS b/Misc/NEWS
index 834dea6..51a7d57 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -122,6 +122,10 @@
 Tests
 -----
 
+- Issue #12400: regrtest -W doesn't rerun the tests twice anymore, but captures
+  the output and displays it on failure instead. regrtest -v doesn't print the
+  error twice anymore if there is only one error.
+
 - Issue #12141: Install a copy of template C module file so that
   test_build_ext of test_distutils is no longer silently skipped when
   run outside of a build directory.