Skip to content

closing async_generator_athrow on an async generator that suppresses GeneratorExit does not raise RuntimeError #117714

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
graingert opened this issue Apr 10, 2024 · 3 comments
Labels
3.12 only security fixes 3.13 bugs and security fixes interpreter-core (Objects, Python, Grammar, and Parser dirs) type-bug An unexpected behavior, bug, or error

Comments

@graingert
Copy link
Contributor

graingert commented Apr 10, 2024

Bug report

Bug description:

when running agen.aclose().close() it should throw GeneratorExit into the coroutine and raise RuntimeError from .close():

import types

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

async def agenfn():
    try:
        yield 1
    finally:
        try:
            await _async_yield(2)
        except GeneratorExit:
            print("generator exit")
            await _async_yield(3)


agen = agenfn()
try:
    anext(agen).send(None)
except StopIteration as e:
    print(e.value)

try:
    agen.aclose().close()
except RuntimeError:
    print("good")
else:
    print("bad")

prints:

1
bad
Exception ignored in: <async_generator object agenfn at 0x7e0c43b09620>
RuntimeError: async generator ignored GeneratorExit

CPython versions tested on:

3.11, 3.12, 3.13, CPython main branch

Operating systems tested on:

Linux

Linked PRs

@graingert graingert added the type-bug An unexpected behavior, bug, or error label Apr 10, 2024
@graingert graingert changed the title closing async_generator_athrow on an async generator that suppresses exception does not raise RuntimError closing async_generator_athrow on an async generator that suppresses exception does not raise RuntimeError Apr 10, 2024
@graingert
Copy link
Contributor Author

graingert commented Apr 10, 2024

it looks like async_gen_athrow_close just marks the async_generator_athrow as closed and returns None, instead it should call gen_throw with a GeneratorExit object and transform any return values into RuntimeError exceptions.

cpython/Objects/genobject.c

Lines 2244 to 2249 in 6bc0b33

static PyObject *
async_gen_athrow_close(PyAsyncGenAThrow *o, PyObject *args)
{
o->agt_state = AWAITABLE_STATE_CLOSED;
Py_RETURN_NONE;
}

@graingert graingert added 3.12 only security fixes 3.13 bugs and security fixes interpreter-core (Objects, Python, Grammar, and Parser dirs) labels Apr 10, 2024
@graingert graingert changed the title closing async_generator_athrow on an async generator that suppresses exception does not raise RuntimeError closing async_generator_athrow on an async generator that suppresses GeneratorExit does not raise RuntimeError Apr 10, 2024
@graingert
Copy link
Contributor Author

this also applies to async_generator_asend.close()

@graingert
Copy link
Contributor Author

graingert commented Apr 11, 2024

another example showing aclose().close() doesn't finalize the generator:

import types
finalized = False

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

async def agenfn():
    global finalized
    try:
        yield 1
    finally:
        try:
            await _async_yield(2)
        except GeneratorExit:
            finalized = True
            raise


agen = agenfn()
try:
    anext(agen).send(None)
except StopIteration as e:
    print(e.value)

aclose = agen.aclose()
print(f"{aclose.send(None)=}")
aclose.close()
print(f"{finalized=}")

graingert added a commit to graingert/cpython that referenced this issue Apr 15, 2024
graingert added a commit to graingert/cpython that referenced this issue Apr 15, 2024
graingert added a commit to graingert/cpython that referenced this issue Apr 15, 2024
graingert added a commit to graingert/cpython that referenced this issue Apr 24, 2024
graingert added a commit to graingert/cpython that referenced this issue May 1, 2024
encukou added a commit that referenced this issue May 6, 2024
…GH-117906)

* GH-117714: replace athrow().close() and asend().close() stubs with implimentations

* test athrow().close() and asend().close() raises RuntimeError

* 📜🤖 Added by blurb_it.

* Update Objects/genobject.c

Co-authored-by: Petr Viktorin <[email protected]>

---------

Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com>
Co-authored-by: Petr Viktorin <[email protected]>
miss-islington pushed a commit to miss-islington/cpython that referenced this issue May 6, 2024
… throw (pythonGH-117906)

* pythonGH-117714: replace athrow().close() and asend().close() stubs with implimentations

* test athrow().close() and asend().close() raises RuntimeError

* 📜🤖 Added by blurb_it.

* Update Objects/genobject.c

Co-authored-by: Petr Viktorin <[email protected]>

---------

(cherry picked from commit e5c6992)

Co-authored-by: Thomas Grainger <[email protected]>
Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com>
Co-authored-by: Petr Viktorin <[email protected]>
SonicField pushed a commit to SonicField/cpython that referenced this issue May 8, 2024
… throw (pythonGH-117906)

* pythonGH-117714: replace athrow().close() and asend().close() stubs with implimentations

* test athrow().close() and asend().close() raises RuntimeError

* 📜🤖 Added by blurb_it.

* Update Objects/genobject.c

Co-authored-by: Petr Viktorin <[email protected]>

---------

Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com>
Co-authored-by: Petr Viktorin <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
3.12 only security fixes 3.13 bugs and security fixes interpreter-core (Objects, Python, Grammar, and Parser dirs) type-bug An unexpected behavior, bug, or error
Projects
None yet
Development

No branches or pull requests

1 participant