bpo-39386: Prevent double awaiting of async iterator (GH-18081)
This commit is contained in:
parent
2c49becc69
commit
a96e06db77
|
@ -1128,6 +1128,42 @@ class AsyncGenAsyncioTest(unittest.TestCase):
|
||||||
|
|
||||||
self.assertEqual([], messages)
|
self.assertEqual([], messages)
|
||||||
|
|
||||||
|
def test_async_gen_await_anext_twice(self):
|
||||||
|
async def async_iterate():
|
||||||
|
yield 1
|
||||||
|
yield 2
|
||||||
|
|
||||||
|
async def run():
|
||||||
|
it = async_iterate()
|
||||||
|
nxt = it.__anext__()
|
||||||
|
await nxt
|
||||||
|
with self.assertRaisesRegex(
|
||||||
|
RuntimeError,
|
||||||
|
r"cannot reuse already awaited __anext__\(\)/asend\(\)"
|
||||||
|
):
|
||||||
|
await nxt
|
||||||
|
|
||||||
|
await it.aclose() # prevent unfinished iterator warning
|
||||||
|
|
||||||
|
self.loop.run_until_complete(run())
|
||||||
|
|
||||||
|
def test_async_gen_await_aclose_twice(self):
|
||||||
|
async def async_iterate():
|
||||||
|
yield 1
|
||||||
|
yield 2
|
||||||
|
|
||||||
|
async def run():
|
||||||
|
it = async_iterate()
|
||||||
|
nxt = it.aclose()
|
||||||
|
await nxt
|
||||||
|
with self.assertRaisesRegex(
|
||||||
|
RuntimeError,
|
||||||
|
r"cannot reuse already awaited aclose\(\)/athrow\(\)"
|
||||||
|
):
|
||||||
|
await nxt
|
||||||
|
|
||||||
|
self.loop.run_until_complete(run())
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Prevent double awaiting of async iterator.
|
|
@ -1518,7 +1518,9 @@ async_gen_asend_send(PyAsyncGenASend *o, PyObject *arg)
|
||||||
PyObject *result;
|
PyObject *result;
|
||||||
|
|
||||||
if (o->ags_state == AWAITABLE_STATE_CLOSED) {
|
if (o->ags_state == AWAITABLE_STATE_CLOSED) {
|
||||||
PyErr_SetNone(PyExc_StopIteration);
|
PyErr_SetString(
|
||||||
|
PyExc_RuntimeError,
|
||||||
|
"cannot reuse already awaited __anext__()/asend()");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1561,7 +1563,9 @@ async_gen_asend_throw(PyAsyncGenASend *o, PyObject *args)
|
||||||
PyObject *result;
|
PyObject *result;
|
||||||
|
|
||||||
if (o->ags_state == AWAITABLE_STATE_CLOSED) {
|
if (o->ags_state == AWAITABLE_STATE_CLOSED) {
|
||||||
PyErr_SetNone(PyExc_StopIteration);
|
PyErr_SetString(
|
||||||
|
PyExc_RuntimeError,
|
||||||
|
"cannot reuse already awaited __anext__()/asend()");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1795,7 +1799,9 @@ async_gen_athrow_send(PyAsyncGenAThrow *o, PyObject *arg)
|
||||||
|
|
||||||
if (f == NULL || f->f_stacktop == NULL ||
|
if (f == NULL || f->f_stacktop == NULL ||
|
||||||
o->agt_state == AWAITABLE_STATE_CLOSED) {
|
o->agt_state == AWAITABLE_STATE_CLOSED) {
|
||||||
PyErr_SetNone(PyExc_StopIteration);
|
PyErr_SetString(
|
||||||
|
PyExc_RuntimeError,
|
||||||
|
"cannot reuse already awaited aclose()/athrow()");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1917,7 +1923,9 @@ async_gen_athrow_throw(PyAsyncGenAThrow *o, PyObject *args)
|
||||||
PyObject *retval;
|
PyObject *retval;
|
||||||
|
|
||||||
if (o->agt_state == AWAITABLE_STATE_CLOSED) {
|
if (o->agt_state == AWAITABLE_STATE_CLOSED) {
|
||||||
PyErr_SetNone(PyExc_StopIteration);
|
PyErr_SetString(
|
||||||
|
PyExc_RuntimeError,
|
||||||
|
"cannot reuse already awaited aclose()/athrow()");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue