Skip to content

Commit 10eac02

Browse files
authored
gh-119786: add links to code in exception handling doc (#120077)
1 parent 4bba1c9 commit 10eac02

File tree

1 file changed

+16
-33
lines changed

1 file changed

+16
-33
lines changed

InternalDocs/exception_handling.md

Lines changed: 16 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -67,14 +67,18 @@ handler located at label `L1`.
6767
Handling Exceptions
6868
-------------------
6969

70-
At runtime, when an exception occurs, the interpreter looks up
71-
the offset of the current instruction in the exception table. If
72-
it finds a handler, control flow transfers to it. Otherwise, the
70+
At runtime, when an exception occurs, the interpreter calls
71+
``get_exception_handler()`` in
72+
[Python/ceval.c](https://github.com/python/cpython/blob/main/Python/ceval.c)
73+
to look up the offset of the current instruction in the exception
74+
table. If it finds a handler, control flow transfers to it. Otherwise, the
7375
exception bubbles up to the caller, and the caller's frame is
7476
checked for a handler covering the `CALL` instruction. This
7577
repeats until a handler is found or the topmost frame is reached.
7678
If no handler is found, the program terminates. During unwinding,
77-
the traceback is constructed as each frame is added to it.
79+
the traceback is constructed as each frame is added to it by
80+
``PyTraceBack_Here()``, which is in
81+
[Python/traceback.c](https://github.com/python/cpython/blob/main/Python/traceback.c).
7882

7983
Along with the location of an exception handler, each entry of the
8084
exception table also contains the stack depth of the `try` instruction
@@ -169,33 +173,12 @@ which is then encoded as:
169173

170174
for a total of five bytes.
171175

176+
The code to construct the exception table is in ``assemble_exception_table()``
177+
in [Python/assemble.c](https://github.com/python/cpython/blob/main/Python/assemble.c).
172178

173-
Script to parse the exception table
174-
-----------------------------------
175-
176-
```
177-
def parse_varint(iterator):
178-
b = next(iterator)
179-
val = b & 63
180-
while b&64:
181-
val <<= 6
182-
b = next(iterator)
183-
val |= b&63
184-
return val
185-
```
186-
```
187-
def parse_exception_table(code):
188-
iterator = iter(code.co_exceptiontable)
189-
try:
190-
while True:
191-
start = parse_varint(iterator)*2
192-
length = parse_varint(iterator)*2
193-
end = start + length - 2 # Present as inclusive, not exclusive
194-
target = parse_varint(iterator)*2
195-
dl = parse_varint(iterator)
196-
depth = dl >> 1
197-
lasti = bool(dl&1)
198-
yield start, end, target, depth, lasti
199-
except StopIteration:
200-
return
201-
```
179+
The interpreter's function to lookup the table by instruction offset is
180+
``get_exception_handler()`` in
181+
[Python/ceval.c](https://github.com/python/cpython/blob/main/Python/ceval.c).
182+
The Python function ``_parse_exception_table()`` in
183+
[Lib/dis.py](https://github.com/python/cpython/blob/main/Lib/dis.py)
184+
returns the exception table content as a list of namedtuple instances.

0 commit comments

Comments
 (0)