Fix anext awaitable ag gen - #157035
Closed
anshuman0123 wants to merge 2 commits into
Closed
Conversation
…graph Expose ag_gen attribute on anext_awaitable objects (returned by anext(agen, default)) that delegates to the wrapped awaitable's ag_gen. This allows asyncio.print_call_graph() and capture_call_graph() to traverse through anext_awaitable to reach the underlying async generator without truncating the call stack.
anshuman0123
requested review from
1st1,
asvetlov,
kumaraditya303,
markshannon and
willingc
as code owners
September 6, 2026 14:08
Member
|
The issue says:
Don't open issues when the OP already suggests to open a PR as it's rude, especially if such PRs are fully AI generated. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Fixes gh-157032.
When calling anext(agen, default) with a default value, Python wraps the underlying anext() awaitable in an internal
anext_awaitable instance (iterobject.c:406-410 in Objects/iterobject.c).
During task call-stack inspection, _build_graph_for_future in graph.py:40-82 traverses cr_await, ag_await, and ag_gen to walk
through coroutines, async generators, and generator-driving awaitables. Because anext_awaitable lacked an ag_gen attribute,
traversal terminated early upon encountering anext_awaitable, losing the entire call stack inside the async generator and any
child coroutines it was waiting on.
This PR exposes a read-only ag_gen attribute on anext_awaitable that delegates to self.wrapped.ag_gen.
──────
Changes Made:
• Added getter anextawaitable_getag_gen to read ag_gen from obj->wrapped.
• Added anextawaitable_getsetlist and hooked it into _PyAnextAwaitable_Type.tp_getset.
• Updated the comment on ag_gen traversal to reference both
asyncio.print_call_graph()loses the call stack at asynchronous generators #156980 andasyncio.print_call_graph()loses the call stack at anext(agen, default) #157032.• Added test_async_gen_anext_default_ag_gen to verify anext(agen, default).ag_gen returns the generator, is read-only, and
raises AttributeError for non-generator async iterators.
• Added test_stack_async_gen_anext_default testing both C and Python event loop implementations.
• Documented the ag_gen attribute on the awaitable returned by anext().
• Added NEWS entry for
asyncio.print_call_graph()loses the call stack at anext(agen, default) #157032.──────
Repro & Verification
Before:
After:
──────
Test Suite Results:
• python -m test test_asyncgen: Passed (100%)
• python -m test test_asyncio: Passed (35/35 test suites, 2,749 tests, 0 failures)