Commit 4ed35f23 authored by Stefan Behnel's avatar Stefan Behnel

split Cython's Generator type into separate Coroutine and Generator types to...

split Cython's Generator type into separate Coroutine and Generator types to prepare PEP 492 implementation
parent be1d2f0d
...@@ -8669,7 +8669,7 @@ class YieldFromExprNode(YieldExprNode): ...@@ -8669,7 +8669,7 @@ class YieldFromExprNode(YieldExprNode):
self.arg = self.arg.coerce_to_pyobject(env) self.arg = self.arg.coerce_to_pyobject(env)
def generate_evaluation_code(self, code): def generate_evaluation_code(self, code):
code.globalstate.use_utility_code(UtilityCode.load_cached("YieldFrom", "Generator.c")) code.globalstate.use_utility_code(UtilityCode.load_cached("YieldFrom", "Coroutine.c"))
self.arg.generate_evaluation_code(code) self.arg.generate_evaluation_code(code)
code.putln("%s = __Pyx_Generator_Yield_From(%s, %s);" % ( code.putln("%s = __Pyx_Generator_Yield_From(%s, %s);" % (
......
...@@ -2071,17 +2071,10 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -2071,17 +2071,10 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.putln("%s = PyBytes_FromStringAndSize(\"\", 0); %s" % ( code.putln("%s = PyBytes_FromStringAndSize(\"\", 0); %s" % (
Naming.empty_bytes, code.error_goto_if_null(Naming.empty_bytes, self.pos))) Naming.empty_bytes, code.error_goto_if_null(Naming.empty_bytes, self.pos)))
code.putln("#ifdef __Pyx_CyFunction_USED") for ext_type in ('CyFunction', 'FusedFunction', 'Coroutine', 'Generator'):
code.put_error_if_neg(self.pos, "__Pyx_CyFunction_init()") code.putln("#ifdef __Pyx_%s_USED" % ext_type)
code.putln("#endif") code.put_error_if_neg(self.pos, "__pyx_%s_init()" % ext_type)
code.putln("#endif")
code.putln("#ifdef __Pyx_FusedFunction_USED")
code.put_error_if_neg(self.pos, "__pyx_FusedFunction_init()")
code.putln("#endif")
code.putln("#ifdef __Pyx_Generator_USED")
code.put_error_if_neg(self.pos, "__pyx_Generator_init()")
code.putln("#endif")
code.putln("/*--- Library function declarations ---*/") code.putln("/*--- Library function declarations ---*/")
env.generate_library_function_declarations(code) env.generate_library_function_declarations(code)
......
...@@ -3956,8 +3956,8 @@ class GeneratorDefNode(DefNode): ...@@ -3956,8 +3956,8 @@ class GeneratorDefNode(DefNode):
qualname = code.intern_identifier(self.qualname) qualname = code.intern_identifier(self.qualname)
code.putln('{') code.putln('{')
code.putln('__pyx_GeneratorObject *gen = __Pyx_Generator_New(' code.putln('__pyx_CoroutineObject *gen = __Pyx_Generator_New('
'(__pyx_generator_body_t) %s, (PyObject *) %s, %s, %s); %s' % ( '(__pyx_coroutine_body_t) %s, (PyObject *) %s, %s, %s); %s' % (
body_cname, Naming.cur_scope_cname, name, qualname, body_cname, Naming.cur_scope_cname, name, qualname,
code.error_goto_if_null('gen', self.pos))) code.error_goto_if_null('gen', self.pos)))
code.put_decref(Naming.cur_scope_cname, py_object_type) code.put_decref(Naming.cur_scope_cname, py_object_type)
...@@ -3972,7 +3972,7 @@ class GeneratorDefNode(DefNode): ...@@ -3972,7 +3972,7 @@ class GeneratorDefNode(DefNode):
code.putln('}') code.putln('}')
def generate_function_definitions(self, env, code): def generate_function_definitions(self, env, code):
env.use_utility_code(UtilityCode.load_cached("Generator", "Generator.c")) env.use_utility_code(UtilityCode.load_cached("Generator", "Coroutine.c"))
self.gbody.generate_function_header(code, proto=True) self.gbody.generate_function_header(code, proto=True)
super(GeneratorDefNode, self).generate_function_definitions(env, code) super(GeneratorDefNode, self).generate_function_definitions(env, code)
...@@ -4005,7 +4005,7 @@ class GeneratorBodyDefNode(DefNode): ...@@ -4005,7 +4005,7 @@ class GeneratorBodyDefNode(DefNode):
self.declare_generator_body(env) self.declare_generator_body(env)
def generate_function_header(self, code, proto=False): def generate_function_header(self, code, proto=False):
header = "static PyObject *%s(__pyx_GeneratorObject *%s, PyObject *%s)" % ( header = "static PyObject *%s(__pyx_CoroutineObject *%s, PyObject *%s)" % (
self.entry.func_cname, self.entry.func_cname,
Naming.generator_cname, Naming.generator_cname,
Naming.sent_value_cname) Naming.sent_value_cname)
...@@ -4070,7 +4070,7 @@ class GeneratorBodyDefNode(DefNode): ...@@ -4070,7 +4070,7 @@ class GeneratorBodyDefNode(DefNode):
code.put_label(code.error_label) code.put_label(code.error_label)
if Future.generator_stop in env.global_scope().context.future_directives: if Future.generator_stop in env.global_scope().context.future_directives:
# PEP 479: turn accidental StopIteration exceptions into a RuntimeError # PEP 479: turn accidental StopIteration exceptions into a RuntimeError
code.globalstate.use_utility_code(UtilityCode.load_cached("pep479", "Generator.c")) code.globalstate.use_utility_code(UtilityCode.load_cached("pep479", "Coroutine.c"))
code.putln("if (unlikely(PyErr_ExceptionMatches(PyExc_StopIteration))) " code.putln("if (unlikely(PyErr_ExceptionMatches(PyExc_StopIteration))) "
"__Pyx_Generator_Replace_StopIteration();") "__Pyx_Generator_Replace_StopIteration();")
for cname, type in code.funcstate.all_managed_temps(): for cname, type in code.funcstate.all_managed_temps():
...@@ -4082,7 +4082,7 @@ class GeneratorBodyDefNode(DefNode): ...@@ -4082,7 +4082,7 @@ class GeneratorBodyDefNode(DefNode):
code.put_xdecref(Naming.retval_cname, py_object_type) code.put_xdecref(Naming.retval_cname, py_object_type)
code.putln('%s->resume_label = -1;' % Naming.generator_cname) code.putln('%s->resume_label = -1;' % Naming.generator_cname)
# clean up as early as possible to help breaking any reference cycles # clean up as early as possible to help breaking any reference cycles
code.putln('__Pyx_Generator_clear((PyObject*)%s);' % Naming.generator_cname) code.putln('__Pyx_Coroutine_clear((PyObject*)%s);' % Naming.generator_cname)
code.put_finish_refcount_context() code.put_finish_refcount_context()
code.putln('return NULL;') code.putln('return NULL;')
code.putln("}") code.putln("}")
...@@ -5512,7 +5512,7 @@ class ReturnStatNode(StatNode): ...@@ -5512,7 +5512,7 @@ class ReturnStatNode(StatNode):
elif self.in_generator: elif self.in_generator:
# return value == raise StopIteration(value), but uncatchable # return value == raise StopIteration(value), but uncatchable
code.globalstate.use_utility_code( code.globalstate.use_utility_code(
UtilityCode.load_cached("ReturnWithStopIteration", "Generator.c")) UtilityCode.load_cached("ReturnWithStopIteration", "Coroutine.c"))
code.putln("%s = NULL; __Pyx_ReturnWithStopIteration(%s);" % ( code.putln("%s = NULL; __Pyx_ReturnWithStopIteration(%s);" % (
Naming.retval_cname, Naming.retval_cname,
self.value.py_result())) self.value.py_result()))
...@@ -7205,8 +7205,8 @@ utility_code_for_cimports = { ...@@ -7205,8 +7205,8 @@ utility_code_for_cimports = {
utility_code_for_imports = { utility_code_for_imports = {
# utility code used when special modules are imported. # utility code used when special modules are imported.
# TODO: Consider a generic user-level mechanism for importing # TODO: Consider a generic user-level mechanism for importing
'asyncio': ("__Pyx_patch_asyncio", "PatchAsyncIO", "Generator.c"), 'asyncio': ("__Pyx_patch_asyncio", "PatchAsyncIO", "Coroutine.c"),
'inspect': ("__Pyx_patch_inspect", "PatchInspect", "Generator.c"), 'inspect': ("__Pyx_patch_inspect", "PatchInspect", "Coroutine.c"),
} }
......
//////////////////// YieldFrom.proto //////////////////// //////////////////// YieldFrom.proto ////////////////////
static CYTHON_INLINE PyObject* __Pyx_Generator_Yield_From(__pyx_GeneratorObject *gen, PyObject *source); static CYTHON_INLINE PyObject* __Pyx_Generator_Yield_From(__pyx_CoroutineObject *gen, PyObject *source);
//////////////////// YieldFrom //////////////////// //////////////////// YieldFrom ////////////////////
//@requires: Generator //@requires: Generator
static CYTHON_INLINE PyObject* __Pyx_Generator_Yield_From(__pyx_GeneratorObject *gen, PyObject *source) { static CYTHON_INLINE PyObject* __Pyx_Generator_Yield_From(__pyx_CoroutineObject *gen, PyObject *source) {
PyObject *source_gen, *retval; PyObject *source_gen, *retval;
source_gen = PyObject_GetIter(source); source_gen = PyObject_GetIter(source);
if (unlikely(!source_gen)) if (unlikely(!source_gen))
...@@ -40,16 +40,13 @@ static void __Pyx_Generator_Replace_StopIteration(void) { ...@@ -40,16 +40,13 @@ static void __Pyx_Generator_Replace_StopIteration(void) {
} }
//////////////////// Generator.proto //////////////////// //////////////////// CoroutineBase.proto ////////////////////
#define __Pyx_Generator_USED
#include <structmember.h>
#include <frameobject.h>
typedef PyObject *(*__pyx_generator_body_t)(PyObject *, PyObject *); typedef PyObject *(*__pyx_coroutine_body_t)(PyObject *, PyObject *);
typedef struct { typedef struct {
PyObject_HEAD PyObject_HEAD
__pyx_generator_body_t body; __pyx_coroutine_body_t body;
PyObject *closure; PyObject *closure;
PyObject *exc_type; PyObject *exc_type;
PyObject *exc_value; PyObject *exc_value;
...@@ -62,14 +59,11 @@ typedef struct { ...@@ -62,14 +59,11 @@ typedef struct {
int resume_label; int resume_label;
// using T_BOOL for property below requires char value // using T_BOOL for property below requires char value
char is_running; char is_running;
} __pyx_GeneratorObject; } __pyx_CoroutineObject;
static PyTypeObject *__pyx_GeneratorType = 0; static __pyx_CoroutineObject *__Pyx__Coroutine_New(PyTypeObject *type, __pyx_coroutine_body_t body,
PyObject *closure, PyObject *name, PyObject *qualname); /*proto*/
static __pyx_GeneratorObject *__Pyx_Generator_New(__pyx_generator_body_t body, static int __Pyx_Coroutine_clear(PyObject *self); /*proto*/
PyObject *closure, PyObject *name, PyObject *qualname);
static int __pyx_Generator_init(void);
static int __Pyx_Generator_clear(PyObject* self);
#if 1 || PY_VERSION_HEX < 0x030300B0 #if 1 || PY_VERSION_HEX < 0x030300B0
static int __Pyx_PyGen_FetchStopIterationValue(PyObject **pvalue); static int __Pyx_PyGen_FetchStopIterationValue(PyObject **pvalue);
...@@ -77,22 +71,47 @@ static int __Pyx_PyGen_FetchStopIterationValue(PyObject **pvalue); ...@@ -77,22 +71,47 @@ static int __Pyx_PyGen_FetchStopIterationValue(PyObject **pvalue);
#define __Pyx_PyGen_FetchStopIterationValue(pvalue) PyGen_FetchStopIterationValue(pvalue) #define __Pyx_PyGen_FetchStopIterationValue(pvalue) PyGen_FetchStopIterationValue(pvalue)
#endif #endif
//////////////////// Generator ////////////////////
//////////////////// Coroutine.proto ////////////////////
#define __Pyx_Coroutine_USED
static PyTypeObject *__pyx_CoroutineType = 0;
#define __Pyx_Coroutine_CheckExact(obj) (Py_TYPE(obj) == __pyx_CoroutineType)
#define __Pyx_Coroutine_New(body, closure, name, qualname) \
__Pyx__Coroutine_New(__pyx_CoroutineType, body, closure, name, qualname)
static int __pyx_Coroutine_init(void);
//////////////////// Generator.proto ////////////////////
#define __Pyx_Generator_USED
static PyTypeObject *__pyx_GeneratorType = 0;
#define __Pyx_Generator_CheckExact(obj) (Py_TYPE(obj) == __pyx_GeneratorType)
#define __Pyx_Generator_New(body, closure, name, qualname) \
__Pyx__Coroutine_New(__pyx_GeneratorType, body, closure, name, qualname)
static int __pyx_Generator_init(void);
//////////////////// CoroutineBase ////////////////////
//@requires: Exceptions.c::PyErrFetchRestore //@requires: Exceptions.c::PyErrFetchRestore
//@requires: Exceptions.c::SwapException //@requires: Exceptions.c::SwapException
//@requires: Exceptions.c::RaiseException //@requires: Exceptions.c::RaiseException
//@requires: ObjectHandling.c::PyObjectCallMethod1 //@requires: ObjectHandling.c::PyObjectCallMethod1
//@requires: ObjectHandling.c::PyObjectGetAttrStr //@requires: ObjectHandling.c::PyObjectGetAttrStr
//@requires: CommonTypes.c::FetchCommonType //@requires: CommonTypes.c::FetchCommonType
//@requires: PatchGeneratorABC
static PyObject *__Pyx_Generator_Next(PyObject *self); #include <structmember.h>
static PyObject *__Pyx_Generator_Send(PyObject *self, PyObject *value); #include <frameobject.h>
static PyObject *__Pyx_Generator_Close(PyObject *self);
static PyObject *__Pyx_Generator_Throw(PyObject *gen, PyObject *args);
#define __Pyx_Generator_CheckExact(obj) (Py_TYPE(obj) == __pyx_GeneratorType) static PyObject *__Pyx_Coroutine_Send(PyObject *self, PyObject *value);
#define __Pyx_Generator_Undelegate(gen) Py_CLEAR((gen)->yieldfrom) static PyObject *__Pyx_Coroutine_Close(PyObject *self);
static PyObject *__Pyx_Coroutine_Throw(PyObject *gen, PyObject *args);
#define __Pyx_Coroutine_Undelegate(gen) Py_CLEAR((gen)->yieldfrom)
// If StopIteration exception is set, fetches its 'value' // If StopIteration exception is set, fetches its 'value'
// attribute if any, otherwise sets pvalue to None. // attribute if any, otherwise sets pvalue to None.
...@@ -190,7 +209,7 @@ static int __Pyx_PyGen_FetchStopIterationValue(PyObject **pvalue) { ...@@ -190,7 +209,7 @@ static int __Pyx_PyGen_FetchStopIterationValue(PyObject **pvalue) {
#endif #endif
static CYTHON_INLINE static CYTHON_INLINE
void __Pyx_Generator_ExceptionClear(__pyx_GeneratorObject *self) { void __Pyx_Coroutine_ExceptionClear(__pyx_CoroutineObject *self) {
PyObject *exc_type = self->exc_type; PyObject *exc_type = self->exc_type;
PyObject *exc_value = self->exc_value; PyObject *exc_value = self->exc_value;
PyObject *exc_traceback = self->exc_traceback; PyObject *exc_traceback = self->exc_traceback;
...@@ -205,7 +224,7 @@ void __Pyx_Generator_ExceptionClear(__pyx_GeneratorObject *self) { ...@@ -205,7 +224,7 @@ void __Pyx_Generator_ExceptionClear(__pyx_GeneratorObject *self) {
} }
static CYTHON_INLINE static CYTHON_INLINE
int __Pyx_Generator_CheckRunning(__pyx_GeneratorObject *gen) { int __Pyx_Coroutine_CheckRunning(__pyx_CoroutineObject *gen) {
if (unlikely(gen->is_running)) { if (unlikely(gen->is_running)) {
PyErr_SetString(PyExc_ValueError, PyErr_SetString(PyExc_ValueError,
"generator already executing"); "generator already executing");
...@@ -215,7 +234,7 @@ int __Pyx_Generator_CheckRunning(__pyx_GeneratorObject *gen) { ...@@ -215,7 +234,7 @@ int __Pyx_Generator_CheckRunning(__pyx_GeneratorObject *gen) {
} }
static CYTHON_INLINE static CYTHON_INLINE
PyObject *__Pyx_Generator_SendEx(__pyx_GeneratorObject *self, PyObject *value) { PyObject *__Pyx_Coroutine_SendEx(__pyx_CoroutineObject *self, PyObject *value) {
PyObject *retval; PyObject *retval;
assert(!self->is_running); assert(!self->is_running);
...@@ -254,7 +273,7 @@ PyObject *__Pyx_Generator_SendEx(__pyx_GeneratorObject *self, PyObject *value) { ...@@ -254,7 +273,7 @@ PyObject *__Pyx_Generator_SendEx(__pyx_GeneratorObject *self, PyObject *value) {
__Pyx_ExceptionSwap(&self->exc_type, &self->exc_value, __Pyx_ExceptionSwap(&self->exc_type, &self->exc_value,
&self->exc_traceback); &self->exc_traceback);
} else { } else {
__Pyx_Generator_ExceptionClear(self); __Pyx_Coroutine_ExceptionClear(self);
} }
self->is_running = 1; self->is_running = 1;
...@@ -277,14 +296,14 @@ PyObject *__Pyx_Generator_SendEx(__pyx_GeneratorObject *self, PyObject *value) { ...@@ -277,14 +296,14 @@ PyObject *__Pyx_Generator_SendEx(__pyx_GeneratorObject *self, PyObject *value) {
} }
#endif #endif
} else { } else {
__Pyx_Generator_ExceptionClear(self); __Pyx_Coroutine_ExceptionClear(self);
} }
return retval; return retval;
} }
static CYTHON_INLINE static CYTHON_INLINE
PyObject *__Pyx_Generator_MethodReturn(PyObject *retval) { PyObject *__Pyx_Coroutine_MethodReturn(PyObject *retval) {
if (unlikely(!retval && !PyErr_Occurred())) { if (unlikely(!retval && !PyErr_Occurred())) {
// method call must not terminate with NULL without setting an exception // method call must not terminate with NULL without setting an exception
PyErr_SetNone(PyExc_StopIteration); PyErr_SetNone(PyExc_StopIteration);
...@@ -293,55 +312,41 @@ PyObject *__Pyx_Generator_MethodReturn(PyObject *retval) { ...@@ -293,55 +312,41 @@ PyObject *__Pyx_Generator_MethodReturn(PyObject *retval) {
} }
static CYTHON_INLINE static CYTHON_INLINE
PyObject *__Pyx_Generator_FinishDelegation(__pyx_GeneratorObject *gen) { PyObject *__Pyx_Coroutine_FinishDelegation(__pyx_CoroutineObject *gen) {
PyObject *ret; PyObject *ret;
PyObject *val = NULL; PyObject *val = NULL;
__Pyx_Generator_Undelegate(gen); __Pyx_Coroutine_Undelegate(gen);
__Pyx_PyGen_FetchStopIterationValue(&val); __Pyx_PyGen_FetchStopIterationValue(&val);
// val == NULL on failure => pass on exception // val == NULL on failure => pass on exception
ret = __Pyx_Generator_SendEx(gen, val); ret = __Pyx_Coroutine_SendEx(gen, val);
Py_XDECREF(val); Py_XDECREF(val);
return ret; return ret;
} }
static PyObject *__Pyx_Generator_Next(PyObject *self) { static PyObject *__Pyx_Coroutine_Send(PyObject *self, PyObject *value) {
__pyx_GeneratorObject *gen = (__pyx_GeneratorObject*) self;
PyObject *yf = gen->yieldfrom;
if (unlikely(__Pyx_Generator_CheckRunning(gen)))
return NULL;
if (yf) {
PyObject *ret;
// FIXME: does this really need an INCREF() ?
//Py_INCREF(yf);
// YieldFrom code ensures that yf is an iterator
gen->is_running = 1;
ret = Py_TYPE(yf)->tp_iternext(yf);
gen->is_running = 0;
//Py_DECREF(yf);
if (likely(ret)) {
return ret;
}
return __Pyx_Generator_FinishDelegation(gen);
}
return __Pyx_Generator_SendEx(gen, Py_None);
}
static PyObject *__Pyx_Generator_Send(PyObject *self, PyObject *value) {
PyObject *retval; PyObject *retval;
__pyx_GeneratorObject *gen = (__pyx_GeneratorObject*) self; __pyx_CoroutineObject *gen = (__pyx_CoroutineObject*) self;
PyObject *yf = gen->yieldfrom; PyObject *yf = gen->yieldfrom;
if (unlikely(__Pyx_Generator_CheckRunning(gen))) if (unlikely(__Pyx_Coroutine_CheckRunning(gen)))
return NULL; return NULL;
if (yf) { if (yf) {
PyObject *ret; PyObject *ret;
// FIXME: does this really need an INCREF() ? // FIXME: does this really need an INCREF() ?
//Py_INCREF(yf); //Py_INCREF(yf);
gen->is_running = 1; gen->is_running = 1;
#ifdef __Pyx_Generator_USED
if (__Pyx_Generator_CheckExact(yf)) { if (__Pyx_Generator_CheckExact(yf)) {
ret = __Pyx_Generator_Send(yf, value); ret = __Pyx_Coroutine_Send(yf, value);
} else { } else
#endif
#ifdef __Pyx_Coroutine_USED
if (__Pyx_Coroutine_CheckExact(yf)) {
ret = __Pyx_Coroutine_Send(yf, value);
} else
#endif
{
if (value == Py_None) if (value == Py_None)
ret = PyIter_Next(yf); ret = PyIter_Next(yf); // FIXME!
else else
ret = __Pyx_PyObject_CallMethod1(yf, PYIDENT("send"), value); ret = __Pyx_PyObject_CallMethod1(yf, PYIDENT("send"), value);
} }
...@@ -350,24 +355,34 @@ static PyObject *__Pyx_Generator_Send(PyObject *self, PyObject *value) { ...@@ -350,24 +355,34 @@ static PyObject *__Pyx_Generator_Send(PyObject *self, PyObject *value) {
if (likely(ret)) { if (likely(ret)) {
return ret; return ret;
} }
retval = __Pyx_Generator_FinishDelegation(gen); retval = __Pyx_Coroutine_FinishDelegation(gen);
} else { } else {
retval = __Pyx_Generator_SendEx(gen, value); retval = __Pyx_Coroutine_SendEx(gen, value);
} }
return __Pyx_Generator_MethodReturn(retval); return __Pyx_Coroutine_MethodReturn(retval);
} }
// This helper function is used by gen_close and gen_throw to // This helper function is used by gen_close and gen_throw to
// close a subiterator being delegated to by yield-from. // close a subiterator being delegated to by yield-from.
static int __Pyx_Generator_CloseIter(__pyx_GeneratorObject *gen, PyObject *yf) { static int __Pyx_Coroutine_CloseIter(__pyx_CoroutineObject *gen, PyObject *yf) {
PyObject *retval = NULL; PyObject *retval = NULL;
int err = 0; int err = 0;
#ifdef __Pyx_Generator_USED
if (__Pyx_Generator_CheckExact(yf)) { if (__Pyx_Generator_CheckExact(yf)) {
retval = __Pyx_Generator_Close(yf); retval = __Pyx_Coroutine_Close(yf);
if (!retval) if (!retval)
return -1; return -1;
} else { } else
#endif
#ifdef __Pyx_Coroutine_USED
if (__Pyx_Coroutine_CheckExact(yf)) {
retval = __Pyx_Coroutine_Close(yf);
if (!retval)
return -1;
} else
#endif
{
PyObject *meth; PyObject *meth;
gen->is_running = 1; gen->is_running = 1;
meth = __Pyx_PyObject_GetAttrStr(yf, PYIDENT("close")); meth = __Pyx_PyObject_GetAttrStr(yf, PYIDENT("close"));
...@@ -388,24 +403,24 @@ static int __Pyx_Generator_CloseIter(__pyx_GeneratorObject *gen, PyObject *yf) { ...@@ -388,24 +403,24 @@ static int __Pyx_Generator_CloseIter(__pyx_GeneratorObject *gen, PyObject *yf) {
return err; return err;
} }
static PyObject *__Pyx_Generator_Close(PyObject *self) { static PyObject *__Pyx_Coroutine_Close(PyObject *self) {
__pyx_GeneratorObject *gen = (__pyx_GeneratorObject *) self; __pyx_CoroutineObject *gen = (__pyx_CoroutineObject *) self;
PyObject *retval, *raised_exception; PyObject *retval, *raised_exception;
PyObject *yf = gen->yieldfrom; PyObject *yf = gen->yieldfrom;
int err = 0; int err = 0;
if (unlikely(__Pyx_Generator_CheckRunning(gen))) if (unlikely(__Pyx_Coroutine_CheckRunning(gen)))
return NULL; return NULL;
if (yf) { if (yf) {
Py_INCREF(yf); Py_INCREF(yf);
err = __Pyx_Generator_CloseIter(gen, yf); err = __Pyx_Coroutine_CloseIter(gen, yf);
__Pyx_Generator_Undelegate(gen); __Pyx_Coroutine_Undelegate(gen);
Py_DECREF(yf); Py_DECREF(yf);
} }
if (err == 0) if (err == 0)
PyErr_SetNone(PyExc_GeneratorExit); PyErr_SetNone(PyExc_GeneratorExit);
retval = __Pyx_Generator_SendEx(gen, NULL); retval = __Pyx_Coroutine_SendEx(gen, NULL);
if (retval) { if (retval) {
Py_DECREF(retval); Py_DECREF(retval);
PyErr_SetString(PyExc_RuntimeError, PyErr_SetString(PyExc_RuntimeError,
...@@ -427,8 +442,8 @@ static PyObject *__Pyx_Generator_Close(PyObject *self) { ...@@ -427,8 +442,8 @@ static PyObject *__Pyx_Generator_Close(PyObject *self) {
return NULL; return NULL;
} }
static PyObject *__Pyx_Generator_Throw(PyObject *self, PyObject *args) { static PyObject *__Pyx_Coroutine_Throw(PyObject *self, PyObject *args) {
__pyx_GeneratorObject *gen = (__pyx_GeneratorObject *) self; __pyx_CoroutineObject *gen = (__pyx_CoroutineObject *) self;
PyObject *typ; PyObject *typ;
PyObject *tb = NULL; PyObject *tb = NULL;
PyObject *val = NULL; PyObject *val = NULL;
...@@ -437,24 +452,32 @@ static PyObject *__Pyx_Generator_Throw(PyObject *self, PyObject *args) { ...@@ -437,24 +452,32 @@ static PyObject *__Pyx_Generator_Throw(PyObject *self, PyObject *args) {
if (!PyArg_UnpackTuple(args, (char *)"throw", 1, 3, &typ, &val, &tb)) if (!PyArg_UnpackTuple(args, (char *)"throw", 1, 3, &typ, &val, &tb))
return NULL; return NULL;
if (unlikely(__Pyx_Generator_CheckRunning(gen))) if (unlikely(__Pyx_Coroutine_CheckRunning(gen)))
return NULL; return NULL;
if (yf) { if (yf) {
PyObject *ret; PyObject *ret;
Py_INCREF(yf); Py_INCREF(yf);
if (PyErr_GivenExceptionMatches(typ, PyExc_GeneratorExit)) { if (PyErr_GivenExceptionMatches(typ, PyExc_GeneratorExit)) {
int err = __Pyx_Generator_CloseIter(gen, yf); int err = __Pyx_Coroutine_CloseIter(gen, yf);
Py_DECREF(yf); Py_DECREF(yf);
__Pyx_Generator_Undelegate(gen); __Pyx_Coroutine_Undelegate(gen);
if (err < 0) if (err < 0)
return __Pyx_Generator_MethodReturn(__Pyx_Generator_SendEx(gen, NULL)); return __Pyx_Coroutine_MethodReturn(__Pyx_Coroutine_SendEx(gen, NULL));
goto throw_here; goto throw_here;
} }
gen->is_running = 1; gen->is_running = 1;
#ifdef __Pyx_Generator_USED
if (__Pyx_Generator_CheckExact(yf)) { if (__Pyx_Generator_CheckExact(yf)) {
ret = __Pyx_Generator_Throw(yf, args); ret = __Pyx_Coroutine_Throw(yf, args);
} else { } else
#endif
#ifdef __Pyx_Coroutine_USED
if (__Pyx_Coroutine_CheckExact(yf)) {
ret = __Pyx_Coroutine_Throw(yf, args);
} else
#endif
{
PyObject *meth = __Pyx_PyObject_GetAttrStr(yf, PYIDENT("throw")); PyObject *meth = __Pyx_PyObject_GetAttrStr(yf, PYIDENT("throw"));
if (unlikely(!meth)) { if (unlikely(!meth)) {
Py_DECREF(yf); Py_DECREF(yf);
...@@ -463,7 +486,7 @@ static PyObject *__Pyx_Generator_Throw(PyObject *self, PyObject *args) { ...@@ -463,7 +486,7 @@ static PyObject *__Pyx_Generator_Throw(PyObject *self, PyObject *args) {
return NULL; return NULL;
} }
PyErr_Clear(); PyErr_Clear();
__Pyx_Generator_Undelegate(gen); __Pyx_Coroutine_Undelegate(gen);
gen->is_running = 0; gen->is_running = 0;
goto throw_here; goto throw_here;
} }
...@@ -473,17 +496,17 @@ static PyObject *__Pyx_Generator_Throw(PyObject *self, PyObject *args) { ...@@ -473,17 +496,17 @@ static PyObject *__Pyx_Generator_Throw(PyObject *self, PyObject *args) {
gen->is_running = 0; gen->is_running = 0;
Py_DECREF(yf); Py_DECREF(yf);
if (!ret) { if (!ret) {
ret = __Pyx_Generator_FinishDelegation(gen); ret = __Pyx_Coroutine_FinishDelegation(gen);
} }
return __Pyx_Generator_MethodReturn(ret); return __Pyx_Coroutine_MethodReturn(ret);
} }
throw_here: throw_here:
__Pyx_Raise(typ, val, tb, NULL); __Pyx_Raise(typ, val, tb, NULL);
return __Pyx_Generator_MethodReturn(__Pyx_Generator_SendEx(gen, NULL)); return __Pyx_Coroutine_MethodReturn(__Pyx_Coroutine_SendEx(gen, NULL));
} }
static int __Pyx_Generator_traverse(PyObject *self, visitproc visit, void *arg) { static int __Pyx_Coroutine_traverse(PyObject *self, visitproc visit, void *arg) {
__pyx_GeneratorObject *gen = (__pyx_GeneratorObject *) self; __pyx_CoroutineObject *gen = (__pyx_CoroutineObject *) self;
Py_VISIT(gen->closure); Py_VISIT(gen->closure);
Py_VISIT(gen->classobj); Py_VISIT(gen->classobj);
...@@ -494,8 +517,8 @@ static int __Pyx_Generator_traverse(PyObject *self, visitproc visit, void *arg) ...@@ -494,8 +517,8 @@ static int __Pyx_Generator_traverse(PyObject *self, visitproc visit, void *arg)
return 0; return 0;
} }
static int __Pyx_Generator_clear(PyObject *self) { static int __Pyx_Coroutine_clear(PyObject *self) {
__pyx_GeneratorObject *gen = (__pyx_GeneratorObject *) self; __pyx_CoroutineObject *gen = (__pyx_CoroutineObject *) self;
Py_CLEAR(gen->closure); Py_CLEAR(gen->closure);
Py_CLEAR(gen->classobj); Py_CLEAR(gen->classobj);
...@@ -508,8 +531,8 @@ static int __Pyx_Generator_clear(PyObject *self) { ...@@ -508,8 +531,8 @@ static int __Pyx_Generator_clear(PyObject *self) {
return 0; return 0;
} }
static void __Pyx_Generator_dealloc(PyObject *self) { static void __Pyx_Coroutine_dealloc(PyObject *self) {
__pyx_GeneratorObject *gen = (__pyx_GeneratorObject *) self; __pyx_CoroutineObject *gen = (__pyx_CoroutineObject *) self;
PyObject_GC_UnTrack(gen); PyObject_GC_UnTrack(gen);
if (gen->gi_weakreflist != NULL) if (gen->gi_weakreflist != NULL)
...@@ -531,14 +554,14 @@ static void __Pyx_Generator_dealloc(PyObject *self) { ...@@ -531,14 +554,14 @@ static void __Pyx_Generator_dealloc(PyObject *self) {
PyObject_GC_UnTrack(self); PyObject_GC_UnTrack(self);
} }
__Pyx_Generator_clear(self); __Pyx_Coroutine_clear(self);
PyObject_GC_Del(gen); PyObject_GC_Del(gen);
} }
static void __Pyx_Generator_del(PyObject *self) { static void __Pyx_Coroutine_del(PyObject *self) {
PyObject *res; PyObject *res;
PyObject *error_type, *error_value, *error_traceback; PyObject *error_type, *error_value, *error_traceback;
__pyx_GeneratorObject *gen = (__pyx_GeneratorObject *) self; __pyx_CoroutineObject *gen = (__pyx_CoroutineObject *) self;
if (gen->resume_label <= 0) if (gen->resume_label <= 0)
return ; return ;
...@@ -552,7 +575,7 @@ static void __Pyx_Generator_del(PyObject *self) { ...@@ -552,7 +575,7 @@ static void __Pyx_Generator_del(PyObject *self) {
// Save the current exception, if any. // Save the current exception, if any.
__Pyx_ErrFetch(&error_type, &error_value, &error_traceback); __Pyx_ErrFetch(&error_type, &error_value, &error_traceback);
res = __Pyx_Generator_Close(self); res = __Pyx_Coroutine_Close(self);
if (res == NULL) if (res == NULL)
PyErr_WriteUnraisable(self); PyErr_WriteUnraisable(self);
...@@ -599,14 +622,14 @@ static void __Pyx_Generator_del(PyObject *self) { ...@@ -599,14 +622,14 @@ static void __Pyx_Generator_del(PyObject *self) {
} }
static PyObject * static PyObject *
__Pyx_Generator_get_name(__pyx_GeneratorObject *self) __Pyx_Coroutine_get_name(__pyx_CoroutineObject *self)
{ {
Py_INCREF(self->gi_name); Py_INCREF(self->gi_name);
return self->gi_name; return self->gi_name;
} }
static int static int
__Pyx_Generator_set_name(__pyx_GeneratorObject *self, PyObject *value) __Pyx_Coroutine_set_name(__pyx_CoroutineObject *self, PyObject *value)
{ {
PyObject *tmp; PyObject *tmp;
...@@ -627,14 +650,14 @@ __Pyx_Generator_set_name(__pyx_GeneratorObject *self, PyObject *value) ...@@ -627,14 +650,14 @@ __Pyx_Generator_set_name(__pyx_GeneratorObject *self, PyObject *value)
} }
static PyObject * static PyObject *
__Pyx_Generator_get_qualname(__pyx_GeneratorObject *self) __Pyx_Coroutine_get_qualname(__pyx_CoroutineObject *self)
{ {
Py_INCREF(self->gi_qualname); Py_INCREF(self->gi_qualname);
return self->gi_qualname; return self->gi_qualname;
} }
static int static int
__Pyx_Generator_set_qualname(__pyx_GeneratorObject *self, PyObject *value) __Pyx_Coroutine_set_qualname(__pyx_CoroutineObject *self, PyObject *value)
{ {
PyObject *tmp; PyObject *tmp;
...@@ -654,32 +677,64 @@ __Pyx_Generator_set_qualname(__pyx_GeneratorObject *self, PyObject *value) ...@@ -654,32 +677,64 @@ __Pyx_Generator_set_qualname(__pyx_GeneratorObject *self, PyObject *value)
return 0; return 0;
} }
static PyGetSetDef __pyx_Generator_getsets[] = { static PyGetSetDef __pyx_Coroutine_getsets[] = {
{(char *) "__name__", (getter)__Pyx_Generator_get_name, (setter)__Pyx_Generator_set_name, {(char *) "__name__", (getter)__Pyx_Coroutine_get_name, (setter)__Pyx_Coroutine_set_name,
(char*) PyDoc_STR("name of the generator"), 0}, (char*) PyDoc_STR("name of the generator"), 0},
{(char *) "__qualname__", (getter)__Pyx_Generator_get_qualname, (setter)__Pyx_Generator_set_qualname, {(char *) "__qualname__", (getter)__Pyx_Coroutine_get_qualname, (setter)__Pyx_Coroutine_set_qualname,
(char*) PyDoc_STR("qualified name of the generator"), 0}, (char*) PyDoc_STR("qualified name of the generator"), 0},
{0, 0, 0, 0, 0} {0, 0, 0, 0, 0}
}; };
static PyMemberDef __pyx_Generator_memberlist[] = { static PyMemberDef __pyx_Coroutine_memberlist[] = {
{(char *) "gi_running", T_BOOL, offsetof(__pyx_GeneratorObject, is_running), READONLY, NULL}, {(char *) "gi_running", T_BOOL, offsetof(__pyx_CoroutineObject, is_running), READONLY, NULL},
{0, 0, 0, 0, 0} {0, 0, 0, 0, 0}
}; };
static PyMethodDef __pyx_Generator_methods[] = { static PyMethodDef __pyx_Coroutine_methods[] = {
{"send", (PyCFunction) __Pyx_Generator_Send, METH_O, 0}, {"send", (PyCFunction) __Pyx_Coroutine_Send, METH_O, 0},
{"throw", (PyCFunction) __Pyx_Generator_Throw, METH_VARARGS, 0}, {"throw", (PyCFunction) __Pyx_Coroutine_Throw, METH_VARARGS, 0},
{"close", (PyCFunction) __Pyx_Generator_Close, METH_NOARGS, 0}, {"close", (PyCFunction) __Pyx_Coroutine_Close, METH_NOARGS, 0},
{0, 0, 0, 0} {0, 0, 0, 0}
}; };
static PyTypeObject __pyx_GeneratorType_type = { static __pyx_CoroutineObject *__Pyx__Coroutine_New(PyTypeObject* type, __pyx_coroutine_body_t body,
PyObject *closure, PyObject *name, PyObject *qualname) {
__pyx_CoroutineObject *gen = PyObject_GC_New(__pyx_CoroutineObject, type);
if (gen == NULL)
return NULL;
gen->body = body;
gen->closure = closure;
Py_XINCREF(closure);
gen->is_running = 0;
gen->resume_label = 0;
gen->classobj = NULL;
gen->yieldfrom = NULL;
gen->exc_type = NULL;
gen->exc_value = NULL;
gen->exc_traceback = NULL;
gen->gi_weakreflist = NULL;
Py_XINCREF(qualname);
gen->gi_qualname = qualname;
Py_XINCREF(name);
gen->gi_name = name;
PyObject_GC_Track(gen);
return gen;
}
//////////////////// Coroutine ////////////////////
//@requires: CoroutineBase
//@requires: PatchGeneratorABC
static PyTypeObject __pyx_CoroutineType_type = {
PyVarObject_HEAD_INIT(0, 0) PyVarObject_HEAD_INIT(0, 0)
"generator", /*tp_name*/ "coroutine", /*tp_name*/
sizeof(__pyx_GeneratorObject), /*tp_basicsize*/ sizeof(__pyx_CoroutineObject), /*tp_basicsize*/
0, /*tp_itemsize*/ 0, /*tp_itemsize*/
(destructor) __Pyx_Generator_dealloc,/*tp_dealloc*/ (destructor) __Pyx_Coroutine_dealloc,/*tp_dealloc*/
0, /*tp_print*/ 0, /*tp_print*/
0, /*tp_getattr*/ 0, /*tp_getattr*/
0, /*tp_setattr*/ 0, /*tp_setattr*/
...@@ -700,15 +755,15 @@ static PyTypeObject __pyx_GeneratorType_type = { ...@@ -700,15 +755,15 @@ static PyTypeObject __pyx_GeneratorType_type = {
0, /*tp_as_buffer*/ 0, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
0, /*tp_doc*/ 0, /*tp_doc*/
(traverseproc) __Pyx_Generator_traverse, /*tp_traverse*/ (traverseproc) __Pyx_Coroutine_traverse, /*tp_traverse*/
0, /*tp_clear*/ 0, /*tp_clear*/
0, /*tp_richcompare*/ 0, /*tp_richcompare*/
offsetof(__pyx_GeneratorObject, gi_weakreflist), /*tp_weaklistoffset*/ offsetof(__pyx_CoroutineObject, gi_weakreflist), /*tp_weaklistoffset*/
0, /*tp_iter*/ 0, /*tp_iter*/
(iternextfunc) __Pyx_Generator_Next, /*tp_iternext*/ 0, /*tp_iternext*/
__pyx_Generator_methods, /*tp_methods*/ __pyx_Coroutine_methods, /*tp_methods*/
__pyx_Generator_memberlist, /*tp_members*/ __pyx_Coroutine_memberlist, /*tp_members*/
__pyx_Generator_getsets, /*tp_getset*/ __pyx_Coroutine_getsets, /*tp_getset*/
0, /*tp_base*/ 0, /*tp_base*/
0, /*tp_dict*/ 0, /*tp_dict*/
0, /*tp_descr_get*/ 0, /*tp_descr_get*/
...@@ -727,49 +782,122 @@ static PyTypeObject __pyx_GeneratorType_type = { ...@@ -727,49 +782,122 @@ static PyTypeObject __pyx_GeneratorType_type = {
#if PY_VERSION_HEX >= 0x030400a1 #if PY_VERSION_HEX >= 0x030400a1
0, /*tp_del*/ 0, /*tp_del*/
#else #else
__Pyx_Generator_del, /*tp_del*/ __Pyx_Coroutine_del, /*tp_del*/
#endif #endif
0, /*tp_version_tag*/ 0, /*tp_version_tag*/
#if PY_VERSION_HEX >= 0x030400a1 #if PY_VERSION_HEX >= 0x030400a1
__Pyx_Generator_del, /*tp_finalize*/ __Pyx_Coroutine_del, /*tp_finalize*/
#endif #endif
}; };
static __pyx_GeneratorObject *__Pyx_Generator_New(__pyx_generator_body_t body, static int __pyx_Generator_init(void) {
PyObject *closure, PyObject *name, PyObject *qualname) { // on Windows, C-API functions can't be used in slots statically
__pyx_GeneratorObject *gen = __pyx_CoroutineType_type.tp_getattro = PyObject_GenericGetAttr;
PyObject_GC_New(__pyx_GeneratorObject, __pyx_GeneratorType);
if (gen == NULL) __pyx_CoroutineType = __Pyx_FetchCommonType(&__pyx_CoroutineType_type);
return NULL; if (unlikely(!__pyx_CoroutineType)) {
return -1;
}
return 0;
}
gen->body = body;
gen->closure = closure;
Py_XINCREF(closure);
gen->is_running = 0;
gen->resume_label = 0;
gen->classobj = NULL;
gen->yieldfrom = NULL;
gen->exc_type = NULL;
gen->exc_value = NULL;
gen->exc_traceback = NULL;
gen->gi_weakreflist = NULL;
Py_XINCREF(qualname);
gen->gi_qualname = qualname;
Py_XINCREF(name);
gen->gi_name = name;
PyObject_GC_Track(gen); //////////////////// Generator ////////////////////
return gen; //@requires: CoroutineBase
//@requires: PatchGeneratorABC
static PyObject *__Pyx_Generator_Next(PyObject *self);
static PyObject *__Pyx_Generator_Next(PyObject *self) {
__pyx_CoroutineObject *gen = (__pyx_CoroutineObject*) self;
PyObject *yf = gen->yieldfrom;
if (unlikely(__Pyx_Coroutine_CheckRunning(gen)))
return NULL;
if (yf) {
PyObject *ret;
// FIXME: does this really need an INCREF() ?
//Py_INCREF(yf);
// YieldFrom code ensures that yf is an iterator
gen->is_running = 1;
ret = Py_TYPE(yf)->tp_iternext(yf);
gen->is_running = 0;
//Py_DECREF(yf);
if (likely(ret)) {
return ret;
}
return __Pyx_Coroutine_FinishDelegation(gen);
}
return __Pyx_Coroutine_SendEx(gen, Py_None);
} }
static PyTypeObject __pyx_GeneratorType_type = {
PyVarObject_HEAD_INIT(0, 0)
"generator", /*tp_name*/
sizeof(__pyx_CoroutineObject), /*tp_basicsize*/
0, /*tp_itemsize*/
(destructor) __Pyx_Coroutine_dealloc,/*tp_dealloc*/
0, /*tp_print*/
0, /*tp_getattr*/
0, /*tp_setattr*/
#if PY_MAJOR_VERSION < 3
0, /*tp_compare*/
#else
0, /*reserved*/
#endif
0, /*tp_repr*/
0, /*tp_as_number*/
0, /*tp_as_sequence*/
0, /*tp_as_mapping*/
0, /*tp_hash*/
0, /*tp_call*/
0, /*tp_str*/
0, /*tp_getattro*/
0, /*tp_setattro*/
0, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
0, /*tp_doc*/
(traverseproc) __Pyx_Coroutine_traverse, /*tp_traverse*/
0, /*tp_clear*/
0, /*tp_richcompare*/
offsetof(__pyx_CoroutineObject, gi_weakreflist), /*tp_weaklistoffset*/
0, /*tp_iter*/
(iternextfunc) __Pyx_Generator_Next, /*tp_iternext*/
__pyx_Coroutine_methods, /*tp_methods*/
__pyx_Coroutine_memberlist, /*tp_members*/
__pyx_Coroutine_getsets, /*tp_getset*/
0, /*tp_base*/
0, /*tp_dict*/
0, /*tp_descr_get*/
0, /*tp_descr_set*/
0, /*tp_dictoffset*/
0, /*tp_init*/
0, /*tp_alloc*/
0, /*tp_new*/
0, /*tp_free*/
0, /*tp_is_gc*/
0, /*tp_bases*/
0, /*tp_mro*/
0, /*tp_cache*/
0, /*tp_subclasses*/
0, /*tp_weaklist*/
#if PY_VERSION_HEX >= 0x030400a1
0, /*tp_del*/
#else
__Pyx_Coroutine_del, /*tp_del*/
#endif
0, /*tp_version_tag*/
#if PY_VERSION_HEX >= 0x030400a1
__Pyx_Coroutine_del, /*tp_finalize*/
#endif
};
static int __pyx_Generator_init(void) { static int __pyx_Generator_init(void) {
// on Windows, C-API functions can't be used in slots statically // on Windows, C-API functions can't be used in slots statically
__pyx_GeneratorType_type.tp_getattro = PyObject_GenericGetAttr; __pyx_GeneratorType_type.tp_getattro = PyObject_GenericGetAttr;
__pyx_GeneratorType_type.tp_iter = PyObject_SelfIter; __pyx_GeneratorType_type.tp_iter = PyObject_SelfIter;
__pyx_GeneratorType = __Pyx_FetchCommonType(&__pyx_GeneratorType_type); __pyx_GeneratorType = __Pyx_FetchCommonType(&__pyx_GeneratorType_type);
if (__pyx_GeneratorType == NULL) { if (unlikely(!__pyx_GeneratorType)) {
return -1; return -1;
} }
return 0; return 0;
...@@ -805,18 +933,23 @@ static void __Pyx__ReturnWithStopIteration(PyObject* value) { ...@@ -805,18 +933,23 @@ static void __Pyx__ReturnWithStopIteration(PyObject* value) {
#endif #endif
//////////////////// PatchModuleWithGenerator.proto //////////////////// //////////////////// PatchModuleWithCoroutine.proto ////////////////////
static PyObject* __Pyx_Generator_patch_module(PyObject* module, const char* py_code); /*proto*/ static PyObject* __Pyx_Coroutine_patch_module(PyObject* module, const char* py_code); /*proto*/
//////////////////// PatchModuleWithGenerator //////////////////// //////////////////// PatchModuleWithCoroutine ////////////////////
//@substitute: naming //@substitute: naming
static PyObject* __Pyx_Generator_patch_module(PyObject* module, const char* py_code) { static PyObject* __Pyx_Coroutine_patch_module(PyObject* module, const char* py_code) {
#ifdef __Pyx_Generator_USED #if defined(__Pyx_Generator_USED) || defined(__Pyx_Coroutine_USED)
PyObject *globals, *result_obj; PyObject *globals, *result_obj;
globals = PyDict_New(); if (unlikely(!globals)) goto ignore; globals = PyDict_New(); if (unlikely(!globals)) goto ignore;
#ifdef __Pyx_Coroutine_USED
if (unlikely(PyDict_SetItemString(globals, "_cython_coroutine_type", (PyObject*)__pyx_CoroutineType) < 0)) goto ignore;
#endif
#ifdef __Pyx_Generator_USED
if (unlikely(PyDict_SetItemString(globals, "_cython_generator_type", (PyObject*)__pyx_GeneratorType) < 0)) goto ignore; if (unlikely(PyDict_SetItemString(globals, "_cython_generator_type", (PyObject*)__pyx_GeneratorType) < 0)) goto ignore;
#endif
if (unlikely(PyDict_SetItemString(globals, "_module", module) < 0)) goto ignore; if (unlikely(PyDict_SetItemString(globals, "_module", module) < 0)) goto ignore;
if (unlikely(PyDict_SetItemString(globals, "__builtins__", $builtins_cname) < 0)) goto ignore; if (unlikely(PyDict_SetItemString(globals, "__builtins__", $builtins_cname) < 0)) goto ignore;
result_obj = PyRun_String(py_code, Py_file_input, globals, globals); result_obj = PyRun_String(py_code, Py_file_input, globals, globals);
...@@ -847,10 +980,10 @@ ignore: ...@@ -847,10 +980,10 @@ ignore:
static int __Pyx_patch_abc(void); /*proto*/ static int __Pyx_patch_abc(void); /*proto*/
//////////////////// PatchGeneratorABC //////////////////// //////////////////// PatchGeneratorABC ////////////////////
//@requires: PatchModuleWithGenerator //@requires: PatchModuleWithCoroutine
static int __Pyx_patch_abc(void) { static int __Pyx_patch_abc(void) {
#if defined(__Pyx_Generator_USED) && (!defined(CYTHON_PATCH_ABC) || CYTHON_PATCH_ABC) #if (defined(__Pyx_Generator_USED) || defined(__Pyx_Coroutine_USED)) && (!defined(CYTHON_PATCH_ABC) || CYTHON_PATCH_ABC)
static int abc_patched = 0; static int abc_patched = 0;
if (!abc_patched) { if (!abc_patched) {
PyObject *module; PyObject *module;
...@@ -859,19 +992,40 @@ static int __Pyx_patch_abc(void) { ...@@ -859,19 +992,40 @@ static int __Pyx_patch_abc(void) {
PyErr_WriteUnraisable(NULL); PyErr_WriteUnraisable(NULL);
if (unlikely(PyErr_WarnEx(PyExc_RuntimeWarning, if (unlikely(PyErr_WarnEx(PyExc_RuntimeWarning,
((PY_VERSION_HEX >= 0x03030000) ? ((PY_VERSION_HEX >= 0x03030000) ?
"Cython module failed to patch collections.abc.Generator" : "Cython module failed to patch collections.abc module" :
"Cython module failed to patch collections.Generator"), 1) < 0)) { "Cython module failed to patch collections module"), 1) < 0)) {
return -1; return -1;
} }
} else { } else {
PyObject *abc = PyObject_GetAttrString(module, "Generator"); PyObject *abc;
int needs_generator = 1, needs_coroutine = 1;
#ifdef __Pyx_Generator_USED
abc = PyObject_GetAttrString(module, "Generator");
if (abc) { if (abc) {
abc_patched = 1; needs_generator = 0;
Py_DECREF(abc);
} else {
PyErr_Clear();
}
#else
needs_generator = 0;
#endif
#ifdef __Pyx_Coroutine_USED
abc = PyObject_GetAttrString(module, "Coroutine");
if (abc) {
needs_coroutine = 0;
Py_DECREF(abc); Py_DECREF(abc);
} else { } else {
PyErr_Clear(); PyErr_Clear();
module = __Pyx_Generator_patch_module( }
module, CSTRING("""\ #else
needs_coroutine = 0;
#endif
if (needs_coroutine || needs_generator) {
module = __Pyx_Coroutine_patch_module(
module,
#ifdef __Pyx_Generator_USED
CSTRING("""\
def mk_gen(): def mk_gen():
from abc import abstractmethod from abc import abstractmethod
...@@ -931,6 +1085,88 @@ def mk_gen(): ...@@ -931,6 +1085,88 @@ def mk_gen():
_module.Generator = mk_gen() _module.Generator = mk_gen()
""") """)
#endif
#ifdef __Pyx_Coroutine_USED
CSTRING("""\
def mk_coroutine():
from abc import abstractmethod
""")
#if PY_MAJOR_VERSION >= 3
" class Coroutine(metaclass=_module.ABCMeta):\n"
#else
" class Coroutine(object):\n"
" __metaclass__ = _module.ABCMeta\n"
#endif
CSTRING("""\
__slots__ = ()
@abstractmethod
def send(self, value):
'''Send a value into the coroutine.
Return next yielded value or raise StopIteration.
'''
raise StopIteration
@abstractmethod
def throw(self, typ, val=None, tb=None):
'''Raise an exception in the coroutine.
Return next yielded value or raise StopIteration.
'''
if val is None:
if tb is None:
raise typ
val = typ()
if tb is not None:
val = val.with_traceback(tb)
raise val
def close(self):
'''Raise GeneratorExit inside coroutine.
'''
try:
self.throw(GeneratorExit)
except (GeneratorExit, StopIteration):
pass
else:
raise RuntimeError('coroutine ignored GeneratorExit')
""")
#if PY_MAJOR_VERSION >= 3
" class Awaitable(metaclass=_module.ABCMeta):\n"
#else
" class Awaitable(object):\n"
" __metaclass__ = _module.ABCMeta\n"
#endif
CSTRING("""\
__slots__ = ()
@abstractmethod
def __await__(self):
yield
@classmethod
def __subclasshook__(cls, C):
if cls is Awaitable:
for B in C.__mro__:
if '__await__' in B.__dict__:
if B.__dict__['__await__']:
return True
break
return NotImplemented
try:
_module.Awaitable
except AttributeError:
Awaitable.register(Coroutine)
_module.Awaitable = Awaitable
Coroutine.register(_cython_coroutine_type)
return Coroutine
_module.Coroutine = mk_coroutine()
""")
#endif
); );
abc_patched = 1; abc_patched = 1;
if (unlikely(!module)) if (unlikely(!module))
...@@ -940,8 +1176,8 @@ _module.Generator = mk_gen() ...@@ -940,8 +1176,8 @@ _module.Generator = mk_gen()
} }
} }
#else #else
// avoid "unused" warning for __Pyx_Generator_patch_module() // avoid "unused" warning for __Pyx_Coroutine_patch_module()
if (0) __Pyx_Generator_patch_module(NULL, NULL); if (0) __Pyx_Coroutine_patch_module(NULL, NULL);
#endif #endif
return 0; return 0;
} }
...@@ -953,7 +1189,7 @@ _module.Generator = mk_gen() ...@@ -953,7 +1189,7 @@ _module.Generator = mk_gen()
static PyObject* __Pyx_patch_asyncio(PyObject* module); /*proto*/ static PyObject* __Pyx_patch_asyncio(PyObject* module); /*proto*/
//////////////////// PatchAsyncIO //////////////////// //////////////////// PatchAsyncIO ////////////////////
//@requires: PatchModuleWithGenerator //@requires: PatchModuleWithCoroutine
//@requires: PatchInspect //@requires: PatchInspect
static PyObject* __Pyx_patch_asyncio(PyObject* module) { static PyObject* __Pyx_patch_asyncio(PyObject* module) {
...@@ -964,7 +1200,7 @@ static PyObject* __Pyx_patch_asyncio(PyObject* module) { ...@@ -964,7 +1200,7 @@ static PyObject* __Pyx_patch_asyncio(PyObject* module) {
PyObject *package; PyObject *package;
package = __Pyx_Import(PYIDENT("asyncio.coroutines"), NULL, 0); package = __Pyx_Import(PYIDENT("asyncio.coroutines"), NULL, 0);
if (package) { if (package) {
patch_module = __Pyx_Generator_patch_module( patch_module = __Pyx_Coroutine_patch_module(
PyObject_GetAttrString(package, "coroutines"), CSTRING("""\ PyObject_GetAttrString(package, "coroutines"), CSTRING("""\
old_types = getattr(_module, '_COROUTINE_TYPES', None) old_types = getattr(_module, '_COROUTINE_TYPES', None)
if old_types is not None and _cython_generator_type not in old_types: if old_types is not None and _cython_generator_type not in old_types:
...@@ -977,7 +1213,7 @@ if old_types is not None and _cython_generator_type not in old_types: ...@@ -977,7 +1213,7 @@ if old_types is not None and _cython_generator_type not in old_types:
PyErr_Clear(); PyErr_Clear();
package = __Pyx_Import(PYIDENT("asyncio.tasks"), NULL, 0); package = __Pyx_Import(PYIDENT("asyncio.tasks"), NULL, 0);
if (unlikely(!package)) goto asyncio_done; if (unlikely(!package)) goto asyncio_done;
patch_module = __Pyx_Generator_patch_module( patch_module = __Pyx_Coroutine_patch_module(
PyObject_GetAttrString(package, "tasks"), CSTRING("""\ PyObject_GetAttrString(package, "tasks"), CSTRING("""\
if (hasattr(_module, 'iscoroutine') and if (hasattr(_module, 'iscoroutine') and
getattr(_module.iscoroutine, '_cython_generator_type', None) is not _cython_generator_type): getattr(_module.iscoroutine, '_cython_generator_type', None) is not _cython_generator_type):
...@@ -1023,8 +1259,8 @@ ignore: ...@@ -1023,8 +1259,8 @@ ignore:
module = NULL; module = NULL;
} }
#else #else
// avoid "unused" warning for __Pyx_Generator_patch_module() // avoid "unused" warning for __Pyx_Coroutine_patch_module()
if (0) return __Pyx_Generator_patch_module(module, NULL); if (0) return __Pyx_Coroutine_patch_module(module, NULL);
#endif #endif
return module; return module;
} }
...@@ -1036,14 +1272,16 @@ ignore: ...@@ -1036,14 +1272,16 @@ ignore:
static PyObject* __Pyx_patch_inspect(PyObject* module); /*proto*/ static PyObject* __Pyx_patch_inspect(PyObject* module); /*proto*/
//////////////////// PatchInspect //////////////////// //////////////////// PatchInspect ////////////////////
//@requires: PatchModuleWithGenerator //@requires: PatchModuleWithCoroutine
static PyObject* __Pyx_patch_inspect(PyObject* module) { static PyObject* __Pyx_patch_inspect(PyObject* module) {
#if defined(__Pyx_Generator_USED) && (!defined(CYTHON_PATCH_INSPECT) || CYTHON_PATCH_INSPECT) #if (defined(__Pyx_Generator_USED) || defined(__Pyx_Coroutine_USED)) && (!defined(CYTHON_PATCH_INSPECT) || CYTHON_PATCH_INSPECT)
static int inspect_patched = 0; static int inspect_patched = 0;
if (unlikely((!inspect_patched) && module)) { if (unlikely((!inspect_patched) && module)) {
module = __Pyx_Generator_patch_module( module = __Pyx_Coroutine_patch_module(
module, CSTRING("""\ module,
#ifdef __Pyx_Generator_USED
CSTRING("""\
if getattr(_module.isgenerator, '_cython_generator_type', None) is not _cython_generator_type: if getattr(_module.isgenerator, '_cython_generator_type', None) is not _cython_generator_type:
def cy_wrap(orig_func, cython_generator_type=_cython_generator_type, type=type): def cy_wrap(orig_func, cython_generator_type=_cython_generator_type, type=type):
def cy_isgenerator(obj): return type(obj) is cython_generator_type or orig_func(obj) def cy_isgenerator(obj): return type(obj) is cython_generator_type or orig_func(obj)
...@@ -1051,12 +1289,48 @@ if getattr(_module.isgenerator, '_cython_generator_type', None) is not _cython_g ...@@ -1051,12 +1289,48 @@ if getattr(_module.isgenerator, '_cython_generator_type', None) is not _cython_g
return cy_isgenerator return cy_isgenerator
_module.isgenerator = cy_wrap(_module.isgenerator) _module.isgenerator = cy_wrap(_module.isgenerator)
""") """)
#endif
#ifdef __Pyx_Coroutine_USED
CSTRING("""\
try:
_module.iscoroutine
except AttributeError:
def cy_wrap(cython_coroutine_type=_cython_coroutine_type, type=type):
try:
from collections.abc import Coroutine
except ImportError:
from collections import Coroutine
def cy_iscoroutine(obj): return isinstance(obj, Coroutine)
return cy_iscoroutine
try:
_module.iscoroutine = cy_wrap()
except ImportError:
pass
try:
_module.isawaitable
except AttributeError:
def cy_wrap(cython_coroutine_type=_cython_coroutine_type, type=type):
try:
from collections.abc import Awaitable
except ImportError:
from collections import Awaitable
def cy_isawaitable(obj): return isinstance(obj, Awaitable)
return cy_isawaitable
try:
_module.isawaitable = cy_wrap()
except ImportError:
pass
""")
#endif
); );
inspect_patched = 1; inspect_patched = 1;
} }
#else #else
// avoid "unused" warning for __Pyx_Generator_patch_module() // avoid "unused" warning for __Pyx_Coroutine_patch_module()
if (0) return __Pyx_Generator_patch_module(module, NULL); if (0) return __Pyx_Coroutine_patch_module(module, NULL);
#endif #endif
return module; return module;
} }
...@@ -68,7 +68,7 @@ static CYTHON_INLINE void __Pyx_CyFunction_SetAnnotationsDict(PyObject *m, ...@@ -68,7 +68,7 @@ static CYTHON_INLINE void __Pyx_CyFunction_SetAnnotationsDict(PyObject *m,
PyObject *dict); PyObject *dict);
static int __Pyx_CyFunction_init(void); static int __pyx_CyFunction_init(void);
//////////////////// CythonFunction //////////////////// //////////////////// CythonFunction ////////////////////
//@substitute: naming //@substitute: naming
...@@ -693,7 +693,7 @@ static PyTypeObject __pyx_CyFunctionType_type = { ...@@ -693,7 +693,7 @@ static PyTypeObject __pyx_CyFunctionType_type = {
}; };
static int __Pyx_CyFunction_init(void) { static int __pyx_CyFunction_init(void) {
#if !CYTHON_COMPILING_IN_PYPY #if !CYTHON_COMPILING_IN_PYPY
// avoid a useless level of call indirection // avoid a useless level of call indirection
__pyx_CyFunctionType_type.tp_call = PyCFunction_Call; __pyx_CyFunctionType_type.tp_call = PyCFunction_Call;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment