66import sysconfig
77import time
88import trace
9- from _colorize import decolor , get_colors # type: ignore[import-not-found]
9+ from _colorize import get_colors # type: ignore[import-not-found]
1010from typing import NoReturn
1111
1212from test .support import os_helper , MS_WINDOWS , flush_std_streams
1515from .findtests import findtests , split_test_packages , list_cases , collect_cases
1616from .logger import Logger
1717from .pgo import setup_pgo_tests
18+ from .reporter import get_reporter
1819from .result import TestResult
1920from .results import TestResults , EXITCODE_INTERRUPTED
2021from .runtests import RunTests , HuntRefleak
@@ -285,7 +286,7 @@ def _rerun_failed_tests(self, runtests: RunTests) -> RunTests:
285286 fail_fast = False ,
286287 match_tests_dict = match_tests_dict ,
287288 output_on_failure = False ,
288- github_annotations = bool ( self .github_summary ) )
289+ github_summary = self .github_summary )
289290 self .logger .set_tests (runtests )
290291
291292 msg = f"Re-running { len (tests )} failed tests in verbose mode"
@@ -298,7 +299,7 @@ def _rerun_failed_tests(self, runtests: RunTests) -> RunTests:
298299 self .run_tests_sequentially (runtests )
299300 return runtests
300301
301- def rerun_failed_tests (self , runtests : RunTests ) -> None :
302+ def rerun_failed_tests (self , runtests : RunTests ) -> RunTests :
302303 ansi = get_colors ()
303304 red , reset = ansi .BOLD_RED , ansi .RESET
304305
@@ -308,7 +309,7 @@ def rerun_failed_tests(self, runtests: RunTests) -> None:
308309 "Re-running failed tests is not supported with --python "
309310 "host runner option."
310311 )
311- return
312+ return runtests
312313
313314 self .first_state = self .get_state ()
314315
@@ -323,6 +324,7 @@ def rerun_failed_tests(self, runtests: RunTests) -> None:
323324 printlist (self .results .bad )
324325
325326 self .display_result (rerun_runtests )
327+ return rerun_runtests
326328
327329 def _run_bisect (self , runtests : RunTests , test : str , progress : str ) -> bool :
328330 print ()
@@ -396,7 +398,6 @@ def run_test(
396398 result = run_single_test (test_name , runtests )
397399
398400 self .results .accumulate_result (result , runtests )
399- result .print_github_annotation (runtests )
400401
401402 return result
402403
@@ -463,7 +464,8 @@ def _run_tests_mp(self, runtests: RunTests, num_workers: int) -> None:
463464 from .run_workers import RunWorkers
464465 RunWorkers (num_workers , runtests , self .logger , self .results ).run ()
465466
466- def finalize_tests (self , coverage : trace .CoverageResults | None ) -> None :
467+ def finalize_tests (self , coverage : trace .CoverageResults | None ,
468+ runtests : RunTests ) -> None :
467469 if self .next_single_filename :
468470 if self .next_single_test :
469471 with open (self .next_single_filename , 'w' ) as fp :
@@ -482,24 +484,11 @@ def finalize_tests(self, coverage: trace.CoverageResults | None) -> None:
482484 if self .junit_filename :
483485 self .results .write_junit (self .junit_filename )
484486
485- self .write_github_summary ()
486-
487- def write_github_summary (self ) -> None :
488- # Tests which failed in the last run (the re-run, if any)
489- failed = self .results .rerun_results
490- # Only write a summary on failure: a CI run has many test jobs
491- exitcode = self .results .get_exitcode (self .fail_env_changed ,
492- self .fail_rerun )
493- if not self .github_summary or not failed or not exitcode :
494- return
495- ncases = sum (len (result .failed_test_cases ) for result in failed )
496- with open (self .github_summary , "a" , encoding = "utf-8" ) as fp :
497- fp .write (f"## { decolor (self .get_state ())} : "
498- f"{ count (len (failed ), 'test file' )} and "
499- f"{ count (ncases , 'test case' )} failed\n \n " )
500- for result in failed :
501- # Expand the tracebacks of up to 5 test cases
502- fp .write (result .format_github_summary (expand = ncases <= 5 ))
487+ # Test files which failed in the last run (the re-run, if any)
488+ failed = [result for result in self .results .rerun_results
489+ if result .is_failed (self .fail_env_changed )]
490+ if failed :
491+ get_reporter (runtests ).run_failed (failed , self .get_state ())
503492
504493 def display_summary (self ) -> None :
505494 if self .first_runtests is None :
@@ -538,10 +527,10 @@ def create_run_tests(self, tests: TestTuple) -> RunTests:
538527 hunt_refleak = self .hunt_refleak ,
539528 test_dir = self .test_dir ,
540529 use_junit = (self .junit_filename is not None ),
541- # Only annotate the failure that results in job failure.
542- # Ex: When reruning failed tests , only annotate the the final run.
543- github_annotations = ( bool ( self .github_summary ) and
544- not ( self .want_rerun and not self . python_cmd ) ),
530+ # Only report the failures which fail the job: when failed tests
531+ # are re-run , only report the re- run.
532+ github_summary = ( None if self .want_rerun and not self . python_cmd
533+ else self .github_summary ),
545534 coverage = self .coverage ,
546535 memory_limit = self .memory_limit ,
547536 gc_threshold = self .gc_threshold ,
@@ -612,8 +601,10 @@ def _run_tests(self, selected: TestTuple, tests: TestList | None) -> int:
612601 coverage = self .results .get_coverage_results ()
613602 self .display_result (runtests )
614603
604+ # The re-run, if any, is the last run
605+ last_runtests = runtests
615606 if self .want_rerun and self .results .need_rerun ():
616- self .rerun_failed_tests (runtests )
607+ last_runtests = self .rerun_failed_tests (runtests )
617608
618609 if self .want_bisect and self .results .need_rerun ():
619610 self .run_bisect (runtests )
@@ -622,7 +613,7 @@ def _run_tests(self, selected: TestTuple, tests: TestList | None) -> int:
622613 self .logger .stop_load_tracker ()
623614
624615 self .display_summary ()
625- self .finalize_tests (coverage )
616+ self .finalize_tests (coverage , last_runtests )
626617
627618 return self .results .get_exitcode (self .fail_env_changed ,
628619 self .fail_rerun )
0 commit comments