mirror of
https://github.com/python/cpython.git
synced 2025-08-04 08:59:19 +00:00
gh-89770: Implement PEP-678 - Exception notes (GH-31317)
This commit is contained in:
parent
7fa3a5a219
commit
d4c4a76ed1
12 changed files with 383 additions and 144 deletions
|
@ -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(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue