Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork33.7k
Closed
Description
Bug report
Input:
def f(): try: x = "try" except: x = "except" finally: x = "finally" return ximport disdis.dis(f)Output:
1 0 RESUME 0 2 2 NOP 3 4 LOAD_CONST 1 ('try') 6 STORE_FAST 0 (x) 8 JUMP_FORWARD 9 (to 28) >> 10 PUSH_EXC_INFO 4 12 POP_TOP 5 14 LOAD_CONST 2 ('except') 16 STORE_FAST 0 (x) 18 POP_EXCEPT 20 JUMP_FORWARD 8 (to 38) >> 22 COPY 3 24 POP_EXCEPT 26 RERAISE 1 3 >> 28 NOP 7 30 LOAD_CONST 3 ('finally') 32 STORE_FAST 0 (x) 8 34 LOAD_FAST 0 (x) 36 RETURN_VALUE 5 >> 38 NOP 7 40 LOAD_CONST 3 ('finally') 42 STORE_FAST 0 (x) 8 44 LOAD_FAST 0 (x) 46 RETURN_VALUE >> 48 PUSH_EXC_INFO 7 50 LOAD_CONST 3 ('finally') 52 STORE_FAST 0 (x) 8 54 LOAD_FAST 0 (x) 56 SWAP 2 58 POP_TOP 60 SWAP 2 62 POP_EXCEPT 64 RETURN_VALUE >> 66 COPY 3 68 POP_EXCEPT 70 RERAISE 1ExceptionTable: 4 to 6 -> 10 [0] 8 to 8 -> 48 [0] 10 to 16 -> 22 [1] lasti 18 to 26 -> 48 [0] 48 to 60 -> 66 [1] lastiLines 28-36 are exactly the same as lines 38-46. The reason they got duplicated is because ofduplicate_exits_without_lineno, which makes copies of exit blocks that don't have a line number, and can be reached from more than one place (because line numbers are static).
However, the check is "is it an exit block and does the first instruction have a lineno". In our case, the first instruction is a virtual POP_BLOCK (which eventually becomes a NOP). The virtual instruction doesn't have a line number, but the following instructions (the finally body) do. Note that what we really care about is whether the last instruction has a line number.