@@ -1963,8 +1963,11 @@ PyAsyncGen_New(PyFrameObject *f, PyObject *name, PyObject *qualname)
19631963 return (PyObject * )ag ;
19641964}
19651965
1966- static PyObject *
1967- async_gen_unwrap_value (PyAsyncGenObject * gen , PyObject * result )
1966+ // Like async_gen_unwrap_value(), but an async yield is reported as
1967+ // PYGEN_RETURN with the yielded value instead of raising StopIteration.
1968+ static PySendResult
1969+ async_gen_unwrap_send (PyAsyncGenObject * gen , PyObject * result ,
1970+ PyObject * * presult )
19681971{
19691972 if (result == NULL ) {
19701973 if (!PyErr_Occurred ()) {
@@ -1977,17 +1980,31 @@ async_gen_unwrap_value(PyAsyncGenObject *gen, PyObject *result)
19771980 FT_ATOMIC_STORE_INT8_RELAXED (gen -> ag_closed , 1 );
19781981 }
19791982
1980- return NULL ;
1983+ * presult = NULL ;
1984+ return PYGEN_ERROR ;
19811985 }
19821986
19831987 if (_PyAsyncGenWrappedValue_CheckExact (result )) {
19841988 /* async yield */
1985- _PyGen_SetStopIterationValue (((_PyAsyncGenWrappedValue * )result )-> agw_val );
1989+ * presult = Py_NewRef (((_PyAsyncGenWrappedValue * )result )-> agw_val );
19861990 Py_DECREF (result );
1987- return NULL ;
1991+ return PYGEN_RETURN ;
19881992 }
19891993
1990- return result ;
1994+ * presult = result ;
1995+ return PYGEN_NEXT ;
1996+ }
1997+
1998+ static PyObject *
1999+ async_gen_unwrap_value (PyAsyncGenObject * gen , PyObject * result )
2000+ {
2001+ PyObject * value ;
2002+ if (async_gen_unwrap_send (gen , result , & value ) == PYGEN_RETURN ) {
2003+ _PyGen_SetStopIterationValue (value );
2004+ Py_DECREF (value );
2005+ return NULL ;
2006+ }
2007+ return value ;
19912008}
19922009
19932010
@@ -2023,18 +2040,19 @@ async_gen_asend_traverse(PyObject *self, visitproc visit, void *arg)
20232040}
20242041
20252042
2026- static PyObject *
2027- async_gen_asend_send (PyObject * self , PyObject * arg )
2043+ PySendResult
2044+ _PyAsyncGenASend_Send (PyObject * self , PyObject * arg , PyObject * * presult )
20282045{
20292046 PyAsyncGenASend * o = _PyAsyncGenASend_CAST (self );
20302047
2048+ * presult = NULL ;
20312049 int8_t state = FT_ATOMIC_LOAD_INT8_RELAXED (o -> ags_state );
20322050 do {
20332051 if (state == AWAITABLE_STATE_CLOSED ) {
20342052 PyErr_SetString (
20352053 PyExc_RuntimeError ,
20362054 "cannot reuse already awaited __anext__()/asend()" );
2037- return NULL ;
2055+ return PYGEN_ERROR ;
20382056 }
20392057 if (state == AWAITABLE_STATE_ITER ) {
20402058 goto do_send ;
@@ -2051,37 +2069,37 @@ async_gen_asend_send(PyObject *self, PyObject *arg)
20512069 PyErr_SetString (
20522070 PyExc_RuntimeError ,
20532071 "anext(): asynchronous generator is already running" );
2054- return NULL ;
2072+ return PYGEN_ERROR ;
20552073 }
20562074
20572075 if (arg == NULL || arg == Py_None ) {
20582076 arg = o -> ags_sendval ;
20592077 }
20602078
20612079 PyObject * result ;
2080+ PySendResult res ;
20622081do_send :
20632082 result = gen_send ((PyObject * )o -> ags_gen , arg );
2064- result = async_gen_unwrap_value (o -> ags_gen , result );
2083+ res = async_gen_unwrap_send (o -> ags_gen , result , presult );
20652084
2066- if (result == NULL ) {
2085+ if (res != PYGEN_NEXT ) {
20672086 FT_ATOMIC_STORE_INT8_RELAXED (o -> ags_state , AWAITABLE_STATE_CLOSED );
20682087 FT_ATOMIC_STORE_INT8_RELEASE (o -> ags_gen -> ag_running_async , 0 );
20692088 }
20702089
2071- return result ;
2090+ return res ;
20722091}
20732092
2074- PySendResult
2075- _PyAsyncGenASend_Send (PyObject * iter , PyObject * arg , PyObject * * result )
2093+ static PyObject *
2094+ async_gen_asend_send (PyObject * self , PyObject * arg )
20762095{
2077- * result = async_gen_asend_send (iter , arg );
2078- if (* result != NULL ) {
2079- return PYGEN_NEXT ;
2080- }
2081- if (_PyGen_FetchStopIterationValue (result ) == 0 ) {
2082- return PYGEN_RETURN ;
2096+ PyObject * result ;
2097+ if (_PyAsyncGenASend_Send (self , arg , & result ) == PYGEN_RETURN ) {
2098+ _PyGen_SetStopIterationValue (result );
2099+ Py_DECREF (result );
2100+ return NULL ;
20832101 }
2084- return PYGEN_ERROR ;
2102+ return result ;
20852103}
20862104
20872105
0 commit comments