From b4843679a2e5a8528469a0d88717b155240122ca Mon Sep 17 00:00:00 2001 From: Thomas Grainger Date: Wed, 24 Apr 2024 13:20:19 +0100 Subject: [PATCH 1/2] GH-117536: GH-117894: fix athrow().throw(...) unawaited warning (GH-117851) (cherry picked from commit 7d369d471cf2b067c4d795d70b75201c48b46f5b) --- Lib/test/test_asyncgen.py | 62 ++++++++++++++++++- ...-04-13-16-55-53.gh-issue-117536.xkVbfv.rst | 1 + ...-04-15-13-53-59.gh-issue-117894.8LpZ6m.rst | 1 + Objects/genobject.c | 9 ++- 4 files changed, 71 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-04-13-16-55-53.gh-issue-117536.xkVbfv.rst create mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-04-15-13-53-59.gh-issue-117894.8LpZ6m.rst diff --git a/Lib/test/test_asyncgen.py b/Lib/test/test_asyncgen.py index 9a9343781cd40c..ee7e3968b00b26 100644 --- a/Lib/test/test_asyncgen.py +++ b/Lib/test/test_asyncgen.py @@ -395,7 +395,11 @@ async def gen(): yield 123 with self.assertWarns(DeprecationWarning): - gen().athrow(GeneratorExit, GeneratorExit(), None) + x = gen().athrow(GeneratorExit, GeneratorExit(), None) + with self.assertRaises(GeneratorExit): + x.send(None) + del x + gc_collect() def test_async_gen_api_01(self): async def gen(): @@ -1653,6 +1657,62 @@ async def run(): self.loop.run_until_complete(run()) + def test_async_gen_throw_same_aclose_coro_twice(self): + async def async_iterate(): + yield 1 + yield 2 + + it = async_iterate() + nxt = it.aclose() + with self.assertRaises(StopIteration): + nxt.throw(GeneratorExit) + + with self.assertRaisesRegex( + RuntimeError, + r"cannot reuse already awaited aclose\(\)/athrow\(\)" + ): + nxt.throw(GeneratorExit) + + def test_async_gen_throw_custom_same_aclose_coro_twice(self): + async def async_iterate(): + yield 1 + yield 2 + + it = async_iterate() + + class MyException(Exception): + pass + + nxt = it.aclose() + with self.assertRaises(MyException): + nxt.throw(MyException) + + with self.assertRaisesRegex( + RuntimeError, + r"cannot reuse already awaited aclose\(\)/athrow\(\)" + ): + nxt.throw(MyException) + + def test_async_gen_throw_custom_same_athrow_coro_twice(self): + async def async_iterate(): + yield 1 + yield 2 + + it = async_iterate() + + class MyException(Exception): + pass + + nxt = it.athrow(MyException) + with self.assertRaises(MyException): + nxt.throw(MyException) + + with self.assertRaisesRegex( + RuntimeError, + r"cannot reuse already awaited aclose\(\)/athrow\(\)" + ): + nxt.throw(MyException) + def test_async_gen_aclose_twice_with_different_coros(self): # Regression test for https://bugs.python.org/issue39606 async def async_iterate(): diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-04-13-16-55-53.gh-issue-117536.xkVbfv.rst b/Misc/NEWS.d/next/Core and Builtins/2024-04-13-16-55-53.gh-issue-117536.xkVbfv.rst new file mode 100644 index 00000000000000..2492fd163cb549 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2024-04-13-16-55-53.gh-issue-117536.xkVbfv.rst @@ -0,0 +1 @@ +Fix a :exc:`RuntimeWarning` when calling ``agen.aclose().throw(Exception)``. diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-04-15-13-53-59.gh-issue-117894.8LpZ6m.rst b/Misc/NEWS.d/next/Core and Builtins/2024-04-15-13-53-59.gh-issue-117894.8LpZ6m.rst new file mode 100644 index 00000000000000..bd32500a54ee21 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2024-04-15-13-53-59.gh-issue-117894.8LpZ6m.rst @@ -0,0 +1 @@ +Prevent ``agen.aclose()`` objects being re-used after ``.throw()``. diff --git a/Objects/genobject.c b/Objects/genobject.c index bc58409c181360..3fc2ac083d1c15 100644 --- a/Objects/genobject.c +++ b/Objects/genobject.c @@ -2223,7 +2223,11 @@ async_gen_athrow_throw(PyAsyncGenAThrow *o, PyObject *const *args, Py_ssize_t na retval = gen_throw((PyGenObject*)o->agt_gen, args, nargs); if (o->agt_args) { - return async_gen_unwrap_value(o->agt_gen, retval); + retval = async_gen_unwrap_value(o->agt_gen, retval); + if (retval == NULL) { + o->agt_state = AWAITABLE_STATE_CLOSED; + } + return retval; } else { /* aclose() mode */ if (retval && _PyAsyncGenWrappedValue_CheckExact(retval)) { @@ -2233,6 +2237,9 @@ async_gen_athrow_throw(PyAsyncGenAThrow *o, PyObject *const *args, Py_ssize_t na PyErr_SetString(PyExc_RuntimeError, ASYNC_GEN_IGNORED_EXIT_MSG); return NULL; } + if (retval == NULL) { + o->agt_state = AWAITABLE_STATE_CLOSED; + } if (PyErr_ExceptionMatches(PyExc_StopAsyncIteration) || PyErr_ExceptionMatches(PyExc_GeneratorExit)) { From 338efdab1e0aab591dc315c03318c494dbfaba17 Mon Sep 17 00:00:00 2001 From: Thomas Grainger Date: Wed, 24 Apr 2024 13:59:57 +0100 Subject: [PATCH 2/2] remove blurb only applicable on 3.13 --- .../2024-04-13-16-55-53.gh-issue-117536.xkVbfv.rst | 1 - 1 file changed, 1 deletion(-) delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-04-13-16-55-53.gh-issue-117536.xkVbfv.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-04-13-16-55-53.gh-issue-117536.xkVbfv.rst b/Misc/NEWS.d/next/Core and Builtins/2024-04-13-16-55-53.gh-issue-117536.xkVbfv.rst deleted file mode 100644 index 2492fd163cb549..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2024-04-13-16-55-53.gh-issue-117536.xkVbfv.rst +++ /dev/null @@ -1 +0,0 @@ -Fix a :exc:`RuntimeWarning` when calling ``agen.aclose().throw(Exception)``. pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy