Skip to content

Commit 76ffaef

Browse files
gh-128078: Clear exception in anext before calling _PyGen_SetStopIterationValue (#128780)
Co-authored-by: Kumar Aditya <kumaraditya@python.org>
1 parent 517dc65 commit 76ffaef

File tree

4 files changed

+22
-0
lines changed

4 files changed

+22
-0
lines changed

Lib/test/test_asyncgen.py

+17
Original file line numberDiff line numberDiff line change
@@ -1152,6 +1152,23 @@ async def run():
11521152

11531153
self.loop.run_until_complete(run())
11541154

1155+
def test_async_gen_asyncio_anext_tuple_no_exceptions(self):
1156+
# StopAsyncIteration exceptions should be cleared.
1157+
# See: https://github.com/python/cpython/issues/128078.
1158+
1159+
async def foo():
1160+
if False:
1161+
yield (1, 2)
1162+
1163+
async def run():
1164+
it = foo().__aiter__()
1165+
with self.assertRaises(StopAsyncIteration):
1166+
await it.__anext__()
1167+
res = await anext(it, ('a', 'b'))
1168+
self.assertEqual(res, ('a', 'b'))
1169+
1170+
self.loop.run_until_complete(run())
1171+
11551172
def test_async_gen_asyncio_anext_stopiteration(self):
11561173
async def foo():
11571174
try:
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix a :exc:`SystemError` when using :func:`anext` with a default tuple
2+
value. Patch by Bénédikt Tran.

Objects/genobject.c

+1
Original file line numberDiff line numberDiff line change
@@ -633,6 +633,7 @@ gen_iternext(PyObject *self)
633633
int
634634
_PyGen_SetStopIterationValue(PyObject *value)
635635
{
636+
assert(!PyErr_Occurred());
636637
PyObject *e;
637638

638639
if (value == NULL ||

Objects/iterobject.c

+2
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,7 @@ anextawaitable_iternext(anextawaitableobject *obj)
384384
return result;
385385
}
386386
if (PyErr_ExceptionMatches(PyExc_StopAsyncIteration)) {
387+
PyErr_Clear();
387388
_PyGen_SetStopIterationValue(obj->default_value);
388389
}
389390
return NULL;
@@ -407,6 +408,7 @@ anextawaitable_proxy(anextawaitableobject *obj, char *meth, PyObject *arg) {
407408
* exception we replace it with a `StopIteration(default)`, as if
408409
* it was the return value of `__anext__()` coroutine.
409410
*/
411+
PyErr_Clear();
410412
_PyGen_SetStopIterationValue(obj->default_value);
411413
}
412414
return NULL;

0 commit comments

Comments
 (0)