Commit e83ff762 authored by Stefan Behnel's avatar Stefan Behnel

Fix temp cleanup in async functions when the return value is in a temp variable.

Closes #3337.
parent 373e59c4
...@@ -5,6 +5,9 @@ Cython Changelog ...@@ -5,6 +5,9 @@ Cython Changelog
0.29.15 (20??-??-??) 0.29.15 (20??-??-??)
==================== ====================
* Crash when returning a temporary Python object from an async-def function.
(Github issue #3337)
* Crash when using ``**kwargs`` in generators. * Crash when using ``**kwargs`` in generators.
Patch by David Woods. (Github issue #3265) Patch by David Woods. (Github issue #3265)
......
...@@ -5996,6 +5996,7 @@ class ReturnStatNode(StatNode): ...@@ -5996,6 +5996,7 @@ class ReturnStatNode(StatNode):
rhs=value, rhs=value,
code=code, code=code,
have_gil=self.in_nogil_context) have_gil=self.in_nogil_context)
value.generate_post_assignment_code(code)
elif self.in_generator: elif self.in_generator:
# return value == raise StopIteration(value), but uncatchable # return value == raise StopIteration(value), but uncatchable
code.globalstate.use_utility_code( code.globalstate.use_utility_code(
...@@ -6009,7 +6010,7 @@ class ReturnStatNode(StatNode): ...@@ -6009,7 +6010,7 @@ class ReturnStatNode(StatNode):
code.putln("%s = %s;" % ( code.putln("%s = %s;" % (
Naming.retval_cname, Naming.retval_cname,
value.result_as(self.return_type))) value.result_as(self.return_type)))
value.generate_post_assignment_code(code) value.generate_post_assignment_code(code)
value.free_temps(code) value.free_temps(code)
else: else:
if self.return_type.is_pyobject: if self.return_type.is_pyobject:
......
# cython: language_level=3, binding=True
# mode: run
# tag: pep492, await, gh3337
"""
Cython specific tests in addition to "test_coroutines_pep492.pyx"
(which is copied from CPython).
"""
import sys
def run_async(coro):
#assert coro.__class__ is types.GeneratorType
assert coro.__class__.__name__ in ('coroutine', '_GeneratorWrapper'), coro.__class__.__name__
buffer = []
result = None
while True:
try:
buffer.append(coro.send(None))
except StopIteration as ex:
result = ex.value if sys.version_info >= (3, 5) else ex.args[0] if ex.args else None
break
return buffer, result
async def test_async_temp_gh3337(x, y):
"""
>>> run_async(test_async_temp_gh3337(2, 3))
([], -1)
>>> run_async(test_async_temp_gh3337(3, 2))
([], 0)
"""
return min(x - y, 0)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment