bpo-35409: Ignore GeneratorExit in async_gen_athrow_throw (GH-14755)
Ignore `GeneratorExit` exceptions when throwing an exception into the `aclose` coroutine of an asynchronous generator.
https://bugs.python.org/issue35409
(cherry picked from commit 8e0de2a480
)
Co-authored-by: Vincent Michel <vxgmichel@gmail.com>
This commit is contained in:
parent
c749326d24
commit
6c3b471c8c
|
@ -735,6 +735,33 @@ class AsyncGenAsyncioTest(unittest.TestCase):
|
|||
self.loop.run_until_complete(run())
|
||||
self.assertEqual(DONE, 10)
|
||||
|
||||
def test_async_gen_asyncio_aclose_12(self):
|
||||
DONE = 0
|
||||
|
||||
async def target():
|
||||
await asyncio.sleep(0.01)
|
||||
1 / 0
|
||||
|
||||
async def foo():
|
||||
nonlocal DONE
|
||||
task = asyncio.create_task(target())
|
||||
try:
|
||||
yield 1
|
||||
finally:
|
||||
try:
|
||||
await task
|
||||
except ZeroDivisionError:
|
||||
DONE = 1
|
||||
|
||||
async def run():
|
||||
gen = foo()
|
||||
it = gen.__aiter__()
|
||||
await it.__anext__()
|
||||
await gen.aclose()
|
||||
|
||||
self.loop.run_until_complete(run())
|
||||
self.assertEqual(DONE, 1)
|
||||
|
||||
def test_async_gen_asyncio_asend_01(self):
|
||||
DONE = 0
|
||||
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
Ignore GeneratorExit exceptions when throwing an exception into the aclose
|
||||
coroutine of an asynchronous generator.
|
|
@ -1947,6 +1947,17 @@ async_gen_athrow_throw(PyAsyncGenAThrow *o, PyObject *args)
|
|||
PyErr_SetString(PyExc_RuntimeError, ASYNC_GEN_IGNORED_EXIT_MSG);
|
||||
return NULL;
|
||||
}
|
||||
if (PyErr_ExceptionMatches(PyExc_StopAsyncIteration) ||
|
||||
PyErr_ExceptionMatches(PyExc_GeneratorExit))
|
||||
{
|
||||
/* when aclose() is called we don't want to propagate
|
||||
StopAsyncIteration or GeneratorExit; just raise
|
||||
StopIteration, signalling that this 'aclose()' await
|
||||
is done.
|
||||
*/
|
||||
PyErr_Clear();
|
||||
PyErr_SetNone(PyExc_StopIteration);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue