From 2e00df5c7e56883c376f0cef83759cd889a37c15 Mon Sep 17 00:00:00 2001 From: Stefan Behnel <stefan_ml@behnel.de> Date: Thu, 28 May 2015 21:00:50 +0200 Subject: [PATCH] Revert "make Coroutine type a non-iterable/iterator and instead let __await__() return a thin Iterator wrapper" This reverts commit cf51fa4eafec6dcf840bfa4c616e3a9391fd6bec. --- Cython/Utility/Coroutine.c | 124 +++------------------------ tests/run/test_coroutines_pep492.pyx | 5 +- 2 files changed, 15 insertions(+), 114 deletions(-) diff --git a/Cython/Utility/Coroutine.c b/Cython/Utility/Coroutine.c index 290442f59..17df90fb4 100644 --- a/Cython/Utility/Coroutine.c +++ b/Cython/Utility/Coroutine.c @@ -19,8 +19,8 @@ static CYTHON_INLINE PyObject* __Pyx_Generator_Yield_From(__pyx_CoroutineObject && __Pyx_Coroutine_CheckExact(source)) { PyErr_Clear(); // TODO: this should only happen for types.coroutine()ed generators, but we can't determine that here - source_gen = __Pyx__Coroutine_await(source); - if (unlikely(!source_gen)) return NULL; + Py_INCREF(source); + source_gen = source; } else #endif return NULL; @@ -257,14 +257,12 @@ static int __Pyx_PyGen_FetchStopIterationValue(PyObject **pvalue); #define __Pyx_Coroutine_USED static PyTypeObject *__pyx_CoroutineType = 0; -static PyTypeObject *__pyx_CoroutineAwaitType = 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); -static CYTHON_INLINE PyObject *__Pyx__Coroutine_await(PyObject *coroutine); //////////////////// Generator.proto //////////////////// @@ -945,105 +943,6 @@ static __pyx_CoroutineObject *__Pyx__Coroutine_New(PyTypeObject* type, __pyx_cor //@requires: CoroutineBase //@requires: PatchGeneratorABC -typedef struct { - PyObject_HEAD - PyObject *coroutine; -} __pyx_CoroutineAwaitObject; - -static void __Pyx_CoroutineAwait_dealloc(PyObject *self) { - PyObject_GC_UnTrack(self); - Py_CLEAR(((__pyx_CoroutineAwaitObject*)self)->coroutine); - PyObject_GC_Del(self); -} - -static int __Pyx_CoroutineAwait_traverse(__pyx_CoroutineAwaitObject *self, visitproc visit, void *arg) { - Py_VISIT(self->coroutine); - return 0; -} - -static int __Pyx_CoroutineAwait_clear(__pyx_CoroutineAwaitObject *self) { - Py_CLEAR(self->coroutine); - return 0; -} - -static PyObject *__Pyx_CoroutineAwait_Next(__pyx_CoroutineAwaitObject *self) { - return __Pyx_Generator_Next(self->coroutine); -} - -static PyObject *__Pyx_CoroutineAwait_self(PyObject *self) { - Py_INCREF(self); - return self; -} - -static PyTypeObject __pyx_CoroutineAwaitType_type = { - PyVarObject_HEAD_INIT(0, 0) - "coroutine_await", /*tp_name*/ - sizeof(__pyx_CoroutineAwaitObject), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - (destructor) __Pyx_CoroutineAwait_dealloc,/*tp_dealloc*/ - 0, /*tp_print*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_as_async resp. tp_compare*/ - 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_CoroutineAwait_traverse, /*tp_traverse*/ - (inquiry) __Pyx_CoroutineAwait_clear, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - __Pyx_CoroutineAwait_self, /*tp_iter*/ - (iternextfunc) __Pyx_CoroutineAwait_Next, /*tp_iternext*/ - 0, /*tp_methods*/ - 0 , /*tp_members*/ - 0 , /*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*/ - 0, /*tp_del*/ - 0, /*tp_version_tag*/ -#if PY_VERSION_HEX >= 0x030400a1 - 0, /*tp_finalize*/ -#endif -}; - -static CYTHON_INLINE PyObject *__Pyx__Coroutine_await(PyObject *coroutine) { - PyObject *await = __pyx_CoroutineAwaitType->tp_alloc(__pyx_CoroutineAwaitType, 0); - if (unlikely(!await)) return NULL; - Py_INCREF(coroutine); - ((__pyx_CoroutineAwaitObject*)await)->coroutine = coroutine; - return await; -} - -static PyObject *__Pyx_Coroutine_await(PyObject *coroutine) { - if (unlikely(!coroutine || !__Pyx_Coroutine_CheckExact(coroutine))) { - PyErr_SetString(PyExc_TypeError, "invalid input, expected coroutine"); - return NULL; - } - return __Pyx__Coroutine_await(coroutine); -} - static void __Pyx_Coroutine_check_and_dealloc(PyObject *self) { __pyx_CoroutineObject *gen = (__pyx_CoroutineObject *) self; @@ -1092,19 +991,24 @@ static void __Pyx_Coroutine_check_and_dealloc(PyObject *self) { __Pyx_Coroutine_dealloc(self); } +static PyObject *__Pyx_Coroutine_return_self(PyObject *self) { + Py_INCREF(self); + return self; +} + static PyMethodDef __pyx_Coroutine_methods[] = { {"send", (PyCFunction) __Pyx_Coroutine_Send, METH_O, 0}, {"throw", (PyCFunction) __Pyx_Coroutine_Throw, METH_VARARGS, 0}, {"close", (PyCFunction) __Pyx_Coroutine_Close, METH_NOARGS, 0}, #if PY_VERSION_HEX < 0x030500B1 - {"__await__", (PyCFunction) __Pyx_Coroutine_await, METH_NOARGS, 0}, + {"__await__", (PyCFunction) __Pyx_Coroutine_return_self, METH_NOARGS, 0}, #endif {0, 0, 0, 0} }; #if PY_VERSION_HEX >= 0x030500B1 static PyAsyncMethods __pyx_Coroutine_as_async = { - __Pyx_Coroutine_await, /*am_await*/ + __Pyx_Coroutine_return_self, /*am_await*/ 0, /*am_aiter*/ 0, /*am_anext*/ }; @@ -1142,7 +1046,7 @@ static PyTypeObject __pyx_CoroutineType_type = { offsetof(__pyx_CoroutineObject, gi_weakreflist), /*tp_weaklistoffset*/ // no tp_iter() as iterator is only available through __await__() 0, /*tp_iter*/ - 0, /*tp_iternext*/ + (iternextfunc) __Pyx_Generator_Next, /*tp_iternext*/ __pyx_Coroutine_methods, /*tp_methods*/ __pyx_Coroutine_memberlist, /*tp_members*/ __pyx_Coroutine_getsets, /*tp_getset*/ @@ -1177,12 +1081,9 @@ static int __pyx_Coroutine_init(void) { __pyx_CoroutineType_type.tp_getattro = PyObject_GenericGetAttr; __pyx_CoroutineType = __Pyx_FetchCommonType(&__pyx_CoroutineType_type); - if (unlikely(!__pyx_CoroutineType)) - return -1; - - __pyx_CoroutineAwaitType = __Pyx_FetchCommonType(&__pyx_CoroutineAwaitType_type); - if (unlikely(!__pyx_CoroutineType)) + if (unlikely(!__pyx_CoroutineType)) { return -1; + } return 0; } @@ -1329,7 +1230,6 @@ static PyObject* __Pyx_Coroutine_patch_module(PyObject* module, const char* py_c 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; - if (unlikely(PyDict_SetItemString(globals, "_cython_coroutine_await_type", (PyObject*)__pyx_CoroutineAwaitType) < 0)) goto ignore; #endif #ifdef __Pyx_Generator_USED if (unlikely(PyDict_SetItemString(globals, "_cython_generator_type", (PyObject*)__pyx_GeneratorType) < 0)) goto ignore; diff --git a/tests/run/test_coroutines_pep492.pyx b/tests/run/test_coroutines_pep492.pyx index 853f4449d..3cd938f50 100644 --- a/tests/run/test_coroutines_pep492.pyx +++ b/tests/run/test_coroutines_pep492.pyx @@ -213,8 +213,9 @@ class CoroutineTest(unittest.TestCase): with check(): iter(foo()) - with check(): - next(foo()) + # in Cython: not iterable, but an iterator ... + #with check(): + # next(foo()) with silence_coro_gc(), check(): for i in foo(): -- 2.30.9