@@ -40,27 +40,89 @@ def __call__(self, *args, **kwargs):
4040
4141def _compare_exc (label , lineno ):
4242 """Compat helper for comparing exceptions."""
43- return (
44- Instr ("COMPARE_OP" , Compare .EXC_MATCH , lineno = lineno )
45- if PY < (3 , 9 )
46- else Instr ("JUMP_IF_NOT_EXC_MATCH" , label , lineno = lineno )
47- )
43+ if PY < (3 , 9 ):
44+ return Instr ("COMPARE_OP" , Compare .EXC_MATCH , lineno = lineno )
45+ return Instr ("JUMP_IF_NOT_EXC_MATCH" , label , lineno = lineno )
4846
4947
5048def _jump_if_false (label , lineno ):
5149 """Compat helper for jumping if false after comparing exceptions."""
52- return Instr ("POP_JUMP_IF_FALSE" , label , lineno = lineno ) if PY < (3 , 9 ) else Instr ("NOP" , lineno = lineno )
50+ if PY < (3 , 9 ):
51+ return Instr ("POP_JUMP_IF_FALSE" , label , lineno = lineno )
52+ return Instr ("NOP" , lineno = lineno )
5353
5454
5555def _end_finally (lineno ):
5656 """Compat helper for ending finally blocks."""
5757 if PY < (3 , 9 ):
5858 return Instr ("END_FINALLY" , lineno = lineno )
59- elif PY < (3 , 10 ):
59+ if PY < (3 , 10 ):
6060 return Instr ("RERAISE" , lineno = lineno )
6161 return Instr ("RERAISE" , 0 , lineno = lineno )
6262
6363
64+ def _pop_except (lineno ):
65+ """Compat helper for popping except blocks."""
66+ if PY >= (3 ,):
67+ return Instr ("POP_EXCEPT" , lineno = lineno )
68+ return Instr ("NOP" , lineno = lineno )
69+
70+
71+ def _setup_block (label , lineno ):
72+ if PY < (3 , 8 ):
73+ return Instr ("SETUP_EXCEPT" , label , lineno = lineno )
74+ return Instr ("SETUP_FINALLY" , label , lineno = lineno )
75+
76+
77+ def _call_variadic (lineno ):
78+ if PY < (3 , 6 ):
79+ return Instr ("CALL_FUNCTION_VAR" , 0 , lineno = lineno )
80+ return Instr ("CALL_FUNCTION_EX" , 0 , lineno = lineno )
81+
82+
83+ def _add (lineno ):
84+ if PY < (3 , 11 ):
85+ return Instr ("INPLACE_ADD" , lineno = lineno )
86+ return Instr ("BINARY_OP" , b .BinaryOp .ADD , lineno = lineno )
87+
88+
89+ def _update_map_block (varkwargsname , lineno ):
90+ if PY < (3 , 11 ):
91+ return [
92+ Instr ("DUP_TOP" , lineno = lineno ),
93+ Instr ("LOAD_ATTR" , "update" , lineno = lineno ),
94+ Instr ("LOAD_FAST" , varkwargsname , lineno = lineno ),
95+ Instr ("CALL_FUNCTION" , 1 , lineno = lineno ),
96+ Instr ("POP_TOP" , lineno = lineno ),
97+ ]
98+
99+ return [
100+ Instr ("COPY" , 1 , lineno = lineno ),
101+ Instr ("LOAD_METHOD" , "update" , lineno = lineno ),
102+ Instr ("LOAD_FAST" , varkwargsname , lineno = lineno ),
103+ Instr ("PRECALL" , 1 , lineno = lineno ),
104+ Instr ("CALL" , 1 , lineno = lineno ),
105+ Instr ("POP_TOP" , lineno = lineno ),
106+ ]
107+
108+
109+ def _call_return_block (arg , lineno ):
110+ if PY < (3 , 11 ):
111+ return [
112+ Instr ("CALL_FUNCTION" , arg , lineno = lineno ),
113+ Instr ("RETURN_VALUE" , lineno = lineno ),
114+ ]
115+
116+ return [
117+ Instr ("PRECALL" , arg , lineno = lineno ),
118+ Instr ("CALL" , arg , lineno = lineno ),
119+ Instr ("RETURN_VALUE" , lineno = lineno ),
120+ ]
121+
122+
123+ FIRSTLINENO_OFFSET = int (PY >= (3 , 11 ))
124+
125+
64126# -----------------------------------------------------------------------------
65127# Generator Wrapping
66128# -----------------------------------------------------------------------------
@@ -91,7 +153,7 @@ def _wrap_generator(instrs, code, lineno):
91153 _yield = Label ()
92154
93155 instrs [- 1 :] = [
94- Instr ( "SETUP_EXCEPT" if PY < ( 3 , 8 ) else "SETUP_FINALLY" , stopiter , lineno = lineno ),
156+ _setup_block ( stopiter , lineno ),
95157 Instr ("DUP_TOP" , lineno = lineno ),
96158 Instr ("STORE_FAST" , "__ddgen" , lineno = lineno ),
97159 Instr ("LOAD_ATTR" , "send" , lineno = lineno ),
@@ -101,7 +163,7 @@ def _wrap_generator(instrs, code, lineno):
101163 loop ,
102164 Instr ("CALL_FUNCTION" , 1 , lineno = lineno ),
103165 _yield ,
104- Instr ( "SETUP_EXCEPT" if PY < ( 3 , 8 ) else "SETUP_FINALLY" , genexit , lineno = lineno ),
166+ _setup_block ( genexit , lineno = lineno ),
105167 Instr ("YIELD_VALUE" , lineno = lineno ),
106168 Instr ("POP_BLOCK" , lineno = lineno ),
107169 Instr ("LOAD_FAST" , "__ddgensend" , lineno = lineno ),
@@ -129,11 +191,11 @@ def _wrap_generator(instrs, code, lineno):
129191 Instr ("LOAD_ATTR" , "throw" , lineno = lineno ),
130192 Instr ("LOAD_CONST" , sys .exc_info , lineno = lineno ),
131193 Instr ("CALL_FUNCTION" , 0 , lineno = lineno ),
132- Instr ( "CALL_FUNCTION_VAR" if PY < ( 3 , 6 ) else "CALL_FUNCTION_EX" , 0 , lineno = lineno ),
194+ _call_variadic ( lineno ),
133195 # DEV: We cannot use ROT_FOUR because it was removed in 3.5 and added
134196 # back in 3.8
135197 Instr ("STORE_FAST" , "__value" , lineno = lineno ),
136- Instr ( "POP_EXCEPT" if PY >= ( 3 ,) else "NOP" , lineno = lineno ),
198+ _pop_except ( lineno ),
137199 Instr ("LOAD_FAST" , "__value" , lineno = lineno ),
138200 Instr ("JUMP_ABSOLUTE" , _yield , lineno = lineno ),
139201 stopiter , # except StopIteration:
@@ -144,7 +206,7 @@ def _wrap_generator(instrs, code, lineno):
144206 Instr ("POP_TOP" , lineno = lineno ),
145207 Instr ("POP_TOP" , lineno = lineno ),
146208 Instr ("POP_TOP" , lineno = lineno ),
147- Instr ( "POP_EXCEPT" if PY >= ( 3 ,) else "NOP" , lineno = lineno ),
209+ _pop_except ( lineno ),
148210 Instr ("LOAD_CONST" , None , lineno = lineno ),
149211 Instr ("RETURN_VALUE" , lineno = lineno ),
150212 propagate ,
@@ -160,7 +222,10 @@ def _wrap_generator_py311(instrs, code, lineno):
160222 pass
161223
162224
163- wrap_generator = _wrap_generator_py311 if PY >= (3 , 11 ) else _wrap_generator
225+ if PY >= (3 , 11 ):
226+ wrap_generator = _wrap_generator_py311
227+ else :
228+ wrap_generator = _wrap_generator
164229
165230
166231# -----------------------------------------------------------------------------
@@ -202,7 +267,7 @@ def _wrap_special_function_py3(instrs, code, lineno):
202267 _yield = Label ()
203268
204269 instrs [- 1 :] = [
205- Instr ( "SETUP_EXCEPT" if PY < ( 3 , 8 ) else "SETUP_FINALLY" , stopiter , lineno = lineno ),
270+ _setup_block ( stopiter , lineno = lineno ),
206271 Instr ("DUP_TOP" , lineno = lineno ),
207272 Instr ("STORE_FAST" , "__ddgen" , lineno = lineno ),
208273 Instr ("LOAD_ATTR" , "asend" , lineno = lineno ),
@@ -215,7 +280,7 @@ def _wrap_special_function_py3(instrs, code, lineno):
215280 Instr ("LOAD_CONST" , None , lineno = lineno ),
216281 Instr ("YIELD_FROM" , lineno = lineno ),
217282 _yield ,
218- Instr ( "SETUP_EXCEPT" if PY < ( 3 , 8 ) else "SETUP_FINALLY" , genexit , lineno = lineno ),
283+ _setup_block ( genexit , lineno = lineno ),
219284 Instr ("YIELD_VALUE" , lineno = lineno ),
220285 Instr ("POP_BLOCK" , lineno = lineno ),
221286 Instr ("LOAD_FAST" , "__ddgensend" , lineno = lineno ),
@@ -282,7 +347,10 @@ def _wrap_special_function_py311(instrs, code, lineno):
282347 pass
283348
284349
285- wrap_special_function = _wrap_special_function_py3 if sys .version_info < (3 , 11 ) else _wrap_special_function_py311
350+ if PY >= (3 , 11 ):
351+ wrap_special_function = _wrap_special_function_py311
352+ else :
353+ wrap_special_function = _wrap_special_function_py3
286354
287355
288356def wrap_bytecode (wrapper , wrapped ):
@@ -298,7 +366,7 @@ def wrap_bytecode(wrapper, wrapped):
298366 """
299367
300368 code = wrapped .__code__
301- lineno = code .co_firstlineno + ( sys . version_info >= ( 3 , 11 ))
369+ lineno = code .co_firstlineno + FIRSTLINENO_OFFSET
302370 varargs = bool (code .co_flags & CompilerFlags .VARARGS )
303371 varkwargs = bool (code .co_flags & CompilerFlags .VARKEYWORDS )
304372 nargs = code .co_argcount
@@ -317,7 +385,8 @@ def wrap_bytecode(wrapper, wrapped):
317385 Instr ("LOAD_CONST" , wrapper , lineno = lineno ),
318386 Instr ("LOAD_CONST" , wrapped , lineno = lineno ),
319387 ]
320- if sys .version_info >= (3 , 11 ):
388+ if PY >= (3 , 11 ):
389+ # THis is required to start a new frame
321390 instrs [0 :0 ] = [
322391 Instr ("RESUME" , 0 , lineno = lineno - 1 ),
323392 Instr ("PUSH_NULL" , lineno = lineno ),
@@ -331,9 +400,7 @@ def wrap_bytecode(wrapper, wrapped):
331400 instrs .extend (
332401 [
333402 Instr ("LOAD_FAST" , varargsname , lineno = lineno ),
334- Instr ("INPLACE_ADD" , lineno = lineno )
335- if sys .version_info < (3 , 11 )
336- else Instr ("BINARY_OP" , b .BinaryOp .ADD , lineno = lineno ),
403+ _add (lineno ),
337404 ]
338405 )
339406 elif varargs :
@@ -352,27 +419,7 @@ def wrap_bytecode(wrapper, wrapped):
352419 )
353420 instrs .append (Instr ("BUILD_MAP" , kwonlyargs , lineno = lineno ))
354421 if varkwargs :
355- if sys .version_info < (3 , 11 ):
356- instrs .extend (
357- [
358- Instr ("DUP_TOP" , lineno = lineno ),
359- Instr ("LOAD_ATTR" , "update" , lineno = lineno ),
360- Instr ("LOAD_FAST" , varkwargsname , lineno = lineno ),
361- Instr ("CALL_FUNCTION" , 1 , lineno = lineno ),
362- Instr ("POP_TOP" , lineno = lineno ),
363- ]
364- )
365- else :
366- instrs .extend (
367- [
368- Instr ("COPY" , 1 , lineno = lineno ),
369- Instr ("LOAD_METHOD" , "update" , lineno = lineno ),
370- Instr ("LOAD_FAST" , varkwargsname , lineno = lineno ),
371- Instr ("PRECALL" , 1 , lineno = lineno ),
372- Instr ("CALL" , 1 , lineno = lineno ),
373- Instr ("POP_TOP" , lineno = lineno ),
374- ]
375- )
422+ instrs .extend (_update_map_block (varkwargsname , lineno ))
376423
377424 elif varkwargs :
378425 instrs .append (Instr ("LOAD_FAST" , varkwargsname , lineno = lineno ))
@@ -382,21 +429,7 @@ def wrap_bytecode(wrapper, wrapped):
382429
383430 # Call the wrapper function with the wrapped function, the positional and
384431 # keyword arguments, and return the result.
385- if sys .version_info < (3 , 11 ):
386- instrs .extend (
387- [
388- Instr ("CALL_FUNCTION" , 3 , lineno = lineno ),
389- Instr ("RETURN_VALUE" , lineno = lineno ),
390- ]
391- )
392- else :
393- instrs .extend (
394- [
395- Instr ("PRECALL" , 3 , lineno = lineno ),
396- Instr ("CALL" , 3 , lineno = lineno ),
397- Instr ("RETURN_VALUE" , lineno = lineno ),
398- ]
399- )
432+ instrs .extend (_call_return_block (3 , lineno ))
400433
401434 # If the function has special flags set, like the generator, async generator
402435 # or coroutine, inject unraveling code before the return opcode.
0 commit comments