Quantcast
Viewing latest article 1
Browse Latest Browse All 2

Answer by Abdul Niyas P M for What is the `ExceptionTable` in the output of `dis`?

ExceptionTable determines where to jump to when an exception is raised(it was implemented in ). Prior version uses separate opcodes to handle this. The advantage of this approach is that entering and leaving a try block normally does not execute any code, making execution faster.

To access this table, you can do so by accessing the co_exceptiontable attribute of the code object. The ExceptionTable representation returned by dis is the result of parsing this table.

>>> def foo():...     c = 1 + 2...     return c... >>> >>> foo.__code__.co_exceptiontableb''>>> def foo():...     try:...             1/0...     except:...             pass... >>> foo.__code__.co_exceptiontableb'\x82\x05\x08\x00\x88\x02\x0c\x03'>>>>>> from dis import _parse_exception_table>>>>>> _parse_exception_table(foo.__code__)[_ExceptionTableEntry(start=4, end=14, target=16, depth=0, lasti=False), _ExceptionTableEntry(start=16, end=20, target=24, depth=1, lasti=True)]

A detailed explanation about ExceptionTable is available here. Quoting from the same link:

uses what is known as "zero-cost" exception handling.Prior to , exceptions were handled by a runtime stack of "blocks".

In zero-cost exception handling, the cost of supporting exceptions isminimized. In the common case (where no exception is raised) the costis reduced to zero (or close to zero). The cost of raising anexception is increased, but not by much.

The following code:

def f():    try:        g(0)    except:        return "fail"compiles as follows in 3.10:  2           0 SETUP_FINALLY            7 (to 16)  3           2 LOAD_GLOBAL              0 (g)              4 LOAD_CONST               1 (0)              6 CALL_NO_KW               1              8 POP_TOP             10 POP_BLOCK             12 LOAD_CONST               0 (None)             14 RETURN_VALUE  4     >>   16 POP_TOP             18 POP_TOP             20 POP_TOP  5          22 POP_EXCEPT             24 LOAD_CONST               3 ('fail')             26 RETURN_VALUE

Note the explicit instructions to push and pop from the "block" stack:SETUP_FINALLY and POP_BLOCK.

In 3.11, the SETUP_FINALLY and POP_BLOCK are eliminated, replaced witha table to determine where to jump to when an exception is raised.

  1           0 RESUME                   0  2           2 NOP  3           4 LOAD_GLOBAL              1 (g + NULL)             16 LOAD_CONST               1 (0)             18 PRECALL                  1             22 CALL                     1             32 POP_TOP             34 LOAD_CONST               0 (None)             36 RETURN_VALUE>>   38 PUSH_EXC_INFO  4          40 POP_TOP  5          42 POP_EXCEPT             44 LOAD_CONST               2 ('fail')             46 RETURN_VALUE>>   48 COPY                     3             50 POP_EXCEPT             52 RERAISE                  1ExceptionTable:  4 to 32 -> 38 [0]  38 to 40 -> 48 [1] lasti

(Note this code is from , later versions may have slightlydifferent bytecode.)

If an instruction raises an exception then its offset is used to findthe target to jump to. For example, the CALL at offset 22, falls intothe range 4 to 32. So, if g() raises an exception, then control jumpsto offset 38.


Viewing latest article 1
Browse Latest Browse All 2

Trending Articles