New submission from Nathaniel Smith <n...@pobox.com>:

In bpo-39386, the 'aclose' method for async generators was fixed so that the 
following broken code would correctly raise an error:

# -- bad code --
async def agen_fn():
    yield

async def do_bad_thing():
    agen = agen_fn()
    aclose_coro = agen.aclose()
    await aclose_coro
    # Should raise RuntimeError:
    await aclose_coro

asyncio.run(do_bad_thing())

# -----------------

However, the merged fix also broke the following correct code, which should 
*not* raise an error:

# -- good code --
async def agen_fn():
    yield

async def do_good_thing():
    agen = agen_fn()
    await agen.aclose()
    # Should *not* raise an error, but currently does in Python dev branches:
    await agen.aclose()

asyncio.run(do_good_thing())

# ----------------

It's not supported to iterate the same coroutine object twice. However, making 
two *independent* calls to aclose should return two independent coroutine 
objects, and it should be legal to iterate over each object once.

This can also occur even if there's only a single call to 'aclose'. For 
example, this is the recommended idiom for making sure that an async generator 
correctly closes all its resources:

# -- good code --
async def agen_fn():
    yield

async def careful_loop():
    agen = agen_fn()
    try:
        async for _ in agen:
            pass
    finally:
        await agen.aclose()

asyncio.run(careful_loop())

# -------------------

On released Python, the code above runs correctly. On the latest Python dev 
branches, it raises a RuntimeError.

So basically the problem is that the fix for bpo-39386 is storing the "was 
aclose iterated?" state on the async generator object, but in fact it needs to 
be stored on the aclose coroutine object.

----------
keywords: 3.7regression, 3.8regression, 3.9regression
messages: 361783
nosy: asvetlov, lukasz.langa, ned.deily, njs, yselivanov
priority: release blocker
severity: normal
status: open
title: Regression: it should be possible to close async iterators multiple times
versions: Python 3.7, Python 3.8, Python 3.9

_______________________________________
Python tracker <rep...@bugs.python.org>
<https://bugs.python.org/issue39606>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to