Issue #28003: Implement PEP 525 -- Asynchronous Generators.
diff --git a/Include/ceval.h b/Include/ceval.h
index 81f4bbf..c682063 100644
--- a/Include/ceval.h
+++ b/Include/ceval.h
@@ -25,6 +25,10 @@
PyAPI_FUNC(void) PyEval_SetTrace(Py_tracefunc, PyObject *);
PyAPI_FUNC(void) _PyEval_SetCoroutineWrapper(PyObject *);
PyAPI_FUNC(PyObject *) _PyEval_GetCoroutineWrapper(void);
+PyAPI_FUNC(void) _PyEval_SetAsyncGenFirstiter(PyObject *);
+PyAPI_FUNC(PyObject *) _PyEval_GetAsyncGenFirstiter(void);
+PyAPI_FUNC(void) _PyEval_SetAsyncGenFinalizer(PyObject *);
+PyAPI_FUNC(PyObject *) _PyEval_GetAsyncGenFinalizer(void);
#endif
struct _frame; /* Avoid including frameobject.h */
diff --git a/Include/code.h b/Include/code.h
index b39d6bd..9823f10 100644
--- a/Include/code.h
+++ b/Include/code.h
@@ -59,6 +59,7 @@
``async def`` keywords) */
#define CO_COROUTINE 0x0080
#define CO_ITERABLE_COROUTINE 0x0100
+#define CO_ASYNC_GENERATOR 0x0200
/* These are no longer used. */
#if 0
diff --git a/Include/genobject.h b/Include/genobject.h
index 1ff32a8..973bdd5 100644
--- a/Include/genobject.h
+++ b/Include/genobject.h
@@ -61,6 +61,37 @@
PyObject *_PyCoro_GetAwaitableIter(PyObject *o);
PyAPI_FUNC(PyObject *) PyCoro_New(struct _frame *,
PyObject *name, PyObject *qualname);
+
+/* Asynchronous Generators */
+
+typedef struct {
+ _PyGenObject_HEAD(ag)
+ PyObject *ag_finalizer;
+
+ /* Flag is set to 1 when hooks set up by sys.set_asyncgen_hooks
+ were called on the generator, to avoid calling them more
+ than once. */
+ int ag_hooks_inited;
+
+ /* Flag is set to 1 when aclose() is called for the first time, or
+ when a StopAsyncIteration exception is raised. */
+ int ag_closed;
+} PyAsyncGenObject;
+
+PyAPI_DATA(PyTypeObject) PyAsyncGen_Type;
+PyAPI_DATA(PyTypeObject) _PyAsyncGenASend_Type;
+PyAPI_DATA(PyTypeObject) _PyAsyncGenWrappedValue_Type;
+PyAPI_DATA(PyTypeObject) _PyAsyncGenAThrow_Type;
+
+PyAPI_FUNC(PyObject *) PyAsyncGen_New(struct _frame *,
+ PyObject *name, PyObject *qualname);
+
+#define PyAsyncGen_CheckExact(op) (Py_TYPE(op) == &PyAsyncGen_Type)
+
+PyObject *_PyAsyncGenValueWrapperNew(PyObject *);
+
+int PyAsyncGen_ClearFreeLists(void);
+
#endif
#undef _PyGenObject_HEAD
diff --git a/Include/pylifecycle.h b/Include/pylifecycle.h
index cf149b2..8390467 100644
--- a/Include/pylifecycle.h
+++ b/Include/pylifecycle.h
@@ -107,6 +107,7 @@
PyAPI_FUNC(void) PySlice_Fini(void);
PyAPI_FUNC(void) _PyType_Fini(void);
PyAPI_FUNC(void) _PyRandom_Fini(void);
+PyAPI_FUNC(void) PyAsyncGen_Fini(void);
PyAPI_DATA(PyThreadState *) _Py_Finalizing;
#endif
diff --git a/Include/pystate.h b/Include/pystate.h
index 5ab5c98..f1c9427 100644
--- a/Include/pystate.h
+++ b/Include/pystate.h
@@ -148,6 +148,9 @@
Py_ssize_t co_extra_user_count;
freefunc co_extra_freefuncs[MAX_CO_EXTRA_USERS];
+ PyObject *async_gen_firstiter;
+ PyObject *async_gen_finalizer;
+
/* XXX signal handlers should also be here */
} PyThreadState;
diff --git a/Include/symtable.h b/Include/symtable.h
index b0259d6..86ae3c2 100644
--- a/Include/symtable.h
+++ b/Include/symtable.h
@@ -48,6 +48,7 @@
unsigned ste_child_free : 1; /* true if a child block has free vars,
including free refs to globals */
unsigned ste_generator : 1; /* true if namespace is a generator */
+ unsigned ste_coroutine : 1; /* true if namespace is a coroutine */
unsigned ste_varargs : 1; /* true if block has varargs */
unsigned ste_varkeywords : 1; /* true if block has varkeywords */
unsigned ste_returns_value : 1; /* true if namespace uses return with