@@ -142,56 +142,40 @@ def print_warning(msg: str) -> None:
142142orig_unraisablehook : Callable [..., None ] | None = None
143143
144144
145- # Stdlib directory: Lib/ in a source checkout or an installed lib/python3.X/
146- STDLIB_DIR = pathlib .Path (os .__file__ ).parent
147- # Stdlib directory relative to the repository
148- REPOSITORY_LIB_DIR = pathlib .Path ("Lib" )
149-
150-
151- def repository_path (filename : str ) -> str :
152- """Path of a stdlib file relative to the repository.
153-
154- Map STDLIB_DIR to Lib/. Return other paths unchanged.
155- """
156- path = pathlib .Path (filename )
157- if not path .is_relative_to (STDLIB_DIR ):
158- return filename
159- return (REPOSITORY_LIB_DIR / path .relative_to (STDLIB_DIR )).as_posix ()
160-
161-
162145# Escape the data and the properties of GitHub Actions workflow commands
163146GITHUB_ESCAPE_DATA = str .maketrans ({"%" : "%25" , "\r " : "%0D" , "\n " : "%0A" })
164147GITHUB_ESCAPE_PROPERTY = GITHUB_ESCAPE_DATA | str .maketrans ({":" : "%3A" ,
165148 "," : "%2C" })
166149
167150
168- def print_github_annotation (title : str , message : str , filename : str | None ,
151+ def print_github_annotation (title : str , message : str , filename : str ,
169152 file = None ) -> None :
170- """Print a GitHub Actions error annotation, if run in GitHub Actions .
153+ """Print a GitHub Actions error annotation.
171154
172155 message is a traceback or a failure description. Only keep the exception
173156 which ends the traceback: the job log has the full traceback. Locate the
174- annotation in filename, the test file, at the last frame of the traceback
175- in this file, if any .
157+ annotation at the last traceback frame in a test file, if any, or else
158+ in filename, the test file .
176159 """
177- if not os .environ .get ("GITHUB_STEP_SUMMARY" ):
178- return
179- if not filename :
180- raise ValueError (f"missing test file of annotation { title !r} " )
181160 message = decolor (message )
182- props = {"file" : repository_path (filename )}
183- # Line of the last traceback frame (' File "filename", line 123') or
184- # failed doctest example (same, but not indented) in filename
185- if lines := re .findall (rf'^ *File "{ re .escape (filename )} ", line (\d+)' ,
186- message , re .MULTILINE ):
187- props ["line" ] = lines [- 1 ]
188- props ["title" ] = title
161+ 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 ]
167+ # In the job, the stdlib can be outside of the repository checkout
168+ path = pathlib .Path (filename )
169+ stdlib_dir = pathlib .Path (os .__file__ ).parent
170+ if path .is_relative_to (stdlib_dir ):
171+ filename = ("Lib" / path .relative_to (stdlib_dir )).as_posix ()
172+ props = {"file" : filename , "line" : line , "title" : title }
189173 # Only keep the exception: strip the traceback frames, each one a
190174 # ' File' line followed by its indented source lines
191175 message = re .split (r'^ File .*\n(?: .*\n)*' , message ,
192176 flags = re .MULTILINE )[- 1 ].strip ()
193177 props_text = "," .join (f"{ key } ={ value .translate (GITHUB_ESCAPE_PROPERTY )} "
194- for key , value in props .items ())
178+ for key , value in props .items () if value )
195179 print (f"::error { props_text } ::{ message .translate (GITHUB_ESCAPE_DATA )} " ,
196180 file = file , flush = True )
197181
0 commit comments