https://github.com/python/cpython/commit/b8ce41861d83063fe85fd11bf8c4452aa4154623
commit: b8ce41861d83063fe85fd11bf8c4452aa4154623
branch: 3.14
author: Timofei Ivankov <[email protected]>
committer: kumaraditya303 <[email protected]>
date: 2026-09-06T15:59:45+05:30
summary:
[3.14] gh-156988: Fix asyncio call graph loss at sync generators (#157005)
files:
A Misc/NEWS.d/next/Library/2026-09-05-18-23-30.gh-issue-156988.nEUQE6.rst
M Lib/asyncio/graph.py
M Lib/test/test_asyncio/test_graph.py
diff --git a/Lib/asyncio/graph.py b/Lib/asyncio/graph.py
index 54df7afa5553b9..d0a54f3625b37e 100644
--- a/Lib/asyncio/graph.py
+++ b/Lib/asyncio/graph.py
@@ -155,7 +155,9 @@ def capture_call_graph(
f = sys._getframe(depth) if limit != 0 else None
try:
while f is not None:
- is_async = f.f_generator is not None
+ # gh-156988: sync gen should not clear the call chain
+ is_async = isinstance(
+ f.f_generator, (types.CoroutineType, types.AsyncGeneratorType))
call_stack.append(FrameCallGraphEntry(f))
if is_async:
diff --git a/Lib/test/test_asyncio/test_graph.py
b/Lib/test/test_asyncio/test_graph.py
index 690f8f58b8f10d..50fa18e888fd22 100644
--- a/Lib/test/test_asyncio/test_graph.py
+++ b/Lib/test/test_asyncio/test_graph.py
@@ -425,6 +425,26 @@ async def boom():
self.assertEqual(asyncio.capture_call_graph(task).call_stack,
())
self.assertIn(f"name={task.get_name()!r}", buf.getvalue())
+ async def test_capture_call_graph_generator_keeps_caller_frames(self):
+ # gh-156988: sync gen should not clear the call chain
+ stack = None
+
+ def gen():
+ nonlocal stack
+ graph = asyncio.capture_call_graph()
+ stack = [entry.frame.f_code.co_name for entry in graph.call_stack]
+ yield
+
+ def middle():
+ for _ in gen():
+ pass
+
+ async def main():
+ middle()
+
+ await main()
+ self.assertEqual(stack[:3], ['gen', 'middle', 'main'])
+
@unittest.skipIf(
not hasattr(asyncio.futures, "_c_future_add_to_awaited_by"),
diff --git
a/Misc/NEWS.d/next/Library/2026-09-05-18-23-30.gh-issue-156988.nEUQE6.rst
b/Misc/NEWS.d/next/Library/2026-09-05-18-23-30.gh-issue-156988.nEUQE6.rst
new file mode 100644
index 00000000000000..6cb2f1f4cf14ae
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2026-09-05-18-23-30.gh-issue-156988.nEUQE6.rst
@@ -0,0 +1,2 @@
+:func:`asyncio.print_call_graph` no longer truncates the call stack at a
+synchronous generator.
_______________________________________________
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]