Include/internal/pycore_traceback.h
Include/internal/pycore_traceback.h is the internal header for CPython's traceback machinery. It declares the _PyTracebackObject struct and the small set of C functions that build, print, and walk traceback chains. Nothing here is part of the public stable ABI — all symbols carry a leading underscore.
Map
| Lines | Symbol | Role |
|---|---|---|
| 1–15 | guard / includes | Py_BUILD_CORE guard, forward decls |
| 16–30 | _PyTracebackObject | Struct layout: tb_next, tb_frame, tb_lasti, tb_lineno |
| 31–45 | _PyTraceBack_Here | Prepend the current frame to the active exception's traceback |
| 46–58 | _PyTraceBack_Print | Format a full traceback chain to a file object |
| 59–70 | _Py_DisplaySourceLine | Read one source line from disk or linecache and write it |
| 71–80 | _Py_UnhandledKeyboardInterrupt | Flag tested by the signal handler after KeyboardInterrupt |
Reading
_PyTracebackObject struct
The struct mirrors the Python-visible types.TracebackType. tb_frame holds a strong reference; tb_next is the older frame further down the stack.
// CPython: Include/internal/pycore_traceback.h:16 _PyTracebackObject
typedef struct _PyTracebackObject {
PyObject_HEAD
struct _PyTracebackObject *tb_next;
PyFrameObject *tb_frame;
int tb_lasti;
int tb_lineno;
} _PyTracebackObject;
tb_lasti is the byte offset of the last executed instruction inside the code object, not a line number. tb_lineno caches the result of PyCode_Addr2Line(tb_lasti) for fast display.
_PyTraceBack_Here
Called by the eval loop every time an exception propagates through a frame boundary. It allocates a new _PyTracebackObject, fills in the current frame and f_lasti, then chains it onto exc->__traceback__.
// CPython: Include/internal/pycore_traceback.h:31 _PyTraceBack_Here
/* Append a new traceback entry for the current frame.
Returns 0 on success, -1 on allocation failure. */
PyAPI_FUNC(int) _PyTraceBack_Here(PyFrameObject *frame);
The function is defined in Python/traceback.c. The header declaration is what the eval loop and ceval.c include.
_Py_DisplaySourceLine
This is the helper that produces the "arrow line" under the filename and line number in a traceback. It tries the in-memory linecache first, then falls back to opening the file with tokenize.open (to respect encoding cookies).
// CPython: Include/internal/pycore_traceback.h:59 _Py_DisplaySourceLine
/* Write source line number `lineno` from `filename` to `f`.
`indent` spaces are prepended. Returns 0 on success, -1 on error. */
PyAPI_FUNC(int) _Py_DisplaySourceLine(PyObject *f, PyObject *filename,
int lineno, int indent,
int *truncation, PyObject **line);
The truncation out-parameter was added in 3.12 to support the fine-grained caret underlining (^~~~~) in SyntaxError tracebacks.
gopy notes
_PyTracebackObjectmaps toobjects/traceback.go. Thetb_framefield must use gopy's*Frametype rather than CPython'sPyFrameObject._PyTraceBack_Hereis called fromvm/eval_unwind.gowhenever an exception unwinds through a frame. The gopy equivalent prepends aTracebackObjecttoexc.Traceback._Py_DisplaySourceLineis deferred: gopy's error printer currently usesruntime.Callersstyle output. A full port requires linecache integration (spec 1700)._Py_UnhandledKeyboardInterruptis a plainintflag in CPython. In gopy it can be anatomic.Int32to avoid data races with the signal goroutine.
CPython 3.14 changes
tb_linenois now populated lazily viaPyCode_Addr2Lineonly when the traceback is printed, reducing overhead on hot exception paths.- The
truncationandlineout-parameters of_Py_DisplaySourceLinegainedPyObject **linein 3.13; 3.14 uses this to powercolorizeoutput in the default traceback formatter. _Py_UnhandledKeyboardInterruptmoved frompystate.hinto this header in 3.14 to consolidate signal-related traceback state.