@@ -1340,7 +1340,8 @@ static PyGetSetDef async_gen_getsetlist[] = {
13401340
13411341static PyMemberDef async_gen_memberlist [] = {
13421342 {"ag_frame" , T_OBJECT , offsetof(PyAsyncGenObject , ag_frame ), READONLY },
1343- {"ag_running" , T_BOOL , offsetof(PyAsyncGenObject , ag_running ), READONLY },
1343+ {"ag_running" , T_BOOL , offsetof(PyAsyncGenObject , ag_running_async ),
1344+ READONLY },
13441345 {"ag_code" , T_OBJECT , offsetof(PyAsyncGenObject , ag_code ), READONLY },
13451346 {NULL } /* Sentinel */
13461347};
@@ -1435,6 +1436,7 @@ PyAsyncGen_New(PyFrameObject *f, PyObject *name, PyObject *qualname)
14351436 o -> ag_finalizer = NULL ;
14361437 o -> ag_closed = 0 ;
14371438 o -> ag_hooks_inited = 0 ;
1439+ o -> ag_running_async = 0 ;
14381440 return (PyObject * )o ;
14391441}
14401442
@@ -1482,13 +1484,15 @@ async_gen_unwrap_value(PyAsyncGenObject *gen, PyObject *result)
14821484 gen -> ag_closed = 1 ;
14831485 }
14841486
1487+ gen -> ag_running_async = 0 ;
14851488 return NULL ;
14861489 }
14871490
14881491 if (_PyAsyncGenWrappedValue_CheckExact (result )) {
14891492 /* async yield */
14901493 _PyGen_SetStopIterationValue (((_PyAsyncGenWrappedValue * )result )-> agw_val );
14911494 Py_DECREF (result );
1495+ gen -> ag_running_async = 0 ;
14921496 return NULL ;
14931497 }
14941498
@@ -1533,12 +1537,20 @@ async_gen_asend_send(PyAsyncGenASend *o, PyObject *arg)
15331537 }
15341538
15351539 if (o -> ags_state == AWAITABLE_STATE_INIT ) {
1540+ if (o -> ags_gen -> ag_running_async ) {
1541+ PyErr_SetString (
1542+ PyExc_RuntimeError ,
1543+ "anext(): asynchronous generator is already running" );
1544+ return NULL ;
1545+ }
1546+
15361547 if (arg == NULL || arg == Py_None ) {
15371548 arg = o -> ags_sendval ;
15381549 }
15391550 o -> ags_state = AWAITABLE_STATE_ITER ;
15401551 }
15411552
1553+ o -> ags_gen -> ag_running_async = 1 ;
15421554 result = gen_send_ex ((PyGenObject * )o -> ags_gen , arg , 0 , 0 );
15431555 result = async_gen_unwrap_value (o -> ags_gen , result );
15441556
@@ -1802,8 +1814,23 @@ async_gen_athrow_send(PyAsyncGenAThrow *o, PyObject *arg)
18021814 }
18031815
18041816 if (o -> agt_state == AWAITABLE_STATE_INIT ) {
1817+ if (o -> agt_gen -> ag_running_async ) {
1818+ if (o -> agt_args == NULL ) {
1819+ PyErr_SetString (
1820+ PyExc_RuntimeError ,
1821+ "aclose(): asynchronous generator is already running" );
1822+ }
1823+ else {
1824+ PyErr_SetString (
1825+ PyExc_RuntimeError ,
1826+ "athrow(): asynchronous generator is already running" );
1827+ }
1828+ return NULL ;
1829+ }
1830+
18051831 if (o -> agt_gen -> ag_closed ) {
1806- PyErr_SetNone (PyExc_StopIteration );
1832+ o -> agt_state == AWAITABLE_STATE_CLOSED ;
1833+ PyErr_SetNone (PyExc_StopAsyncIteration );
18071834 return NULL ;
18081835 }
18091836
@@ -1813,6 +1840,7 @@ async_gen_athrow_send(PyAsyncGenAThrow *o, PyObject *arg)
18131840 }
18141841
18151842 o -> agt_state = AWAITABLE_STATE_ITER ;
1843+ o -> agt_gen -> ag_running_async = 1 ;
18161844
18171845 if (o -> agt_args == NULL ) {
18181846 /* aclose() mode */
@@ -1858,6 +1886,7 @@ async_gen_athrow_send(PyAsyncGenAThrow *o, PyObject *arg)
18581886 /* aclose() mode */
18591887 if (retval ) {
18601888 if (_PyAsyncGenWrappedValue_CheckExact (retval )) {
1889+ o -> agt_gen -> ag_running_async = 0 ;
18611890 Py_DECREF (retval );
18621891 goto yield_close ;
18631892 }
@@ -1871,12 +1900,16 @@ async_gen_athrow_send(PyAsyncGenAThrow *o, PyObject *arg)
18711900 }
18721901
18731902yield_close :
1903+ o -> agt_gen -> ag_running_async = 0 ;
18741904 PyErr_SetString (
18751905 PyExc_RuntimeError , ASYNC_GEN_IGNORED_EXIT_MSG );
18761906 return NULL ;
18771907
18781908check_error :
1879- if (PyErr_ExceptionMatches (PyExc_StopAsyncIteration )) {
1909+ o -> agt_gen -> ag_running_async = 0 ;
1910+ if (PyErr_ExceptionMatches (PyExc_StopAsyncIteration ) ||
1911+ PyErr_ExceptionMatches (PyExc_GeneratorExit ))
1912+ {
18801913 o -> agt_state = AWAITABLE_STATE_CLOSED ;
18811914 if (o -> agt_args == NULL ) {
18821915 /* when aclose() is called we don't want to propagate
@@ -1886,11 +1919,6 @@ async_gen_athrow_send(PyAsyncGenAThrow *o, PyObject *arg)
18861919 PyErr_SetNone (PyExc_StopIteration );
18871920 }
18881921 }
1889- else if (PyErr_ExceptionMatches (PyExc_GeneratorExit )) {
1890- o -> agt_state = AWAITABLE_STATE_CLOSED ;
1891- PyErr_Clear (); /* ignore these errors */
1892- PyErr_SetNone (PyExc_StopIteration );
1893- }
18941922 return NULL ;
18951923}
18961924
@@ -1916,6 +1944,7 @@ async_gen_athrow_throw(PyAsyncGenAThrow *o, PyObject *args)
19161944 } else {
19171945 /* aclose() mode */
19181946 if (retval && _PyAsyncGenWrappedValue_CheckExact (retval )) {
1947+ o -> agt_gen -> ag_running_async = 0 ;
19191948 Py_DECREF (retval );
19201949 PyErr_SetString (PyExc_RuntimeError , ASYNC_GEN_IGNORED_EXIT_MSG );
19211950 return NULL ;
0 commit comments