Skip to content

asyncio.Runner allows async generators to skip gracefull finalization #95584

Closed as not planned
@graingert

Description

@graingert

reproducer:

import gc
import asyncio
import weakref

async def agenfn():
    for i in range(100):
        try:
            yield i
        finally:
            await asyncio.sleep(0)


with asyncio.Runner() as runner:
    agen = agenfn()
    print(runner.run(anext(agen)))
    print(runner.run(anext(agen)))
    print(runner.run(anext(agen)))
    agen_wr = weakref.ref(agen)
    del agen
    gc.collect()
    assert agen_wr() is None


async def run_through():
    agen = agenfn()
    print(await anext(agen))
    print(await anext(agen))
    print(await anext(agen))
    agen_wr = weakref.ref(agen)
    del agen
    gc.collect()
    assert agen_wr() is None

asyncio.run(run_through())
gc.collect()

output:

0
1
2
Exception ignored in: <async_generator object agenfn at 0x7f29a019d000>
Traceback (most recent call last):
  File "/home/graingert/projects/gc_agen_runner.py", line 19, in <module>
    del agen
        ^^^^
RuntimeError: async generator ignored GeneratorExit
0
1
2

Metadata

Metadata

Assignees

No one assigned

    Labels

    3.11only security fixes3.12only security fixespendingThe issue will be closed if no feedback is providedtopic-asynciotype-bugAn unexpected behavior, bug, or error

    Projects

    Status

    Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions