Skip to content

Commit 70cae99

Browse files
cmaloneyclaude
andcommitted
Set GITHUB_ANNOTATIONS in setup_tests(), like USE_XML
Fall back to the first traceback frame (the test) instead of passing the test module file. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent 9a94bf1 commit 70cae99

4 files changed

Lines changed: 19 additions & 18 deletions

File tree

‎Lib/test/libregrtest/setup.py‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,9 +112,10 @@ def setup_tests(runtests: RunTests) -> None:
112112

113113
set_match_tests(runtests.match_tests)
114114

115+
from .testresult import RegressionTestResult
116+
RegressionTestResult.GITHUB_ANNOTATIONS = runtests.github_annotations
115117
if runtests.use_junit:
116118
support.junit_xml_list = []
117-
from .testresult import RegressionTestResult
118119
RegressionTestResult.USE_XML = True
119120
else:
120121
support.junit_xml_list = None

‎Lib/test/libregrtest/single.py‎

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
from .runtests import RunTests
1717
from .save_env import saved_test_environment
1818
from .setup import setup_tests
19-
from .testresult import RegressionTestResult, get_test_runner
19+
from .testresult import get_test_runner
2020
from .parallel_case import ParallelTestCase
2121
from .utils import (
2222
TestName,
@@ -37,8 +37,6 @@ def run_unittest(test_mod, runtests: RunTests):
3737
if loader.errors:
3838
raise Exception("errors while loading tests")
3939
_filter_suite(tests, match_test)
40-
RegressionTestResult.GITHUB_TEST_FILE = (
41-
test_mod.__file__ if runtests.github_annotations else None)
4240
if runtests.parallel_threads:
4341
_parallelize_tests(tests, runtests.parallel_threads)
4442
return _run_suite(tests)

‎Lib/test/libregrtest/testresult.py‎

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,7 @@
1313

1414
class RegressionTestResult(unittest.TextTestResult):
1515
USE_XML = False
16-
# Test file of the GitHub Actions annotations: don't annotate if None
17-
GITHUB_TEST_FILE: str | None = None
16+
GITHUB_ANNOTATIONS = False
1817

1918
def __init__(self, stream, descriptions, verbosity):
2019
super().__init__(stream=stream, descriptions=descriptions,
@@ -137,9 +136,8 @@ def printErrorList(self, flavour, errors):
137136
super().printErrorList(flavour, [(test, err)])
138137
# Annotate just after the failure report, so that the annotation
139138
# links to the report in the job log
140-
if self.GITHUB_TEST_FILE:
141-
print_github_annotation(str(test), err, self.GITHUB_TEST_FILE,
142-
file=self.stream)
139+
if self.GITHUB_ANNOTATIONS:
140+
print_github_annotation(str(test), err, file=self.stream)
143141

144142
def get_xml_element(self):
145143
if not self.USE_XML:

‎Lib/test/libregrtest/utils.py‎

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -148,22 +148,26 @@ def print_warning(msg: str) -> None:
148148
",": "%2C"})
149149

150150

151-
def print_github_annotation(title: str, message: str, filename: str,
152-
file=None) -> None:
151+
def print_github_annotation(title: str, message: str,
152+
filename: str | None = None, file=None) -> None:
153153
"""Print a GitHub Actions error annotation.
154154
155155
message is a traceback or a failure description. Only keep the exception
156156
which ends the traceback: the job log has the full traceback. Locate the
157-
annotation at the last traceback frame in a test file, if any, or else
158-
in filename, the test file.
157+
annotation at the last traceback frame in a test file, or else at the
158+
first frame (the test), or else in filename (the test file).
159159
"""
160160
message = decolor(message)
161161
line = None
162-
# Last traceback frame (' File "filename", line 123') or failed doctest
163-
# example (same, but not indented) in a test file
164-
if frames := re.findall(r'^ *File "(.*[/\\]test_[^/\\]*\.py)", line (\d+)',
165-
message, re.MULTILINE):
166-
filename, line = frames[-1]
162+
# Traceback frames (' File "filename", line 123') and failed doctest
163+
# examples (same, but not indented)
164+
if frames := re.findall(r'^ *File "(.*)", line (\d+)', message,
165+
re.MULTILINE):
166+
test_frames = [frame for frame in frames
167+
if os.path.basename(frame[0]).startswith('test_')]
168+
filename, line = test_frames[-1] if test_frames else frames[0]
169+
if not filename:
170+
raise ValueError(f"missing test file of annotation {title!r}")
167171
# In the job, the stdlib can be outside of the repository checkout
168172
path = pathlib.Path(filename)
169173
stdlib_dir = pathlib.Path(os.__file__).parent

0 commit comments

Comments
 (0)