diff --git a/Lib/test/test_asyncio/test_futures2.py b/Lib/test/test_asyncio/test_futures2.py index cf90835ce87cc3..1878cf8adf63a3 100644 --- a/Lib/test/test_asyncio/test_futures2.py +++ b/Lib/test/test_asyncio/test_futures2.py @@ -28,6 +28,26 @@ async def raise_exc(): 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 index 00000000000000..35008e35314b90 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-07-28-08-02-41.gh-issue-154791.ey7POa.rst @@ -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. diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c index 0cd41d0b4c4d0d..ec6f35f161136c 100644 --- a/Modules/_asynciomodule.c +++ b/Modules/_asynciomodule.c @@ -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; }