]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.13] gh-128078: Clear exception in `anext` before calling `_PyGen_SetStopIterationV...
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Mon, 13 Jan 2025 13:20:49 +0000 (14:20 +0100)
committerGitHub <noreply@github.com>
Mon, 13 Jan 2025 13:20:49 +0000 (13:20 +0000)
gh-128078: Clear exception in `anext` before calling `_PyGen_SetStopIterationValue` (GH-128780)
(cherry picked from commit 76ffaef729c91bb79da6df2ade48f3ec51118300)

Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com>
Co-authored-by: Kumar Aditya <kumaraditya@python.org>
Lib/test/test_asyncgen.py
Misc/NEWS.d/next/Core_and_Builtins/2025-01-13-12-48-30.gh-issue-128078.qOsl9B.rst [new file with mode: 0644]
Objects/genobject.c
Objects/iterobject.c

index 4f2278bb263681aa90804d9918dcfc5195499e98..16164492b25690550f9c60266f2a0ea9391755e6 100644 (file)
@@ -1152,6 +1152,23 @@ class AsyncGenAsyncioTest(unittest.TestCase):
 
         self.loop.run_until_complete(run())
 
+    def test_async_gen_asyncio_anext_tuple_no_exceptions(self):
+        # StopAsyncIteration exceptions should be cleared.
+        # See: https://github.com/python/cpython/issues/128078.
+
+        async def foo():
+            if False:
+                yield (1, 2)
+
+        async def run():
+            it = foo().__aiter__()
+            with self.assertRaises(StopAsyncIteration):
+                await it.__anext__()
+            res = await anext(it, ('a', 'b'))
+            self.assertEqual(res, ('a', 'b'))
+
+        self.loop.run_until_complete(run())
+
     def test_async_gen_asyncio_anext_stopiteration(self):
         async def foo():
             try:
diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-01-13-12-48-30.gh-issue-128078.qOsl9B.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-01-13-12-48-30.gh-issue-128078.qOsl9B.rst
new file mode 100644 (file)
index 0000000..498864a
--- /dev/null
@@ -0,0 +1,2 @@
+Fix a :exc:`SystemError` when using :func:`anext` with a default tuple
+value. Patch by Bénédikt Tran.
index 92cd8c61e7e9ca251ce66e5ef4b08a3b2e8ffb54..524cda1487813c7d2e9c84ebece1bf18de4dd0ac 100644 (file)
@@ -604,6 +604,7 @@ gen_iternext(PyGenObject *gen)
 int
 _PyGen_SetStopIterationValue(PyObject *value)
 {
+    assert(!PyErr_Occurred());
     PyObject *e;
 
     if (value == NULL ||
index 135ced9ea1f2685ec5af9a70d356721fc6ca4dcd..ebb342ff1092224611e0d830ad9c07ab0ca277a5 100644 (file)
@@ -384,6 +384,7 @@ anextawaitable_iternext(anextawaitableobject *obj)
         return result;
     }
     if (PyErr_ExceptionMatches(PyExc_StopAsyncIteration)) {
+        PyErr_Clear();
         _PyGen_SetStopIterationValue(obj->default_value);
     }
     return NULL;
@@ -407,6 +408,7 @@ anextawaitable_proxy(anextawaitableobject *obj, char *meth, PyObject *arg) {
          * exception we replace it with a `StopIteration(default)`, as if
          * it was the return value of `__anext__()` coroutine.
          */
+        PyErr_Clear();
         _PyGen_SetStopIterationValue(obj->default_value);
     }
     return NULL;