https://github.com/python/cpython/commit/313dfd842a3a69fb1c9134561880ab6937d3ff12
commit: 313dfd842a3a69fb1c9134561880ab6937d3ff12
branch: main
author: Timofei Ivankov <[email protected]>
committer: kumaraditya303 <[email protected]>
date: 2026-11-02T14:26:17Z
summary:

gh-161178: Fix missing async generator frames in `asyncio.Task.print_stack()` 
(#161183)

Co-authored-by: Kumar Aditya <[email protected]>

files:
A Misc/NEWS.d/next/Library/2026-11-02-16-28-11.gh-issue-161178.D3-23R.rst
M Lib/asyncio/base_tasks.py
M Lib/test/test_asyncio/test_tasks.py

diff --git a/Lib/asyncio/base_tasks.py b/Lib/asyncio/base_tasks.py
index c907b683413732..2e297c6e0802be 100644
--- a/Lib/asyncio/base_tasks.py
+++ b/Lib/asyncio/base_tasks.py
@@ -42,8 +42,11 @@ def _task_get_stack(task, limit):
     elif hasattr(task._coro, 'ag_frame'):
         # case 3: async generators
         f = task._coro.ag_frame
+    elif not task.done() and hasattr(task._coro, 'aga_gen'):
+        # case 4: async generator's asend/athrow/aclose
+        f = task._coro.aga_gen.ag_frame
     else:
-        # case 4: unknown objects
+        # case 5: unknown objects
         f = None
     if f is not None:
         while f is not None:
diff --git a/Lib/test/test_asyncio/test_tasks.py 
b/Lib/test/test_asyncio/test_tasks.py
index d4d3863923e79e..277b856f57a136 100644
--- a/Lib/test/test_asyncio/test_tasks.py
+++ b/Lib/test/test_asyncio/test_tasks.py
@@ -335,6 +335,40 @@ async def runner():
 
         self.loop.run_until_complete(runner())
 
+    def test_get_stack_async_generator(self):
+        # gh-161178
+        async def gen():
+            try:
+                yield
+            except ValueError:
+                pass
+            finally:
+                await asyncio.sleep(0)
+            yield
+
+        async def runner(method, args):
+            agen = gen()
+            await anext(agen)
+            task = self.new_task(self.loop, getattr(agen, method)(*args))
+            await asyncio.sleep(0)
+            frame = agen.ag_frame
+            stack = task.get_stack()
+            await task
+            try:
+                self.assertEqual(stack, [frame])
+                self.assertEqual(task.get_stack(), [])
+            finally:
+                await agen.aclose()
+
+        for method, args in (
+            ('__anext__', ()),
+            ('asend', (None,)),
+            ('athrow', (ValueError(),)),
+            ('aclose', ()),
+        ):
+            with self.subTest(method=method):
+                self.loop.run_until_complete(runner(method, args))
+
     def test_task_repr(self):
         self.loop.set_debug(False)
 
diff --git 
a/Misc/NEWS.d/next/Library/2026-11-02-16-28-11.gh-issue-161178.D3-23R.rst 
b/Misc/NEWS.d/next/Library/2026-11-02-16-28-11.gh-issue-161178.D3-23R.rst
new file mode 100644
index 00000000000000..1130fbe95ba019
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2026-11-02-16-28-11.gh-issue-161178.D3-23R.rst
@@ -0,0 +1,2 @@
+Fix :meth:`asyncio.Task.print_stack` to include frames from async generator
+operations. Patch by Timofei Ivankov

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]

Reply via email to