From: Raj Kripal Danday Date: Sun, 26 Jul 2026 09:08:51 +0000 (-0700) Subject: gh-148736: Use ag_frame when walking async generators in asyncio.graph (#148737) X-Git-Url: http://git.ipfire.org/gitweb/index.cgi?a=commitdiff_plain;h=306a35c71f1ceada3ea55479087d1c6a5cc8f15f;p=thirdparty%2FPython%2Fcpython.git gh-148736: Use ag_frame when walking async generators in asyncio.graph (#148737) --- diff --git a/Lib/asyncio/graph.py b/Lib/asyncio/graph.py index 35f7fa62140b..7e85e08c4291 100644 --- a/Lib/asyncio/graph.py +++ b/Lib/asyncio/graph.py @@ -62,7 +62,7 @@ def _build_graph_for_future( coro = coro.cr_await elif hasattr(coro, 'ag_await'): # A native async generator or duck-type compatible iterator - st.append(FrameCallGraphEntry(coro.cr_frame)) + st.append(FrameCallGraphEntry(coro.ag_frame)) coro = coro.ag_await else: break diff --git a/Lib/test/test_asyncio/test_graph.py b/Lib/test/test_asyncio/test_graph.py index 3dde7535284b..928b618fe5c5 100644 --- a/Lib/test/test_asyncio/test_graph.py +++ b/Lib/test/test_asyncio/test_graph.py @@ -1,5 +1,6 @@ import asyncio import io +import sys import unittest from unittest import mock @@ -147,6 +148,31 @@ class CallStackTestBase: 'async generator CallStackTestBase.test_stack_async_gen..gen()', stack_for_gen_nested_call[1]) + def test_ag_frame_used_for_async_generator(self): + # Regression test for gh-148736: the ag_await branch of + # _build_graph_for_future must read ag_frame, not cr_frame. + from asyncio.graph import _build_graph_for_future + + sentinel_frame = sys._getframe() + + class FakeAsyncGen: + ag_await = None + ag_frame = sentinel_frame + + class FakeCoro: + cr_frame = sentinel_frame + cr_await = FakeAsyncGen() + + loop = asyncio.new_event_loop() + try: + fut = loop.create_future() + fut.get_coro = lambda: FakeCoro() + result = _build_graph_for_future(fut) + finally: + loop.close() + + self.assertEqual(len(result.call_stack), 2) + async def test_stack_gather(self): stack_for_deep = None diff --git a/Misc/NEWS.d/next/Library/2026-04-18-12-00-00.gh-issue-148736.ag-frame.rst b/Misc/NEWS.d/next/Library/2026-04-18-12-00-00.gh-issue-148736.ag-frame.rst new file mode 100644 index 000000000000..e9701dfaa6a4 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-04-18-12-00-00.gh-issue-148736.ag-frame.rst @@ -0,0 +1,3 @@ +Fix a latent :exc:`AttributeError` in :mod:`asyncio` call-graph capture when +walking an async generator's ``ag_await`` chain: the walker referenced +``cr_frame`` instead of ``ag_frame``.