gh-89770: Implement PEP-678 - Exception notes (GH-31317)

This commit is contained in:
Irit Katriel 2022-04-16 19:59:52 +01:00 committed by GitHub
parent 7fa3a5a219
commit d4c4a76ed1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 383 additions and 144 deletions

View file

@ -1,6 +1,6 @@
"""Extract, format and print information about Python stack traces."""
import collections
import collections.abc
import itertools
import linecache
import sys
@ -163,18 +163,18 @@ def format_exception_only(exc, /, value=_sentinel):
# -- not official API but folk probably use these two functions.
def _format_final_exc_line(etype, value):
valuestr = _some_str(value)
valuestr = _safe_string(value, 'exception')
if value is None or not valuestr:
line = "%s\n" % etype
else:
line = "%s: %s\n" % (etype, valuestr)
return line
def _some_str(value):
def _safe_string(value, what, func=str):
try:
return str(value)
return func(value)
except:
return '<exception str() failed>'
return f'<{what} {func.__name__}() failed>'
# --
@ -688,8 +688,8 @@ class TracebackException:
self.exc_type = exc_type
# Capture now to permit freeing resources: only complication is in the
# unofficial API _format_final_exc_line
self._str = _some_str(exc_value)
self.__note__ = exc_value.__note__ if exc_value else None
self._str = _safe_string(exc_value, 'exception')
self.__notes__ = getattr(exc_value, '__notes__', None)
if exc_type and issubclass(exc_type, SyntaxError):
# Handle SyntaxError's specially
@ -822,8 +822,12 @@ class TracebackException:
yield _format_final_exc_line(stype, self._str)
else:
yield from self._format_syntax_error(stype)
if self.__note__ is not None:
yield from [l + '\n' for l in self.__note__.split('\n')]
if isinstance(self.__notes__, collections.abc.Sequence):
for note in self.__notes__:
note = _safe_string(note, 'note')
yield from [l + '\n' for l in note.split('\n')]
elif self.__notes__ is not None:
yield _safe_string(self.__notes__, '__notes__', func=repr)
def _format_syntax_error(self, stype):
"""Format SyntaxError exceptions (internal helper)."""
@ -913,7 +917,7 @@ class TracebackException:
# format exception group
is_toplevel = (_ctx.exception_group_depth == 0)
if is_toplevel:
_ctx.exception_group_depth += 1
_ctx.exception_group_depth += 1
if exc.stack:
yield from _ctx.emit(