]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-154791: Fix asyncio.Future losing traceback on repeated result() call (#154798)
authorIaroslav <98962283+iaroslavkrasikov@users.noreply.github.com>
Fri, 31 Jul 2026 13:06:47 +0000 (18:06 +0500)
committerGitHub <noreply@github.com>
Fri, 31 Jul 2026 13:06:47 +0000 (13:06 +0000)
Lib/test/test_asyncio/test_futures2.py
Misc/NEWS.d/next/Library/2026-07-28-08-02-41.gh-issue-154791.ey7POa.rst [new file with mode: 0644]
Modules/_asynciomodule.c

index cf90835ce87cc306383e4b7186957342831a1ea7..1878cf8adf63a3b24ce7e47aad1e8fe211eb2c3a 100644 (file)
@@ -28,6 +28,26 @@ class FutureTests:
             else:
                 self.fail('TypeError was not raised')
 
+    async def test_future_traceback_preserved_after_suppress(self):
+        async def raise_exc():
+            raise TypeError(42)
+
+        future = self.cls(raise_exc())
+        try:
+            await future
+        except TypeError:
+            pass
+
+        try:
+            await future
+        except TypeError as e:
+            tb = ''.join(traceback.format_tb(e.__traceback__))
+            self.assertIn('raise_exc', tb,
+                'Original raise site lost after first result() call')
+        else:
+            self.fail('TypeError was not raised')
+
+
     async def test_task_exc_handler_correct_context(self):
         # see https://github.com/python/cpython/issues/96704
         name = contextvars.ContextVar('name', default='foo')
diff --git a/Misc/NEWS.d/next/Library/2026-07-28-08-02-41.gh-issue-154791.ey7POa.rst b/Misc/NEWS.d/next/Library/2026-07-28-08-02-41.gh-issue-154791.ey7POa.rst
new file mode 100644 (file)
index 0000000..35008e3
--- /dev/null
@@ -0,0 +1,5 @@
+Fix :class:`asyncio.Future` (C implementation) losing the initial exception
+traceback frames when ``Future.result()`` is called more than once. Previously,
+the C implementation cleared the stored traceback after the first call, causing
+subsequent raises to omit the original raise site. The pure-Python
+implementation was unaffected.
index 0cd41d0b4c4d0dccea8b9e5a60a038ad036ca6f8..ec6f35f161136c11d3d4d86859170aa6ab77b372 100644 (file)
@@ -769,7 +769,6 @@ future_get_result(asyncio_state *state, FutureObj *fut, PyObject **result)
             return -1;
         }
         *result = Py_NewRef(fut->fut_exception);
-        Py_CLEAR(fut->fut_exception_tb);
         return 1;
     }