https://github.com/python/cpython/commit/e208bf0dda73b8e5a32af154f448e68ad11b26b7
commit: e208bf0dda73b8e5a32af154f448e68ad11b26b7
branch: main
author: Timofei Ivankov <[email protected]>
committer: kumaraditya303 <[email protected]>
date: 2026-09-05T16:48:38Z
summary:
gh-156988: Fix asyncio call graph breaking at sync generators (#156991)
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 94fcd33d7088a6..d5db59f5d6f5f3 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 50d528fb9fb2c5..36841672e1f0f6 100644
--- a/Lib/test/test_asyncio/test_graph.py
+++ b/Lib/test/test_asyncio/test_graph.py
@@ -593,6 +593,26 @@ async def main():
await main()
self.assertRegex(output[0], r'in generator [\w.<>]+\.gen\(\)')
+ 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]