]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-131670: Fix crash in `anext()` when `__anext__` is sync and raises (#131682)
authorsobolevn <mail@sobolevn.me>
Mon, 24 Mar 2025 19:00:48 +0000 (22:00 +0300)
committerGitHub <noreply@github.com>
Mon, 24 Mar 2025 19:00:48 +0000 (19:00 +0000)
Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com>
Lib/test/test_asyncgen.py
Misc/NEWS.d/next/Core_and_Builtins/2025-03-24-19-38-53.gh-issue-131670.IffOZj.rst [new file with mode: 0644]
Python/bltinmodule.c

index b81187871753b9e6fc03f59c0d08c5efd0ef8cc5..d7dcf619300b2bb637f843c7a7e610de48f97aa7 100644 (file)
@@ -1169,6 +1169,26 @@ class AsyncGenAsyncioTest(unittest.TestCase):
 
         self.loop.run_until_complete(run())
 
+    def test_sync_anext_raises_exception(self):
+        # See: https://github.com/python/cpython/issues/131670
+        msg = 'custom'
+        for exc_type in [
+            StopAsyncIteration,
+            StopIteration,
+            ValueError,
+            Exception,
+        ]:
+            exc = exc_type(msg)
+            with self.subTest(exc=exc):
+                class A:
+                    def __anext__(self):
+                        raise exc
+
+                with self.assertRaisesRegex(exc_type, msg):
+                    anext(A())
+                with self.assertRaisesRegex(exc_type, msg):
+                    anext(A(), 1)
+
     def test_async_gen_asyncio_anext_stopiteration(self):
         async def foo():
             try:
diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-03-24-19-38-53.gh-issue-131670.IffOZj.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-03-24-19-38-53.gh-issue-131670.IffOZj.rst
new file mode 100644 (file)
index 0000000..812a75a
--- /dev/null
@@ -0,0 +1 @@
+Fix :func:`anext` failing on sync :meth:`~object.__anext__` raising an exception.
index 6709f306bb024d0978d0e18f00476cf520b87477..f7761207950705dd37d5a63bb7a41ec86a8e0b35 100644 (file)
@@ -1837,6 +1837,9 @@ builtin_anext_impl(PyObject *module, PyObject *aiterator,
     }
 
     awaitable = (*t->tp_as_async->am_anext)(aiterator);
+    if (awaitable == NULL) {
+        return NULL;
+    }
     if (default_value == NULL) {
         return awaitable;
     }