@@ -1521,6 +1521,7 @@ static int init_dictitemsviewtype(PyObject * mod)
15211521
15221522static PyTypeObject wrap_PyGen_Type ;
15231523static PyTypeObject wrap_PyCoro_Type ;
1524+ static PyTypeObject wrap_PyAsyncGen_Type ;
15241525
15251526/* Used to initialize a generator created by gen_new. */
15261527static PyFrameObject * gen_exhausted_frame = NULL ;
@@ -1958,6 +1959,157 @@ static int init_coroutinetype(PyObject * mod)
19581959#undef initchain
19591960#define initchain init_coroutinetype
19601961
1962+ static PyObject *
1963+ async_gen_reduce (PyAsyncGenObject * async_gen )
1964+ {
1965+ PyThreadState * ts = PyThreadState_GET ();
1966+ PyObject * tup ;
1967+ gen_obj_head_ty goh ;
1968+ PyObject * finalizer ;
1969+ int hooks_inited ;
1970+
1971+ if (reduce_to_gen_obj_head (& goh , async_gen -> ag_frame , & async_gen -> ag_exc_state ))
1972+ return NULL ;
1973+
1974+ if (ts -> st .pickleflags & SLP_PICKLEFLAGS_PRESERVE_AG_FINALIZER ) {
1975+ hooks_inited = async_gen -> ag_hooks_inited ;
1976+ finalizer = async_gen -> ag_finalizer ;
1977+ assert (finalizer != Py_None );
1978+ if (finalizer == NULL ) {
1979+ /* encode NULL as Py_None */
1980+ finalizer = Py_None ; /* borrowed ref */
1981+ }
1982+ }
1983+ else if (ts -> st .pickleflags & SLP_PICKLEFLAGS_RESET_AG_FINALIZER ) {
1984+ hooks_inited = 0 ;
1985+ finalizer = Py_None ;
1986+ }
1987+ else {
1988+ hooks_inited = async_gen -> ag_hooks_inited ;
1989+ finalizer = async_gen -> ag_finalizer != NULL ? Py_True : Py_None ;
1990+ }
1991+ Py_INCREF (finalizer );
1992+
1993+ tup = Py_BuildValue ("(O()(ObOOOOOOOii))" ,
1994+ & wrap_PyAsyncGen_Type ,
1995+ goh .frame ,
1996+ async_gen -> ag_running ,
1997+ async_gen -> ag_name ,
1998+ async_gen -> ag_qualname ,
1999+ goh .exc_type ,
2000+ goh .exc_value ,
2001+ goh .exc_traceback ,
2002+ goh .exc_info_obj ,
2003+ finalizer ,
2004+ hooks_inited ,
2005+ async_gen -> ag_closed
2006+ );
2007+
2008+ Py_DECREF (finalizer );
2009+ gen_obj_head_clear (& goh );
2010+ return tup ;
2011+ }
2012+
2013+ static PyObject *
2014+ async_gen_new (PyTypeObject * type , PyObject * args , PyObject * kwds )
2015+ {
2016+ PyAsyncGenObject * async_gen ;
2017+ if (is_wrong_type (type )) return NULL ;
2018+
2019+ /* A reference to frame is stolen by PyGen_New. */
2020+ assert (gen_exhausted_frame != NULL );
2021+ assert (PyFrame_Check (gen_exhausted_frame ));
2022+ assert (type == & wrap_PyAsyncGen_Type );
2023+ async_gen = (PyAsyncGenObject * )PyAsyncGen_New (slp_ensure_new_frame (gen_exhausted_frame ), NULL , NULL );
2024+ if (async_gen == NULL )
2025+ return NULL ;
2026+ Py_TYPE (async_gen ) = type ;
2027+ return (PyObject * )async_gen ;
2028+ }
2029+
2030+ static PyObject *
2031+ async_gen_setstate (PyObject * self , PyObject * args )
2032+ {
2033+ PyThreadState * ts = PyThreadState_GET ();
2034+ PyAsyncGenObject * async_gen = (PyAsyncGenObject * )self ;
2035+ gen_obj_head_ty goh ;
2036+ PyObject * finalizer ;
2037+ int closed ;
2038+ int hooks_inited ;
2039+
2040+ if (is_wrong_type (Py_TYPE (self ))) return NULL ;
2041+
2042+ if ((args = unwrap_frame_arg (args )) == NULL ) /* now args is a counted ref! */
2043+ return NULL ;
2044+
2045+ if (!PyArg_ParseTuple (args , "ObOOOOOOOii:async_gen_setstate" ,
2046+ & goh .frame ,
2047+ & goh .running ,
2048+ & goh .name ,
2049+ & goh .qualname ,
2050+ & goh .exc_type ,
2051+ & goh .exc_value ,
2052+ & goh .exc_traceback ,
2053+ & goh .exc_info_obj ,
2054+ & finalizer ,
2055+ & hooks_inited ,
2056+ & closed )) {
2057+ Py_DECREF (args );
2058+ return NULL ;
2059+ }
2060+
2061+ if (setstate_from_gen_obj_head (& goh ,
2062+ & async_gen -> ag_frame , & async_gen -> ag_exc_state , & async_gen -> ag_code ,
2063+ & async_gen -> ag_name , & async_gen -> ag_qualname , & async_gen -> ag_running )) {
2064+ Py_DECREF (args );
2065+ return NULL ;
2066+ }
2067+
2068+ async_gen -> ag_closed = closed ;
2069+ Py_TYPE (async_gen ) = Py_TYPE (async_gen )-> tp_base ;
2070+
2071+ if (ts -> st .pickleflags & SLP_PICKLEFLAGS_PRESERVE_AG_FINALIZER &&
2072+ finalizer != Py_True ) {
2073+ if (finalizer == Py_None ) {
2074+ /* NULL is pickled as Py_None */
2075+ async_gen -> ag_hooks_inited = hooks_inited ;
2076+ Py_CLEAR (async_gen -> ag_finalizer );
2077+ }
2078+ else {
2079+ async_gen -> ag_hooks_inited = hooks_inited ;
2080+ Py_INCREF (finalizer );
2081+ Py_XSETREF (async_gen -> ag_finalizer , finalizer );
2082+ }
2083+ }
2084+ else if (ts -> st .pickleflags & SLP_PICKLEFLAGS_RESET_AG_FINALIZER ||
2085+ !hooks_inited ) {
2086+ async_gen -> ag_hooks_inited = 0 ;
2087+ Py_CLEAR (async_gen -> ag_finalizer );
2088+ } else {
2089+ assert (hooks_inited );
2090+ async_gen -> ag_hooks_inited = 0 ;
2091+ if (slp_async_gen_init_hooks (async_gen )) {
2092+ async_gen = NULL ;
2093+ goto error ;
2094+ }
2095+ }
2096+
2097+ Py_INCREF (async_gen );
2098+ error :
2099+ Py_DECREF (args ); /* holds the frame and name refs */
2100+ return (PyObject * )async_gen ;
2101+ }
2102+
2103+ MAKE_WRAPPERTYPE (PyAsyncGen_Type , async_gen , "async_generator" , async_gen_reduce ,
2104+ async_gen_new , async_gen_setstate )
2105+
2106+ static int
2107+ init_async_gentype (PyObject * mod )
2108+ {
2109+ return init_type (& wrap_PyAsyncGen_Type , initchain , mod );
2110+ }
2111+ #undef initchain
2112+ #define initchain init_async_gentype
19612113
19622114/******************************************************
19632115
0 commit comments