Skip to content

async generator allows concurrent access via async_gen_athrow_throw and async_gen_asend_throw #117881

@graingert

Description

@graingert

Bug report

Bug description:

import types
import itertools

@types.coroutine
def _async_yield(v):
    return (yield v)

class MyExc(Exception):
    pass

async def agenfn():
    for i in itertools.count():
        try:
            await _async_yield(i)
        except MyExc:
            pass
    return
    yield


agen = agenfn()
gen = agen.asend(None)
print(f"{gen.send(None)}")
gen2 = agen.asend(None)
try:
    print(f"{gen2.throw(MyExc)}")
except RuntimeError:
    print("good")
else:
    print("bad")

gen3 = agen.athrow(MyExc)
try:
    print(f"{gen3.throw(MyExc)}")
except RuntimeError:
    print("good")
else:
    print("bad")

outputs:

0
1
bad
2
bad

should print:

0
good
good

CPython versions tested on:

3.8, 3.9, 3.10, 3.11, 3.12, 3.13, CPython main branch

Operating systems tested on:

Linux

see also #7468 and #74956

Linked PRs

Metadata

Metadata

Assignees

No one assigned

    Labels

    type-bugAn unexpected behavior, bug, or error

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions