@@ -75,7 +75,8 @@ table. If it finds a handler, control flow transfers to it. Otherwise, the
75
75
exception bubbles up to the caller, and the caller's frame is
76
76
checked for a handler covering the ` CALL ` instruction. This
77
77
repeats until a handler is found or the topmost frame is reached.
78
- If no handler is found, the program terminates. During unwinding,
78
+ If no handler is found, then the interpreter function
79
+ (`` _PyEval_EvalFrameDefault() `` ) returns NULL. During unwinding,
79
80
the traceback is constructed as each frame is added to it by
80
81
`` PyTraceBack_Here() `` , which is in
81
82
[ Python/traceback.c] ( https://github.com/python/cpython/blob/main/Python/traceback.c ) .
@@ -182,3 +183,12 @@ The interpreter's function to lookup the table by instruction offset is
182
183
The Python function `` _parse_exception_table() `` in
183
184
[ Lib/dis.py] ( https://github.com/python/cpython/blob/main/Lib/dis.py )
184
185
returns the exception table content as a list of namedtuple instances.
186
+
187
+ Exception Chaining Implementation
188
+ ---------------------------------
189
+
190
+ [ Exception chaining] ( https://docs.python.org/dev/tutorial/errors.html#exception-chaining )
191
+ refers to setting the `` __context__ `` and `` __cause__ `` fields of an exception as it is
192
+ being raised. The `` __context__ `` field is set by `` _PyErr_SetObject() `` in
193
+ :cpy-file:` Python/errors.c ` (which is ultimately called by all `` PyErr_Set*() `` functions).
194
+ The `` __cause__ `` field (explicit chaining) is set by the `` RAISE_VARARGS `` bytecode.
0 commit comments