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():
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():
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)) {
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))
{