Skip to content

Commit 53726a1

Browse files
authored
chore: fix wrapping for 3.13+ (#15313)
## Description We fix the bytecode wrapping to properly support 3.13 and later versions of CPython.
1 parent 2f862fe commit 53726a1

File tree

4 files changed

+224
-27
lines changed

4 files changed

+224
-27
lines changed

ddtrace/internal/assembly.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ def transform_instruction(opcode: str, arg: t.Any) -> t.Tuple[str, t.Any]:
4646
opcode = "LOAD_ATTR"
4747
arg = (True, arg)
4848
elif opcode.upper() == "LOAD_ATTR" and not isinstance(arg, tuple):
49-
arg = (sys.version_info >= (3, 14), arg)
49+
arg = (False, arg)
5050

5151
return opcode, arg
5252

ddtrace/internal/wrapping/asyncs.py

Lines changed: 135 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,10 @@
3434
ASYNC_GEN_ASSEMBLY = Assembly()
3535
ASYNC_HEAD_ASSEMBLY = None
3636

37-
if PY >= (3, 14):
37+
if PY >= (3, 15):
38+
raise NotImplementedError("This version of CPython is not supported yet")
39+
40+
elif PY >= (3, 14):
3841
ASYNC_HEAD_ASSEMBLY = Assembly()
3942
ASYNC_HEAD_ASSEMBLY.parse(
4043
r"""
@@ -50,7 +53,7 @@
5053
5154
presend:
5255
send @send
53-
yield_value 2
56+
yield_value 0
5457
resume 3
5558
jump_backward_no_interrupt @presend
5659
send:
@@ -77,20 +80,19 @@
7780
tried
7881
7982
try @genexit lasti
80-
yield_value 3
83+
yield_value 0
8184
resume 3
8285
jump_backward_no_interrupt @loop
8386
send0:
8487
end_send
8588
8689
yield:
8790
call_intrinsic_1 asm.Intrinsic1Op.INTRINSIC_ASYNC_GEN_WRAP
88-
yield_value 3
91+
yield_value 0
8992
resume 1
9093
push_null
91-
swap 2
9294
load_fast $__ddgensend
93-
swap 2
95+
swap 3
9496
call 1
9597
jump_backward @loop
9698
tried
@@ -110,7 +112,7 @@
110112
111113
presend1:
112114
send @send1
113-
yield_value 4
115+
yield_value 0
114116
resume 3
115117
jump_backward_no_interrupt @presend1
116118
send1:
@@ -122,19 +124,20 @@
122124
123125
exc:
124126
pop_top
125-
push_null
126127
load_fast $__ddgen
127128
load_attr (False, 'athrow')
128129
push_null
129130
load_const sys.exc_info
131+
push_null
130132
call 0
133+
push_null
131134
call_function_ex
132135
get_awaitable 0
133136
load_const None
134137
135138
presend2:
136139
send @send2
137-
yield_value 4
140+
yield_value 0
138141
resume 3
139142
jump_backward_no_interrupt @presend2
140143
send2:
@@ -159,6 +162,129 @@
159162
"""
160163
)
161164

165+
elif PY >= (3, 13):
166+
ASYNC_HEAD_ASSEMBLY = Assembly()
167+
ASYNC_HEAD_ASSEMBLY.parse(
168+
r"""
169+
return_generator
170+
pop_top
171+
"""
172+
)
173+
174+
COROUTINE_ASSEMBLY.parse(
175+
r"""
176+
get_awaitable 0
177+
load_const None
178+
179+
presend:
180+
send @send
181+
yield_value 0
182+
resume 3
183+
jump_backward_no_interrupt @presend
184+
send:
185+
end_send
186+
"""
187+
)
188+
189+
ASYNC_GEN_ASSEMBLY.parse(
190+
r"""
191+
try @stopiter
192+
copy 1
193+
store_fast $__ddgen
194+
load_attr (False, 'asend')
195+
store_fast $__ddgensend
196+
load_fast $__ddgen
197+
load_attr (True, '__anext__')
198+
call 0
199+
200+
loop:
201+
get_awaitable 0
202+
load_const None
203+
presend0:
204+
send @send0
205+
tried
206+
207+
try @genexit lasti
208+
yield_value 0
209+
resume 3
210+
jump_backward_no_interrupt @loop
211+
send0:
212+
end_send
213+
214+
yield:
215+
call_intrinsic_1 asm.Intrinsic1Op.INTRINSIC_ASYNC_GEN_WRAP
216+
yield_value 0
217+
resume 1
218+
push_null
219+
load_fast $__ddgensend
220+
swap 3
221+
call 1
222+
jump_backward @loop
223+
tried
224+
225+
genexit:
226+
try @stopiter
227+
push_exc_info
228+
load_const GeneratorExit
229+
check_exc_match
230+
pop_jump_if_false @exc
231+
pop_top
232+
load_fast $__ddgen
233+
load_attr (True, 'aclose')
234+
call 0
235+
get_awaitable 0
236+
load_const None
237+
238+
presend1:
239+
send @send1
240+
yield_value 0
241+
resume 3
242+
jump_backward_no_interrupt @presend1
243+
send1:
244+
end_send
245+
pop_top
246+
pop_except
247+
load_const None
248+
return_value
249+
250+
exc:
251+
pop_top
252+
load_fast $__ddgen
253+
load_attr (False, 'athrow')
254+
push_null
255+
load_const sys.exc_info
256+
push_null
257+
call 0
258+
call_function_ex 0
259+
get_awaitable 0
260+
load_const None
261+
262+
presend2:
263+
send @send2
264+
yield_value 0
265+
resume 3
266+
jump_backward_no_interrupt @presend2
267+
send2:
268+
end_send
269+
swap 2
270+
pop_except
271+
jump_backward @yield
272+
tried
273+
274+
stopiter:
275+
push_exc_info
276+
load_const StopAsyncIteration
277+
check_exc_match
278+
pop_jump_if_false @propagate
279+
pop_top
280+
pop_except
281+
load_const None
282+
return_value
283+
284+
propagate:
285+
reraise 0
286+
"""
287+
)
162288

163289
elif PY >= (3, 12):
164290
ASYNC_HEAD_ASSEMBLY = Assembly()

ddtrace/internal/wrapping/generators.py

Lines changed: 86 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,10 @@
3030
GENERATOR_ASSEMBLY = Assembly()
3131
GENERATOR_HEAD_ASSEMBLY = None
3232

33-
if PY >= (3, 14):
33+
if PY >= (3, 15):
34+
raise NotImplementedError("This version of CPython is not supported yet")
35+
36+
elif PY >= (3, 14):
3437
GENERATOR_HEAD_ASSEMBLY = Assembly()
3538
GENERATOR_HEAD_ASSEMBLY.parse(
3639
r"""
@@ -46,8 +49,86 @@
4649
store_fast $__ddgen
4750
load_attr $send
4851
store_fast $__ddgensend
52+
load_const next
53+
push_null
54+
load_fast_borrow $__ddgen
55+
56+
loop:
57+
call 1
58+
tried
59+
60+
yield:
61+
try @genexit lasti
62+
yield_value 0
63+
resume 1
4964
push_null
65+
load_fast_borrow $__ddgensend
66+
swap 3
67+
jump_backward @loop
68+
tried
69+
70+
genexit:
71+
try @stopiter
72+
push_exc_info
73+
load_const GeneratorExit
74+
check_exc_match
75+
pop_jump_if_false @exc
76+
pop_top
77+
load_fast $__ddgen
78+
load_method $close
79+
call 0
80+
swap 2
81+
pop_except
82+
return_value
83+
84+
exc:
85+
pop_top
86+
load_fast $__ddgen
87+
load_attr $throw
88+
push_null
89+
load_const sys.exc_info
90+
push_null
91+
call 0
92+
push_null
93+
call_function_ex
94+
swap 2
95+
pop_except
96+
jump_backward @yield
97+
tried
98+
99+
stopiter:
100+
push_exc_info
101+
load_const StopIteration
102+
check_exc_match
103+
pop_jump_if_false @propagate
104+
pop_top
105+
pop_except
106+
load_const None
107+
return_value
108+
109+
propagate:
110+
reraise 0
111+
"""
112+
)
113+
114+
elif PY >= (3, 13):
115+
GENERATOR_HEAD_ASSEMBLY = Assembly()
116+
GENERATOR_HEAD_ASSEMBLY.parse(
117+
r"""
118+
return_generator
119+
pop_top
120+
"""
121+
)
122+
123+
GENERATOR_ASSEMBLY.parse(
124+
r"""
125+
try @stopiter
126+
copy 1
127+
store_fast $__ddgen
128+
load_attr $send
129+
store_fast $__ddgensend
50130
load_const next
131+
push_null
51132
load_fast $__ddgen
52133
53134
loop:
@@ -56,12 +137,11 @@
56137
57138
yield:
58139
try @genexit lasti
59-
yield_value 3
140+
yield_value 0
60141
resume 1
61142
push_null
62-
swap 2
63143
load_fast $__ddgensend
64-
swap 2
144+
swap 3
65145
jump_backward @loop
66146
tried
67147
@@ -81,13 +161,13 @@
81161
82162
exc:
83163
pop_top
84-
push_null
85164
load_fast $__ddgen
86165
load_attr $throw
87166
push_null
88167
load_const sys.exc_info
168+
push_null
89169
call 0
90-
call_function_ex
170+
call_function_ex 0
91171
swap 2
92172
pop_except
93173
jump_backward @yield

0 commit comments

Comments
 (0)