Skip to content
This repository was archived by the owner on Feb 13, 2025. It is now read-only.

Commit 105adf0

Browse files
author
Anselm Kruis
committed
Merge branch 3.7 into 3.7-slp
2 parents 863b822 + b76d5e9 commit 105adf0

File tree

3 files changed

+49
-4
lines changed

3 files changed

+49
-4
lines changed

Lib/test/test_asyncgen.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1117,6 +1117,42 @@ async def main():
11171117

11181118
self.assertEqual([], messages)
11191119

1120+
def test_async_gen_await_anext_twice(self):
1121+
async def async_iterate():
1122+
yield 1
1123+
yield 2
1124+
1125+
async def run():
1126+
it = async_iterate()
1127+
nxt = it.__anext__()
1128+
await nxt
1129+
with self.assertRaisesRegex(
1130+
RuntimeError,
1131+
r"cannot reuse already awaited __anext__\(\)/asend\(\)"
1132+
):
1133+
await nxt
1134+
1135+
await it.aclose() # prevent unfinished iterator warning
1136+
1137+
self.loop.run_until_complete(run())
1138+
1139+
def test_async_gen_await_aclose_twice(self):
1140+
async def async_iterate():
1141+
yield 1
1142+
yield 2
1143+
1144+
async def run():
1145+
it = async_iterate()
1146+
nxt = it.aclose()
1147+
await nxt
1148+
with self.assertRaisesRegex(
1149+
RuntimeError,
1150+
r"cannot reuse already awaited aclose\(\)/athrow\(\)"
1151+
):
1152+
await nxt
1153+
1154+
self.loop.run_until_complete(run())
1155+
11201156

11211157
if __name__ == "__main__":
11221158
unittest.main()
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Prevent double awaiting of async iterator.

Objects/genobject.c

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1706,7 +1706,9 @@ async_gen_asend_send(PyAsyncGenASend *o, PyObject *arg)
17061706
PyObject *result;
17071707

17081708
if (o->ags_state == AWAITABLE_STATE_CLOSED) {
1709-
PyErr_SetNone(PyExc_StopIteration);
1709+
PyErr_SetString(
1710+
PyExc_RuntimeError,
1711+
"cannot reuse already awaited __anext__()/asend()");
17101712
return NULL;
17111713
}
17121714

@@ -1767,7 +1769,9 @@ async_gen_asend_throw(PyAsyncGenASend *o, PyObject *args)
17671769
PyObject *result;
17681770

17691771
if (o->ags_state == AWAITABLE_STATE_CLOSED) {
1770-
PyErr_SetNone(PyExc_StopIteration);
1772+
PyErr_SetString(
1773+
PyExc_RuntimeError,
1774+
"cannot reuse already awaited __anext__()/asend()");
17711775
return NULL;
17721776
}
17731777

@@ -2002,7 +2006,9 @@ async_gen_athrow_send(PyAsyncGenAThrow *o, PyObject *arg)
20022006

20032007
if (f == NULL || f->f_stacktop == NULL ||
20042008
o->agt_state == AWAITABLE_STATE_CLOSED) {
2005-
PyErr_SetNone(PyExc_StopIteration);
2009+
PyErr_SetString(
2010+
PyExc_RuntimeError,
2011+
"cannot reuse already awaited aclose()/athrow()");
20062012
return NULL;
20072013
}
20082014

@@ -2106,7 +2112,9 @@ async_gen_athrow_throw(PyAsyncGenAThrow *o, PyObject *args)
21062112
PyObject *retval;
21072113

21082114
if (o->agt_state == AWAITABLE_STATE_CLOSED) {
2109-
PyErr_SetNone(PyExc_StopIteration);
2115+
PyErr_SetString(
2116+
PyExc_RuntimeError,
2117+
"cannot reuse already awaited aclose()/athrow()");
21102118
return NULL;
21112119
}
21122120

0 commit comments

Comments
 (0)