Skip to content

asyncio.print_call_graph() loses the call stack at asynchronous generators #156980

Open

Description

@deadlovelll

Bug report

Bug description:

asyncio.print_call_graph() stops at the first async gen in the await chain and silently drops all of the call stack below it

Repro:

import asyncio

async def deep():
    await asyncio.Event().wait()

async def producer():
    await deep()
    yield 1

async def consumer():
    async for _ in producer():
        pass

async def main():
    t = asyncio.create_task(consumer(), name='consumer')
    await asyncio.sleep(0.05)
    print(asyncio.format_call_graph(t))

asyncio.run(main())

Expected:

* Task(name='consumer', id=0x105be89b0)
  + Call stack:
  |   File '/Users/timofeiivankov/cpython/Lib/asyncio/locks.py', line 210, in async Event.wait()
  |   File '/Users/timofeiivankov/cpython/repro.py', line 4, in async deep()
  |   File '/Users/timofeiivankov/cpython/repro.py', line 7, in async generator producer()
  |   File '/Users/timofeiivankov/cpython/repro.py', line 11, in async consumer()

Actual:

* Task(name='consumer', id=0x105b089b0)
  + Call stack:
  |   File '/Users/timofeiivankov/cpython/repro.py', line 11, in async consumer()

Proposed fix: expose the wrapped generator as ag_gen and step over the wrapper through it

Have a fix ready for that

CPython versions tested on:

CPython main branch

Operating systems tested on:

macOS

Linked PRs

Activity

  1. kumaraditya303 commented on Sep 5, 2026

    @kumaraditya303
    Contributor

    There might be similar issues when iterating over async gen with anext.

  2. deadlovelll commented on Sep 5, 2026

    @deadlovelll
    ContributorAuthor

    There might be similar issues when iterating over async gen with anext.

    anext(agen) returns the async_generator_asend, so it is already covered by this fix. But anext(agen, default) is not because it returns anext_awaitable which doesnt expose async gen. Do you want me to create a new issue for that, or push to this one?

  3. kumaraditya303 commented on Sep 5, 2026

    @kumaraditya303
    Contributor

    Do you want me to create a new issue for that, or push to this one?

    A new issue would be better, I still need to think more about this case and aiter too.

  4. deadlovelll commented on Sep 5, 2026

    @deadlovelll
    ContributorAuthor

    Do you want me to create a new issue for that, or push to this one?

    A new issue would be better, I still need to think more about this case and aiter too.

    Thanks! I'll do it tomorrow. I can also look into what other cases there might be

  5. kumaraditya303 commented on Sep 5, 2026

    @kumaraditya303
    Contributor
  6. deadlovelll commented on Sep 6, 2026

    @deadlovelll
    ContributorAuthor

    @kumaraditya303 hi! just created issue for anext. There are also issue with aiter(callable, stop_value). If you don't mind i can create issue and pr for it, or give you the details if you want to work on it yourself

  7. kumaraditya303 commented on Sep 6, 2026

    @kumaraditya303
    Contributor

    You can create issues but wait for creating PR, I haven't decided yet how I want to to fix this and will likely work on this myself.

  8. msullivan commented on Sep 25, 2026

    @msullivan
    Contributor

    I ran into the same missing field, as part of a different but related introspection goal (trying to find the future that a blocked async generator is blocked on).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    stdlibStandard Library Python modules in the Lib/ directorytopic-asynciotype-bugAn unexpected behavior, bug, or error

    Projects

    • Status
      Todo

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions