From a694af294d88f67afe2409cdb46da5021e90bac3 Mon Sep 17 00:00:00 2001 From: Timofey Ivankov Date: Sun, 1 Nov 2026 22:09:43 +0300 Subject: [PATCH 1/2] gh-161124: Fix asyncio call graph reporting event loop frames for excessive depth --- Lib/asyncio/graph.py | 7 ++++++- Lib/test/test_asyncio/test_graph.py | 5 +++++ .../Library/2026-11-01-22-07-24.gh-issue-161124.c2YmcV.rst | 2 ++ 3 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2026-11-01-22-07-24.gh-issue-161124.c2YmcV.rst diff --git a/Lib/asyncio/graph.py b/Lib/asyncio/graph.py index ce23339782c16e..ef95df71c4d162 100644 --- a/Lib/asyncio/graph.py +++ b/Lib/asyncio/graph.py @@ -2,6 +2,7 @@ import dataclasses import io +import operator import sys import types @@ -160,7 +161,8 @@ def capture_call_graph( call_stack: list[FrameCallGraphEntry] = [] - f = sys._getframe(depth) if limit != 0 else None + # gh-161124: find the task boundary before skipping frames + f = sys._getframe(0) if limit != 0 else None try: while f is not None: # gh-156988: sync gen should not clear the call chain @@ -178,6 +180,9 @@ def capture_call_graph( finally: del f + if call_stack: + call_stack = call_stack[max(0, operator.index(depth)):] + awaited_by = [] if future._asyncio_awaited_by: for parent in future._asyncio_awaited_by: diff --git a/Lib/test/test_asyncio/test_graph.py b/Lib/test/test_asyncio/test_graph.py index 71853ab642f451..8af42a851707a5 100644 --- a/Lib/test/test_asyncio/test_graph.py +++ b/Lib/test/test_asyncio/test_graph.py @@ -785,6 +785,11 @@ async def main(): self.assertTrue(stack_for_fut[1].startswith('* Future(id=')) + async def test_call_graph_depth_beyond_task(self): + # gh-161124 + graph = asyncio.capture_call_graph(depth=2) + self.assertEqual(graph.call_stack, ()) + async def test_capture_call_graph_positive_limit(self): captured = None diff --git a/Misc/NEWS.d/next/Library/2026-11-01-22-07-24.gh-issue-161124.c2YmcV.rst b/Misc/NEWS.d/next/Library/2026-11-01-22-07-24.gh-issue-161124.c2YmcV.rst new file mode 100644 index 00000000000000..32cfb56adb8316 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-11-01-22-07-24.gh-issue-161124.c2YmcV.rst @@ -0,0 +1,2 @@ +Fix :func:`asyncio.print_call_graph` reporting event loop frames when +*depth* exceeds the task stack. Patch by Timofei Ivankov. From 46f1f61bbdcd44f467ec4a4496e4fd0dcb995cb6 Mon Sep 17 00:00:00 2001 From: Timofey Ivankov Date: Thu, 5 Nov 2026 12:56:34 +0300 Subject: [PATCH 2/2] remove unnecessary check --- Lib/asyncio/graph.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Lib/asyncio/graph.py b/Lib/asyncio/graph.py index ef95df71c4d162..d76d2f6383343d 100644 --- a/Lib/asyncio/graph.py +++ b/Lib/asyncio/graph.py @@ -180,8 +180,7 @@ def capture_call_graph( finally: del f - if call_stack: - call_stack = call_stack[max(0, operator.index(depth)):] + call_stack = call_stack[max(0, operator.index(depth)):] awaited_by = [] if future._asyncio_awaited_by: