Skip to main content

Lib/traceback.py (part 2)

Source:

cpython 3.14 @ ab2d84fe1023/Lib/traceback.py

This annotation covers structured traceback objects and chaining. See lib_traceback_detail for format_tb, print_tb, extract_tb, and FrameSummary.

Map

LinesSymbolRole
1-100TracebackException.__init__Capture __cause__, __context__, __suppress_context__
101-220TracebackException.formatYield formatted strings including chained exceptions
221-360StackSummary.extractExtract frame info from a traceback or FrameInfo list
361-500format_exc / print_excConvenience wrappers around TracebackException
501-600Exception notes__notes__ formatting (PEP 678)

Reading

TracebackException.__init__

# CPython: Lib/traceback.py:680 TracebackException.__init__
class TracebackException:
def __init__(self, exc_type, exc_value, exc_tb, *,
limit=None, lookup_lines=True, capture_locals=False,
compact=False, _seen=None):
if _seen is None:
_seen = set()
_seen.add(id(exc_value))
# Capture chained exceptions
if exc_value and exc_value.__cause__ is not None and id(exc_value.__cause__) not in _seen:
cause = TracebackException(
type(exc_value.__cause__), exc_value.__cause__,
exc_value.__cause__.__traceback__, _seen=_seen)
else:
cause = None
self.__cause__ = cause
self.__context__ = ... # Similar for __context__
self.stack = StackSummary.extract(
walk_tb(exc_tb), limit=limit, lookup_lines=lookup_lines,
capture_locals=capture_locals)
self.exc_type = exc_type
self._str = _safe_string(exc_value, 'exception')

The _seen set prevents infinite recursion for circular exception chains. TracebackException snapshots the exception at creation time, so the original exception and its traceback can be garbage-collected.

TracebackException.format

# CPython: Lib/traceback.py:820 TracebackException.format
def format(self, *, chain=True):
"""Format the exception, including chained exceptions."""
if chain:
if self.__cause__ is not None:
yield from self.__cause__.format(chain=chain)
yield _cause_message # "The above exception was the direct cause..."
elif (self.__context__ is not None and
not self.__suppress_context__):
yield from self.__context__.format(chain=chain)
yield _context_message # "During handling of the above exception..."
yield from self.format_stack()
yield from self.format_exception_only()

The recursive format call traverses the chain before the current exception. __cause__ (from raise X from Y) prints "direct cause"; __context__ (from implicit chaining) prints "during handling of".

StackSummary.extract

# CPython: Lib/traceback.py:560 StackSummary.extract
@classmethod
def extract(cls, frame_gen, *, limit=None, lookup_lines=True,
capture_locals=False):
"""Create a StackSummary from a frame generator (walk_stack or walk_tb)."""
result = cls()
fnames = set()
for frame, lineno in islice(frame_gen, limit):
co = frame.f_code
filename = co.co_filename
name = co.co_qualname
fnames.add(filename)
result.append(FrameSummary(filename, lineno, name,
lookup_line=lookup_lines,
locals=frame.f_locals if capture_locals else None))
for filename in fnames:
linecache.checkcache(filename)
return result

capture_locals=True snapshots frame.f_locals at each frame, enabling post-mortem inspection. linecache.checkcache ensures source lines are fresh.

gopy notes

TracebackException is module/traceback.TracebackException in module/traceback/module.go. The exception chain is walked using objects.ExceptionCause and objects.ExceptionContext. StackSummary.extract uses vm.WalkTB to iterate frames. format yields formatted strings via a Go channel-based iterator.