Hi all, I am the current maintainer of bytecode (https://github.com/MatthieuDartiailh/bytecode) which is a library to perform assembly and disassembly of Python bytecode. The library was created by V. Stinner. I started looking in Python 3.11 support in bytecode, I read Objects/exception_handling_notes.txt and I have a couple of questions regarding the exception table: Currently bytecode exposes three level of abstractions: - the concrete level in which one deals with instruction offset for jumps and explicit indexing into the known constants and names - the bytecode level which uses labels for jumps and allow non integer argument to instructions - the cfg level which provides basic blocks delineation over the bytecode level So my first idea was to directly expose the unpacked exception table (start, stop, target, stack_depth, last_i) at the concrete level and use pseudo-instruction and labels at the bytecode level. At this point of my reflections, I saw https://github.com/python/cpython/commit/c57aad777afc6c0b382981ee9e4bc94c03b... about adding pseudo-instructionto dis output in 3.12 and though it would line up quite nicely. Reading through, I got curious about how SETUP_WITH handled popping one extra item from the stack so I went to look at dis results on a couple of small examples. I tried on 3.10 and 3.11b3 (for some reasons I cannot compile main at a391b74d on windows). I looked at simple things and got a bit surprised: Disassembling: deff(): try: a= 1 except: raise I get on 3.11: 1 0 RESUME 0 2 2 NOP 3 4 LOAD_CONST 1 (1) 6 STORE_FAST 0 (a) 8 LOAD_CONST 0 (None) 10 RETURN_VALUE >> 12 PUSH_EXC_INFO 4 14 POP_TOP 5 16 RAISE_VARARGS 0 >> 18 COPY 3 20 POP_EXCEPT 22 RERAISE 1 ExceptionTable: 4 to 6 -> 12 [0] 12 to 16 -> 18 [1] lasti On 3.10: 2 0 SETUP_FINALLY 5 (to 12) 3 2 LOAD_CONST 1 (1) 4 STORE_FAST 0 (a) 6 POP_BLOCK 8 LOAD_CONST 0 (None) 10 RETURN_VALUE 4 >> 12 POP_TOP 14 POP_TOP 16 POP_TOP 5 18 RAISE_VARARGS 0 This surprised me on two levels: - first I have never seen the RESUME opcode and it is currently not documented - my second surprise comes from the second entry in the exception table. At first I failed to see why it was needed but writing this I realize it corresponds to the explicit handling of exception propagation to the caller. Since I cannot compile 3.12 ATM I am wondering how this plays with pseudo-instruction: in particular are pseudo-instructions generated for all entries in the exception table ? My initial idea was to have a SETUP_FINALLY/SETUP_CLEANUP - POP_BLOCK pair for each line in the exception table and label for the jump target. But I realize it means we will have many such pairs than in 3.10. It is fine by me but I wondered what choice was made in 3.12 dis and if this approach made sense. Best regards Matthieu