Labels don't seem to be handled correctly with Python<3.9
See original GitHub issueI am currently working with the following abstract code
stopiter = Label()
loop = Label()
genexit = Label()
exc = Label()
propagate = Label()
instrs[-1:-1] = [
Instr("DUP_TOP", lineno=lineno),
Instr("STORE_FAST", "__ddgen", lineno=lineno),
Instr("LOAD_ATTR", "asend", lineno=lineno),
Instr("STORE_FAST", "__ddgensend", lineno=lineno),
Instr("LOAD_FAST", "__ddgen", lineno=lineno),
Instr("LOAD_ATTR", "__anext__", lineno=lineno),
Instr("CALL_FUNCTION", 0, lineno=lineno),
loop,
Instr("SETUP_EXCEPT" if PY < (3, 8) else "SETUP_FINALLY", stopiter, lineno=lineno),
Instr("GET_AWAITABLE", lineno=lineno),
Instr("LOAD_CONST", None, lineno=lineno),
Instr("YIELD_FROM", lineno=lineno),
Instr("POP_BLOCK", lineno=lineno),
Instr("SETUP_EXCEPT" if PY < (3, 8) else "SETUP_FINALLY", genexit, lineno=lineno),
Instr("YIELD_VALUE", lineno=lineno),
Instr("POP_BLOCK", lineno=lineno),
Instr("LOAD_FAST", "__ddgensend", lineno=lineno),
Instr("ROT_TWO", lineno=lineno),
Instr("CALL_FUNCTION", 1, lineno=lineno),
Instr("JUMP_ABSOLUTE", loop, lineno=lineno),
stopiter, # except StopAsyncIteration:
Instr("DUP_TOP", lineno=lineno),
Instr("LOAD_CONST", StopAsyncIteration, lineno=lineno),
compare_exc(propagate, lineno),
jump_if_false(propagate, lineno),
Instr("POP_TOP", lineno=lineno),
Instr("POP_TOP", lineno=lineno),
Instr("POP_TOP", lineno=lineno),
Instr("POP_EXCEPT", lineno=lineno),
Instr("LOAD_CONST", None, lineno=lineno),
Instr("RETURN_VALUE", lineno=lineno),
propagate, # finally:
Instr("END_FINALLY" if PY < (3, 9) else "RERAISE", lineno=lineno),
genexit, # except GeneratorExit:
Instr("DUP_TOP", lineno=lineno),
Instr("LOAD_CONST", GeneratorExit, lineno=lineno),
compare_exc(exc, lineno),
jump_if_false(exc, lineno),
Instr("POP_TOP", lineno=lineno),
Instr("POP_TOP", lineno=lineno),
Instr("POP_TOP", lineno=lineno),
Instr("LOAD_FAST", "__ddgen", lineno=lineno),
Instr("LOAD_ATTR", "aclose", lineno=lineno),
Instr("CALL_FUNCTION", 0, lineno=lineno),
Instr("GET_AWAITABLE", lineno=lineno),
Instr("LOAD_CONST", None, lineno=lineno),
Instr("YIELD_FROM", lineno=lineno),
Instr("POP_EXCEPT", lineno=lineno),
Instr("RETURN_VALUE", lineno=lineno),
exc, # except:
Instr("POP_TOP", lineno=lineno),
Instr("POP_TOP", lineno=lineno),
Instr("POP_TOP", lineno=lineno),
Instr("LOAD_FAST", "__ddgen", lineno=lineno),
Instr("LOAD_ATTR", "athrow", lineno=lineno),
Instr("LOAD_CONST", sys.exc_info, lineno=lineno),
Instr("CALL_FUNCTION", 0, lineno=lineno),
Instr("CALL_FUNCTION_EX", 0, lineno=lineno),
Instr("GET_AWAITABLE", lineno=lineno),
Instr("LOAD_CONST", None, lineno=lineno),
Instr("YIELD_FROM", lineno=lineno),
Instr("POP_EXCEPT", lineno=lineno),
Instr("RETURN_VALUE", lineno=lineno),
]
When compiled to concrete Python 3.9 bytecode I get what I would expect (note the correct jump to RERAISE
)
12 DUP_TOP
14 STORE_FAST 1 (__ddgen)
16 LOAD_ATTR 0 (asend)
18 STORE_FAST 2 (__ddgensend)
20 LOAD_FAST 1 (__ddgen)
22 LOAD_ATTR 1 (__anext__)
24 CALL_FUNCTION 0
>> 26 SETUP_FINALLY 22 (to 50)
28 GET_AWAITABLE
30 LOAD_CONST 2 (None)
32 YIELD_FROM
34 POP_BLOCK
36 SETUP_FINALLY 34 (to 72)
38 YIELD_VALUE
40 POP_BLOCK
42 LOAD_FAST 2 (__ddgensend)
44 ROT_TWO
46 CALL_FUNCTION 1
48 JUMP_ABSOLUTE 26
>> 50 DUP_TOP
52 LOAD_CONST 3 (<class 'StopAsyncIteration'>)
54 JUMP_IF_NOT_EXC_MATCH 70
56 NOP
58 POP_TOP
60 POP_TOP
62 POP_TOP
64 POP_EXCEPT
66 LOAD_CONST 2 (None)
68 RETURN_VALUE
>> 70 RERAISE
>> 72 DUP_TOP
74 LOAD_CONST 4 (<class 'GeneratorExit'>)
76 JUMP_IF_NOT_EXC_MATCH 102
78 NOP
80 POP_TOP
82 POP_TOP
84 POP_TOP
86 LOAD_FAST 1 (__ddgen)
88 LOAD_ATTR 2 (aclose)
90 CALL_FUNCTION 0
92 GET_AWAITABLE
94 LOAD_CONST 2 (None)
96 YIELD_FROM
98 POP_EXCEPT
100 RETURN_VALUE
>> 102 POP_TOP
104 POP_TOP
106 POP_TOP
108 LOAD_FAST 1 (__ddgen)
110 LOAD_ATTR 3 (athrow)
112 LOAD_CONST 5 (<built-in function exc_info>)
114 CALL_FUNCTION 0
116 CALL_FUNCTION_EX 0
118 GET_AWAITABLE
120 LOAD_CONST 2 (None)
122 YIELD_FROM
124 POP_EXCEPT
126 RETURN_VALUE
128 RETURN_VALUE
However, with earlier Python versions the jump to the propagate
label is not resolved correctly and actually ends up targeting the exc
label (END_FINALLY
is now in place of the newer RERASE
, but the jump is not there!):
12 DUP_TOP
14 STORE_FAST 1 (__ddgen)
16 LOAD_ATTR 0 (asend)
18 STORE_FAST 2 (__ddgensend)
20 LOAD_FAST 1 (__ddgen)
22 LOAD_ATTR 1 (__anext__)
24 CALL_FUNCTION 0
>> 26 SETUP_FINALLY 22 (to 50)
28 GET_AWAITABLE
30 LOAD_CONST 2 (None)
32 YIELD_FROM
34 POP_BLOCK
36 SETUP_FINALLY 34 (to 72)
38 YIELD_VALUE
40 POP_BLOCK
42 LOAD_FAST 2 (__ddgensend)
44 ROT_TWO
46 CALL_FUNCTION 1
48 JUMP_ABSOLUTE 26
>> 50 DUP_TOP
52 LOAD_CONST 3 (<class 'StopAsyncIteration'>)
54 COMPARE_OP 10 (exception match)
56 POP_JUMP_IF_FALSE 102
58 POP_TOP
60 POP_TOP
62 POP_TOP
64 POP_EXCEPT
66 LOAD_CONST 2 (None)
68 RETURN_VALUE
70 END_FINALLY
>> 72 DUP_TOP
74 LOAD_CONST 4 (<class 'GeneratorExit'>)
76 COMPARE_OP 10 (exception match)
78 POP_JUMP_IF_FALSE 102
80 POP_TOP
82 POP_TOP
84 POP_TOP
86 LOAD_FAST 1 (__ddgen)
88 LOAD_ATTR 2 (aclose)
90 CALL_FUNCTION 0
92 GET_AWAITABLE
94 LOAD_CONST 2 (None)
96 YIELD_FROM
98 POP_EXCEPT
100 RETURN_VALUE
>> 102 POP_TOP
104 POP_TOP
106 POP_TOP
108 LOAD_FAST 1 (__ddgen)
110 LOAD_ATTR 3 (athrow)
112 LOAD_CONST 5 (<built-in function exc_info>)
114 CALL_FUNCTION 0
116 CALL_FUNCTION_EX 0
118 GET_AWAITABLE
120 LOAD_CONST 2 (None)
122 YIELD_FROM
124 POP_EXCEPT
126 RETURN_VALUE
128 RETURN_VALUE
This seems to point to a wrong resolution of the branching label.
Issue Analytics
- State:
- Created 2 years ago
- Comments:5 (5 by maintainers)
Top Results From Across the Web
Cannot install fairseq==0.10.2 with python 3.9 #3535 - GitHub
I don't seem to be able to install fairseq==0.10.2 with python 3.9 on macOS 11.3 $ pip install fairseq==0.10.2 Collecting fairseq==0.10.2 ...
Read more >No handles with labels found to put in legend - Stack Overflow
No handles with labels found to put in legend. I'm not sure why, because, based on the documentation for plt.arrow() , label is...
Read more >Changelog — Python 3.11.1 documentation
gh-84461: run_tests.py now handles cross compiling env vars correctly and pass HOSTRUNNER to regression tests. gh-93616: test_modulefinder now ...
Read more >[Errno 24] "Too many open files" when running a docker agent ...
_execute('get', server) File "/home/Skam/.local/lib/python3.9/site-packages/ ... seems to handle that at every pull), and if this was the case I don't think ...
Read more >IO tools (text, CSV, HDF5, …) — pandas 1.5.2 documentation
Column(s) to use as the row labels of the DataFrame , either given as string ... [53]: pd.read_csv(StringIO(data)) Out[53]: a b ...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Always happy to help !
Big facepalm moment! Your last question helped me find the actual issue, which was due to copy-pasta in my code! 😢 These are the functions
which are defined locally inside another function. I had
exc
in place oflabel
injump_if_false
. So indeed the generated bytecode was correct as it was gettingexc
from the outer scope! 😭 . Now that gives meRuntimeError: Failed to compute stacksize, got negative size
but I should be able to fix this.Apologies for this non-issue!