Skip to content

Commit 4facd7d

Browse files
miss-islingtonpicnixzkumaraditya303
authored
[3.12] gh-128078: Clear exception in anext before calling _PyGen_SetStopIterationValue (GH-128780) (#128784)
gh-128078: Clear exception in `anext` before calling `_PyGen_SetStopIterationValue` (GH-128780) (cherry picked from commit 76ffaef) Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com> Co-authored-by: Kumar Aditya <kumaraditya@python.org>
1 parent 8448552 commit 4facd7d

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
@@ -1100,6 +1100,23 @@ async def run():
11001100

11011101
self.loop.run_until_complete(run())
11021102

1103+
def test_async_gen_asyncio_anext_tuple_no_exceptions(self):
1104+
# StopAsyncIteration exceptions should be cleared.
1105+
# See: https://github.com/python/cpython/issues/128078.
1106+
1107+
async def foo():
1108+
if False:
1109+
yield (1, 2)
1110+
1111+
async def run():
1112+
it = foo().__aiter__()
1113+
with self.assertRaises(StopAsyncIteration):
1114+
await it.__anext__()
1115+
res = await anext(it, ('a', 'b'))
1116+
self.assertEqual(res, ('a', 'b'))
1117+
1118+
self.loop.run_until_complete(run())
1119+
11031120
def test_async_gen_asyncio_anext_stopiteration(self):
11041121
async def foo():
11051122
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
@@ -618,6 +618,7 @@ gen_iternext(PyGenObject *gen)
618618
int
619619
_PyGen_SetStopIterationValue(PyObject *value)
620620
{
621+
assert(!PyErr_Occurred());
621622
PyObject *e;
622623

623624
if (value == NULL ||

Objects/iterobject.c

+2
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,7 @@ anextawaitable_iternext(anextawaitableobject *obj)
382382
return result;
383383
}
384384
if (PyErr_ExceptionMatches(PyExc_StopAsyncIteration)) {
385+
PyErr_Clear();
385386
_PyGen_SetStopIterationValue(obj->default_value);
386387
}
387388
return NULL;
@@ -405,6 +406,7 @@ anextawaitable_proxy(anextawaitableobject *obj, char *meth, PyObject *arg) {
405406
* exception we replace it with a `StopIteration(default)`, as if
406407
* it was the return value of `__anext__()` coroutine.
407408
*/
409+
PyErr_Clear();
408410
_PyGen_SetStopIterationValue(obj->default_value);
409411
}
410412
return NULL;

0 commit comments

Comments
 (0)