mirror of
https://github.com/python/cpython.git
synced 2025-09-09 18:32:22 +00:00

The new API allows to efficiently send values into native generators and coroutines avoiding use of StopIteration exceptions to signal returns. ceval loop now uses this method instead of the old "private" _PyGen_Send C API. This translates to 1.6x increased performance of 'await' calls in micro-benchmarks. Aside from CPython core improvements, this new API will also allow Cython to generate more efficient code, benefiting high-performance IO libraries like uvloop.
115 lines
3.8 KiB
C
115 lines
3.8 KiB
C
|
|
/* Generator object interface */
|
|
|
|
#ifndef Py_LIMITED_API
|
|
#ifndef Py_GENOBJECT_H
|
|
#define Py_GENOBJECT_H
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
#include "pystate.h" /* _PyErr_StackItem */
|
|
|
|
/* _PyGenObject_HEAD defines the initial segment of generator
|
|
and coroutine objects. */
|
|
#define _PyGenObject_HEAD(prefix) \
|
|
PyObject_HEAD \
|
|
/* Note: gi_frame can be NULL if the generator is "finished" */ \
|
|
PyFrameObject *prefix##_frame; \
|
|
/* The code object backing the generator */ \
|
|
PyObject *prefix##_code; \
|
|
/* List of weak reference. */ \
|
|
PyObject *prefix##_weakreflist; \
|
|
/* Name of the generator. */ \
|
|
PyObject *prefix##_name; \
|
|
/* Qualified name of the generator. */ \
|
|
PyObject *prefix##_qualname; \
|
|
_PyErr_StackItem prefix##_exc_state;
|
|
|
|
typedef struct {
|
|
/* The gi_ prefix is intended to remind of generator-iterator. */
|
|
_PyGenObject_HEAD(gi)
|
|
} PyGenObject;
|
|
|
|
PyAPI_DATA(PyTypeObject) PyGen_Type;
|
|
|
|
#define PyGen_Check(op) PyObject_TypeCheck(op, &PyGen_Type)
|
|
#define PyGen_CheckExact(op) Py_IS_TYPE(op, &PyGen_Type)
|
|
|
|
PyAPI_FUNC(PyObject *) PyGen_New(PyFrameObject *);
|
|
PyAPI_FUNC(PyObject *) PyGen_NewWithQualName(PyFrameObject *,
|
|
PyObject *name, PyObject *qualname);
|
|
PyAPI_FUNC(int) _PyGen_SetStopIterationValue(PyObject *);
|
|
PyAPI_FUNC(int) _PyGen_FetchStopIterationValue(PyObject **);
|
|
PyAPI_FUNC(PyObject *) _PyGen_Send(PyGenObject *, PyObject *);
|
|
PyObject *_PyGen_yf(PyGenObject *);
|
|
PyAPI_FUNC(void) _PyGen_Finalize(PyObject *self);
|
|
|
|
typedef enum {
|
|
PYGEN_RETURN = 0,
|
|
PYGEN_ERROR = -1,
|
|
PYGEN_NEXT = 1,
|
|
} PySendResult;
|
|
|
|
/* Sends the value into the generator or the coroutine. Returns:
|
|
- PYGEN_RETURN (0) if generator has returned.
|
|
'result' parameter is filled with return value
|
|
- PYGEN_ERROR (-1) if exception was raised.
|
|
'result' parameter is NULL
|
|
- PYGEN_NEXT (1) if generator has yielded.
|
|
'result' parameter is filled with yielded value. */
|
|
PyAPI_FUNC(PySendResult) PyGen_Send(PyGenObject *, PyObject *, PyObject **);
|
|
|
|
#ifndef Py_LIMITED_API
|
|
typedef struct {
|
|
_PyGenObject_HEAD(cr)
|
|
PyObject *cr_origin;
|
|
} PyCoroObject;
|
|
|
|
PyAPI_DATA(PyTypeObject) PyCoro_Type;
|
|
PyAPI_DATA(PyTypeObject) _PyCoroWrapper_Type;
|
|
|
|
#define PyCoro_CheckExact(op) Py_IS_TYPE(op, &PyCoro_Type)
|
|
PyObject *_PyCoro_GetAwaitableIter(PyObject *o);
|
|
PyAPI_FUNC(PyObject *) PyCoro_New(PyFrameObject *,
|
|
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;
|
|
|
|
int ag_running_async;
|
|
} 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(PyFrameObject *,
|
|
PyObject *name, PyObject *qualname);
|
|
|
|
#define PyAsyncGen_CheckExact(op) Py_IS_TYPE(op, &PyAsyncGen_Type)
|
|
|
|
PyObject *_PyAsyncGenValueWrapperNew(PyObject *);
|
|
|
|
#endif
|
|
|
|
#undef _PyGenObject_HEAD
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
#endif /* !Py_GENOBJECT_H */
|
|
#endif /* Py_LIMITED_API */
|