diff options
Diffstat (limited to 'Cython/Utility/AsyncGen.c')
-rw-r--r-- | Cython/Utility/AsyncGen.c | 293 |
1 files changed, 222 insertions, 71 deletions
diff --git a/Cython/Utility/AsyncGen.c b/Cython/Utility/AsyncGen.c index dd4bf3728..1085d4816 100644 --- a/Cython/Utility/AsyncGen.c +++ b/Cython/Utility/AsyncGen.c @@ -11,6 +11,7 @@ typedef struct { PyObject *ag_finalizer; int ag_hooks_inited; int ag_closed; + int ag_running_async; } __pyx_PyAsyncGenObject; static PyTypeObject *__pyx__PyAsyncGenWrappedValueType = 0; @@ -18,11 +19,11 @@ static PyTypeObject *__pyx__PyAsyncGenASendType = 0; static PyTypeObject *__pyx__PyAsyncGenAThrowType = 0; static PyTypeObject *__pyx_AsyncGenType = 0; -#define __Pyx_AsyncGen_CheckExact(obj) (Py_TYPE(obj) == __pyx_AsyncGenType) +#define __Pyx_AsyncGen_CheckExact(obj) __Pyx_IS_TYPE(obj, __pyx_AsyncGenType) #define __pyx_PyAsyncGenASend_CheckExact(o) \ - (Py_TYPE(o) == __pyx__PyAsyncGenASendType) + __Pyx_IS_TYPE(o, __pyx__PyAsyncGenASendType) #define __pyx_PyAsyncGenAThrow_CheckExact(o) \ - (Py_TYPE(o) == __pyx__PyAsyncGenAThrowType) + __Pyx_IS_TYPE(o, __pyx__PyAsyncGenAThrowType) static PyObject *__Pyx_async_gen_anext(PyObject *o); static CYTHON_INLINE PyObject *__Pyx_async_gen_asend_iternext(PyObject *o); @@ -42,10 +43,11 @@ static __pyx_CoroutineObject *__Pyx_AsyncGen_New( gen->ag_finalizer = NULL; gen->ag_closed = 0; gen->ag_hooks_inited = 0; + gen->ag_running_async = 0; return __Pyx__Coroutine_NewInit((__pyx_CoroutineObject*)gen, body, code, closure, name, qualname, module_name); } -static int __pyx_AsyncGen_init(void); +static int __pyx_AsyncGen_init(PyObject *module); static void __Pyx_PyAsyncGen_Fini(void); //////////////////// AsyncGenerator.cleanup //////////////////// @@ -127,6 +129,8 @@ static PyObject *__Pyx_async_gen_athrow_new(__pyx_PyAsyncGenObject *, PyObject * static const char *__Pyx_NON_INIT_CORO_MSG = "can't send non-None value to a just-started coroutine"; static const char *__Pyx_ASYNC_GEN_IGNORED_EXIT_MSG = "async generator ignored GeneratorExit"; +static const char *__Pyx_ASYNC_GEN_CANNOT_REUSE_SEND_MSG = "cannot reuse already awaited __anext__()/asend()"; +static const char *__Pyx_ASYNC_GEN_CANNOT_REUSE_CLOSE_MSG = "cannot reuse already awaited aclose()/athrow()"; typedef enum { __PYX_AWAITABLE_STATE_INIT, /* new awaitable, has not yet been iterated */ @@ -178,7 +182,7 @@ static __pyx_PyAsyncGenASend *__Pyx_ag_asend_freelist[_PyAsyncGen_MAXFREELIST]; static int __Pyx_ag_asend_freelist_free = 0; #define __pyx__PyAsyncGenWrappedValue_CheckExact(o) \ - (Py_TYPE(o) == __pyx__PyAsyncGenWrappedValueType) + __Pyx_IS_TYPE(o, __pyx__PyAsyncGenWrappedValueType) static int @@ -253,14 +257,15 @@ static PyObject * __Pyx_async_gen_anext(PyObject *g) { __pyx_PyAsyncGenObject *o = (__pyx_PyAsyncGenObject*) g; - if (__Pyx_async_gen_init_hooks(o)) { + if (unlikely(__Pyx_async_gen_init_hooks(o))) { return NULL; } return __Pyx_async_gen_asend_new(o, NULL); } static PyObject * -__Pyx_async_gen_anext_method(PyObject *g, CYTHON_UNUSED PyObject *arg) { +__Pyx_async_gen_anext_method(PyObject *g, PyObject *arg) { + CYTHON_UNUSED_VAR(arg); return __Pyx_async_gen_anext(g); } @@ -268,7 +273,7 @@ __Pyx_async_gen_anext_method(PyObject *g, CYTHON_UNUSED PyObject *arg) { static PyObject * __Pyx_async_gen_asend(__pyx_PyAsyncGenObject *o, PyObject *arg) { - if (__Pyx_async_gen_init_hooks(o)) { + if (unlikely(__Pyx_async_gen_init_hooks(o))) { return NULL; } return __Pyx_async_gen_asend_new(o, arg); @@ -276,9 +281,10 @@ __Pyx_async_gen_asend(__pyx_PyAsyncGenObject *o, PyObject *arg) static PyObject * -__Pyx_async_gen_aclose(__pyx_PyAsyncGenObject *o, CYTHON_UNUSED PyObject *arg) +__Pyx_async_gen_aclose(__pyx_PyAsyncGenObject *o, PyObject *arg) { - if (__Pyx_async_gen_init_hooks(o)) { + CYTHON_UNUSED_VAR(arg); + if (unlikely(__Pyx_async_gen_init_hooks(o))) { return NULL; } return __Pyx_async_gen_athrow_new(o, NULL); @@ -288,7 +294,7 @@ __Pyx_async_gen_aclose(__pyx_PyAsyncGenObject *o, CYTHON_UNUSED PyObject *arg) static PyObject * __Pyx_async_gen_athrow(__pyx_PyAsyncGenObject *o, PyObject *args) { - if (__Pyx_async_gen_init_hooks(o)) { + if (unlikely(__Pyx_async_gen_init_hooks(o))) { return NULL; } return __Pyx_async_gen_athrow_new(o, args); @@ -296,7 +302,8 @@ __Pyx_async_gen_athrow(__pyx_PyAsyncGenObject *o, PyObject *args) static PyObject * -__Pyx_async_gen_self_method(PyObject *g, CYTHON_UNUSED PyObject *arg) { +__Pyx_async_gen_self_method(PyObject *g, PyObject *arg) { + CYTHON_UNUSED_VAR(arg); return __Pyx_NewRef(g); } @@ -313,11 +320,15 @@ static PyGetSetDef __Pyx_async_gen_getsetlist[] = { static PyMemberDef __Pyx_async_gen_memberlist[] = { //REMOVED: {(char*) "ag_frame", T_OBJECT, offsetof(__pyx_PyAsyncGenObject, ag_frame), READONLY}, - {(char*) "ag_running", T_BOOL, offsetof(__pyx_CoroutineObject, is_running), READONLY, NULL}, + {(char*) "ag_running", T_BOOL, offsetof(__pyx_PyAsyncGenObject, ag_running_async), READONLY, NULL}, //REMOVED: {(char*) "ag_code", T_OBJECT, offsetof(__pyx_PyAsyncGenObject, ag_code), READONLY}, //ADDED: "ag_await" {(char*) "ag_await", T_OBJECT, offsetof(__pyx_CoroutineObject, yieldfrom), READONLY, (char*) PyDoc_STR("object being awaited on, or None")}, + {(char *) "__module__", T_OBJECT, offsetof(__pyx_CoroutineObject, gi_modulename), 0, 0}, +#if CYTHON_USE_TYPE_SPECS + {(char *) "__weaklistoffset__", T_PYSSIZET, offsetof(__pyx_CoroutineObject, gi_weakreflist), READONLY, 0}, +#endif {0, 0, 0, 0, 0} /* Sentinel */ }; @@ -346,6 +357,31 @@ static PyMethodDef __Pyx_async_gen_methods[] = { }; +#if CYTHON_USE_TYPE_SPECS +static PyType_Slot __pyx_AsyncGenType_slots[] = { + {Py_tp_dealloc, (void *)__Pyx_Coroutine_dealloc}, + {Py_am_aiter, (void *)PyObject_SelfIter}, + {Py_am_anext, (void *)__Pyx_async_gen_anext}, + {Py_tp_repr, (void *)__Pyx_async_gen_repr}, + {Py_tp_traverse, (void *)__Pyx_async_gen_traverse}, + {Py_tp_methods, (void *)__Pyx_async_gen_methods}, + {Py_tp_members, (void *)__Pyx_async_gen_memberlist}, + {Py_tp_getset, (void *)__Pyx_async_gen_getsetlist}, +#if CYTHON_USE_TP_FINALIZE + {Py_tp_finalize, (void *)__Pyx_Coroutine_del}, +#endif + {0, 0}, +}; + +static PyType_Spec __pyx_AsyncGenType_spec = { + __PYX_TYPE_MODULE_PREFIX "async_generator", + sizeof(__pyx_PyAsyncGenObject), + 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/ + __pyx_AsyncGenType_slots +}; +#else /* CYTHON_USE_TYPE_SPECS */ + #if CYTHON_USE_ASYNC_SLOTS static __Pyx_PyAsyncMethodsStruct __Pyx_async_gen_as_async = { 0, /* am_await */ @@ -363,7 +399,7 @@ static PyTypeObject __pyx_AsyncGenType_type = { sizeof(__pyx_PyAsyncGenObject), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)__Pyx_Coroutine_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ #if CYTHON_USE_ASYNC_SLOTS @@ -437,6 +473,7 @@ static PyTypeObject __pyx_AsyncGenType_type = { 0, /*tp_pypy_flags*/ #endif }; +#endif /* CYTHON_USE_TYPE_SPECS */ static int @@ -448,14 +485,14 @@ __Pyx_PyAsyncGen_ClearFreeLists(void) __pyx__PyAsyncGenWrappedValue *o; o = __Pyx_ag_value_freelist[--__Pyx_ag_value_freelist_free]; assert(__pyx__PyAsyncGenWrappedValue_CheckExact(o)); - PyObject_GC_Del(o); + __Pyx_PyHeapTypeObject_GC_Del(o); } while (__Pyx_ag_asend_freelist_free) { __pyx_PyAsyncGenASend *o; o = __Pyx_ag_asend_freelist[--__Pyx_ag_asend_freelist_free]; - assert(Py_TYPE(o) == __pyx__PyAsyncGenASendType); - PyObject_GC_Del(o); + assert(__Pyx_IS_TYPE(o, __pyx__PyAsyncGenASendType)); + __Pyx_PyHeapTypeObject_GC_Del(o); } return ret; @@ -480,6 +517,7 @@ __Pyx_async_gen_unwrap_value(__pyx_PyAsyncGenObject *gen, PyObject *result) gen->ag_closed = 1; } + gen->ag_running_async = 0; return NULL; } @@ -487,6 +525,7 @@ __Pyx_async_gen_unwrap_value(__pyx_PyAsyncGenObject *gen, PyObject *result) /* async yield */ __Pyx_ReturnWithStopIteration(((__pyx__PyAsyncGenWrappedValue*)result)->agw_val); Py_DECREF(result); + gen->ag_running_async = 0; return NULL; } @@ -503,11 +542,11 @@ __Pyx_async_gen_asend_dealloc(__pyx_PyAsyncGenASend *o) PyObject_GC_UnTrack((PyObject *)o); Py_CLEAR(o->ags_gen); Py_CLEAR(o->ags_sendval); - if (__Pyx_ag_asend_freelist_free < _PyAsyncGen_MAXFREELIST) { + if (likely(__Pyx_ag_asend_freelist_free < _PyAsyncGen_MAXFREELIST)) { assert(__pyx_PyAsyncGenASend_CheckExact(o)); __Pyx_ag_asend_freelist[__Pyx_ag_asend_freelist_free++] = o; } else { - PyObject_GC_Del(o); + __Pyx_PyHeapTypeObject_GC_Del(o); } } @@ -527,17 +566,25 @@ __Pyx_async_gen_asend_send(PyObject *g, PyObject *arg) PyObject *result; if (unlikely(o->ags_state == __PYX_AWAITABLE_STATE_CLOSED)) { - PyErr_SetNone(PyExc_StopIteration); + PyErr_SetString(PyExc_RuntimeError, __Pyx_ASYNC_GEN_CANNOT_REUSE_SEND_MSG); return NULL; } if (o->ags_state == __PYX_AWAITABLE_STATE_INIT) { + if (unlikely(o->ags_gen->ag_running_async)) { + PyErr_SetString( + PyExc_RuntimeError, + "anext(): asynchronous generator is already running"); + return NULL; + } + if (arg == NULL || arg == Py_None) { arg = o->ags_sendval ? o->ags_sendval : Py_None; } o->ags_state = __PYX_AWAITABLE_STATE_ITER; } + o->ags_gen->ag_running_async = 1; result = __Pyx_Coroutine_Send((PyObject*)o->ags_gen, arg); result = __Pyx_async_gen_unwrap_value(o->ags_gen, result); @@ -562,7 +609,7 @@ __Pyx_async_gen_asend_throw(__pyx_PyAsyncGenASend *o, PyObject *args) PyObject *result; if (unlikely(o->ags_state == __PYX_AWAITABLE_STATE_CLOSED)) { - PyErr_SetNone(PyExc_StopIteration); + PyErr_SetString(PyExc_RuntimeError, __Pyx_ASYNC_GEN_CANNOT_REUSE_SEND_MSG); return NULL; } @@ -578,9 +625,10 @@ __Pyx_async_gen_asend_throw(__pyx_PyAsyncGenASend *o, PyObject *args) static PyObject * -__Pyx_async_gen_asend_close(PyObject *g, CYTHON_UNUSED PyObject *args) +__Pyx_async_gen_asend_close(PyObject *g, PyObject *args) { __pyx_PyAsyncGenASend *o = (__pyx_PyAsyncGenASend*) g; + CYTHON_UNUSED_VAR(args); o->ags_state = __PYX_AWAITABLE_STATE_CLOSED; Py_RETURN_NONE; } @@ -595,6 +643,26 @@ static PyMethodDef __Pyx_async_gen_asend_methods[] = { }; +#if CYTHON_USE_TYPE_SPECS +static PyType_Slot __pyx__PyAsyncGenASendType_slots[] = { + {Py_tp_dealloc, (void *)__Pyx_async_gen_asend_dealloc}, + {Py_am_await, (void *)PyObject_SelfIter}, + {Py_tp_traverse, (void *)__Pyx_async_gen_asend_traverse}, + {Py_tp_methods, (void *)__Pyx_async_gen_asend_methods}, + {Py_tp_iter, (void *)PyObject_SelfIter}, + {Py_tp_iternext, (void *)__Pyx_async_gen_asend_iternext}, + {0, 0}, +}; + +static PyType_Spec __pyx__PyAsyncGenASendType_spec = { + __PYX_TYPE_MODULE_PREFIX "async_generator_asend", + sizeof(__pyx_PyAsyncGenASend), + 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /*tp_flags*/ + __pyx__PyAsyncGenASendType_slots +}; +#else /* CYTHON_USE_TYPE_SPECS */ + #if CYTHON_USE_ASYNC_SLOTS static __Pyx_PyAsyncMethodsStruct __Pyx_async_gen_asend_as_async = { PyObject_SelfIter, /* am_await */ @@ -606,7 +674,6 @@ static __Pyx_PyAsyncMethodsStruct __Pyx_async_gen_asend_as_async = { }; #endif - static PyTypeObject __pyx__PyAsyncGenASendType_type = { PyVarObject_HEAD_INIT(0, 0) "async_generator_asend", /* tp_name */ @@ -614,7 +681,7 @@ static PyTypeObject __pyx__PyAsyncGenASendType_type = { 0, /* tp_itemsize */ /* methods */ (destructor)__Pyx_async_gen_asend_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ #if CYTHON_USE_ASYNC_SLOTS @@ -681,19 +748,20 @@ static PyTypeObject __pyx__PyAsyncGenASendType_type = { 0, /*tp_pypy_flags*/ #endif }; +#endif /* CYTHON_USE_TYPE_SPECS */ static PyObject * __Pyx_async_gen_asend_new(__pyx_PyAsyncGenObject *gen, PyObject *sendval) { __pyx_PyAsyncGenASend *o; - if (__Pyx_ag_asend_freelist_free) { + if (likely(__Pyx_ag_asend_freelist_free)) { __Pyx_ag_asend_freelist_free--; o = __Pyx_ag_asend_freelist[__Pyx_ag_asend_freelist_free]; _Py_NewReference((PyObject *)o); } else { o = PyObject_GC_New(__pyx_PyAsyncGenASend, __pyx__PyAsyncGenASendType); - if (o == NULL) { + if (unlikely(o == NULL)) { return NULL; } } @@ -719,11 +787,11 @@ __Pyx_async_gen_wrapped_val_dealloc(__pyx__PyAsyncGenWrappedValue *o) { PyObject_GC_UnTrack((PyObject *)o); Py_CLEAR(o->agw_val); - if (__Pyx_ag_value_freelist_free < _PyAsyncGen_MAXFREELIST) { + if (likely(__Pyx_ag_value_freelist_free < _PyAsyncGen_MAXFREELIST)) { assert(__pyx__PyAsyncGenWrappedValue_CheckExact(o)); __Pyx_ag_value_freelist[__Pyx_ag_value_freelist_free++] = o; } else { - PyObject_GC_Del(o); + __Pyx_PyHeapTypeObject_GC_Del(o); } } @@ -737,6 +805,22 @@ __Pyx_async_gen_wrapped_val_traverse(__pyx__PyAsyncGenWrappedValue *o, } +#if CYTHON_USE_TYPE_SPECS +static PyType_Slot __pyx__PyAsyncGenWrappedValueType_slots[] = { + {Py_tp_dealloc, (void *)__Pyx_async_gen_wrapped_val_dealloc}, + {Py_tp_traverse, (void *)__Pyx_async_gen_wrapped_val_traverse}, + {0, 0}, +}; + +static PyType_Spec __pyx__PyAsyncGenWrappedValueType_spec = { + __PYX_TYPE_MODULE_PREFIX "async_generator_wrapped_value", + sizeof(__pyx__PyAsyncGenWrappedValue), + 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /*tp_flags*/ + __pyx__PyAsyncGenWrappedValueType_slots +}; +#else /* CYTHON_USE_TYPE_SPECS */ + static PyTypeObject __pyx__PyAsyncGenWrappedValueType_type = { PyVarObject_HEAD_INIT(0, 0) "async_generator_wrapped_value", /* tp_name */ @@ -744,7 +828,7 @@ static PyTypeObject __pyx__PyAsyncGenWrappedValueType_type = { 0, /* tp_itemsize */ /* methods */ (destructor)__Pyx_async_gen_wrapped_val_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_as_async */ @@ -802,6 +886,7 @@ static PyTypeObject __pyx__PyAsyncGenWrappedValueType_type = { 0, /*tp_pypy_flags*/ #endif }; +#endif /* CYTHON_USE_TYPE_SPECS */ static PyObject * @@ -811,7 +896,7 @@ __Pyx__PyAsyncGenValueWrapperNew(PyObject *val) __pyx__PyAsyncGenWrappedValue *o; assert(val); - if (__Pyx_ag_value_freelist_free) { + if (likely(__Pyx_ag_value_freelist_free)) { __Pyx_ag_value_freelist_free--; o = __Pyx_ag_value_freelist[__Pyx_ag_value_freelist_free]; assert(__pyx__PyAsyncGenWrappedValue_CheckExact(o)); @@ -839,7 +924,7 @@ __Pyx_async_gen_athrow_dealloc(__pyx_PyAsyncGenAThrow *o) PyObject_GC_UnTrack((PyObject *)o); Py_CLEAR(o->agt_gen); Py_CLEAR(o->agt_args); - PyObject_GC_Del(o); + __Pyx_PyHeapTypeObject_GC_Del(o); } @@ -856,34 +941,56 @@ static PyObject * __Pyx_async_gen_athrow_send(__pyx_PyAsyncGenAThrow *o, PyObject *arg) { __pyx_CoroutineObject *gen = (__pyx_CoroutineObject*)o->agt_gen; - PyObject *retval; + PyObject *retval, *exc_type; - if (o->agt_state == __PYX_AWAITABLE_STATE_CLOSED) { + if (unlikely(o->agt_state == __PYX_AWAITABLE_STATE_CLOSED)) { + PyErr_SetString(PyExc_RuntimeError, __Pyx_ASYNC_GEN_CANNOT_REUSE_CLOSE_MSG); + return NULL; + } + + if (unlikely(gen->resume_label == -1)) { + // already run past the end + o->agt_state = __PYX_AWAITABLE_STATE_CLOSED; PyErr_SetNone(PyExc_StopIteration); return NULL; } if (o->agt_state == __PYX_AWAITABLE_STATE_INIT) { - if (o->agt_gen->ag_closed) { - PyErr_SetNone(PyExc_StopIteration); + if (unlikely(o->agt_gen->ag_running_async)) { + o->agt_state = __PYX_AWAITABLE_STATE_CLOSED; + if (o->agt_args == NULL) { + PyErr_SetString( + PyExc_RuntimeError, + "aclose(): asynchronous generator is already running"); + } else { + PyErr_SetString( + PyExc_RuntimeError, + "athrow(): asynchronous generator is already running"); + } + return NULL; + } + + if (unlikely(o->agt_gen->ag_closed)) { + o->agt_state = __PYX_AWAITABLE_STATE_CLOSED; + PyErr_SetNone(__Pyx_PyExc_StopAsyncIteration); return NULL; } - if (arg != Py_None) { + if (unlikely(arg != Py_None)) { PyErr_SetString(PyExc_RuntimeError, __Pyx_NON_INIT_CORO_MSG); return NULL; } o->agt_state = __PYX_AWAITABLE_STATE_ITER; + o->agt_gen->ag_running_async = 1; if (o->agt_args == NULL) { /* aclose() mode */ o->agt_gen->ag_closed = 1; retval = __Pyx__Coroutine_Throw((PyObject*)gen, - /* Do not close generator when - PyExc_GeneratorExit is passed */ - PyExc_GeneratorExit, NULL, NULL, NULL, 0); + /* Do not close generator when PyExc_GeneratorExit is passed */ + PyExc_GeneratorExit, NULL, NULL, NULL, 0); if (retval && __pyx__PyAsyncGenWrappedValue_CheckExact(retval)) { Py_DECREF(retval); @@ -894,14 +1001,13 @@ __Pyx_async_gen_athrow_send(__pyx_PyAsyncGenAThrow *o, PyObject *arg) PyObject *tb = NULL; PyObject *val = NULL; - if (!PyArg_UnpackTuple(o->agt_args, "athrow", 1, 3, - &typ, &val, &tb)) { + if (unlikely(!PyArg_UnpackTuple(o->agt_args, "athrow", 1, 3, &typ, &val, &tb))) { return NULL; } retval = __Pyx__Coroutine_Throw((PyObject*)gen, - /* Do not close generator when PyExc_GeneratorExit is passed */ - typ, val, tb, o->agt_args, 0); + /* Do not close generator when PyExc_GeneratorExit is passed */ + typ, val, tb, o->agt_args, 0); retval = __Pyx_async_gen_unwrap_value(o->agt_gen, retval); } if (retval == NULL) { @@ -918,7 +1024,7 @@ __Pyx_async_gen_athrow_send(__pyx_PyAsyncGenAThrow *o, PyObject *arg) } else { /* aclose() mode */ if (retval) { - if (__pyx__PyAsyncGenWrappedValue_CheckExact(retval)) { + if (unlikely(__pyx__PyAsyncGenWrappedValue_CheckExact(retval))) { Py_DECREF(retval); goto yield_close; } @@ -932,26 +1038,26 @@ __Pyx_async_gen_athrow_send(__pyx_PyAsyncGenAThrow *o, PyObject *arg) } yield_close: + o->agt_gen->ag_running_async = 0; + o->agt_state = __PYX_AWAITABLE_STATE_CLOSED; PyErr_SetString( PyExc_RuntimeError, __Pyx_ASYNC_GEN_IGNORED_EXIT_MSG); return NULL; check_error: - if (PyErr_ExceptionMatches(__Pyx_PyExc_StopAsyncIteration)) { - o->agt_state = __PYX_AWAITABLE_STATE_CLOSED; + o->agt_gen->ag_running_async = 0; + o->agt_state = __PYX_AWAITABLE_STATE_CLOSED; + exc_type = PyErr_Occurred(); + if (__Pyx_PyErr_GivenExceptionMatches2(exc_type, __Pyx_PyExc_StopAsyncIteration, PyExc_GeneratorExit)) { if (o->agt_args == NULL) { // when aclose() is called we don't want to propagate - // StopAsyncIteration; just raise StopIteration, signalling - // that 'aclose()' is done. + // StopAsyncIteration or GeneratorExit; just raise + // StopIteration, signalling that this 'aclose()' await + // is done. PyErr_Clear(); PyErr_SetNone(PyExc_StopIteration); } } - else if (PyErr_ExceptionMatches(PyExc_GeneratorExit)) { - o->agt_state = __PYX_AWAITABLE_STATE_CLOSED; - PyErr_Clear(); /* ignore these errors */ - PyErr_SetNone(PyExc_StopIteration); - } return NULL; } @@ -961,13 +1067,8 @@ __Pyx_async_gen_athrow_throw(__pyx_PyAsyncGenAThrow *o, PyObject *args) { PyObject *retval; - if (o->agt_state == __PYX_AWAITABLE_STATE_INIT) { - PyErr_SetString(PyExc_RuntimeError, __Pyx_NON_INIT_CORO_MSG); - return NULL; - } - - if (o->agt_state == __PYX_AWAITABLE_STATE_CLOSED) { - PyErr_SetNone(PyExc_StopIteration); + if (unlikely(o->agt_state == __PYX_AWAITABLE_STATE_CLOSED)) { + PyErr_SetString(PyExc_RuntimeError, __Pyx_ASYNC_GEN_CANNOT_REUSE_CLOSE_MSG); return NULL; } @@ -975,12 +1076,24 @@ __Pyx_async_gen_athrow_throw(__pyx_PyAsyncGenAThrow *o, PyObject *args) if (o->agt_args) { return __Pyx_async_gen_unwrap_value(o->agt_gen, retval); } else { - /* aclose() mode */ - if (retval && __pyx__PyAsyncGenWrappedValue_CheckExact(retval)) { + // aclose() mode + PyObject *exc_type; + if (unlikely(retval && __pyx__PyAsyncGenWrappedValue_CheckExact(retval))) { + o->agt_gen->ag_running_async = 0; + o->agt_state = __PYX_AWAITABLE_STATE_CLOSED; Py_DECREF(retval); PyErr_SetString(PyExc_RuntimeError, __Pyx_ASYNC_GEN_IGNORED_EXIT_MSG); return NULL; } + exc_type = PyErr_Occurred(); + if (__Pyx_PyErr_GivenExceptionMatches2(exc_type, __Pyx_PyExc_StopAsyncIteration, PyExc_GeneratorExit)) { + // when aclose() is called we don't want to propagate + // StopAsyncIteration or GeneratorExit; just raise + // StopIteration, signalling that this 'aclose()' await + // is done. + PyErr_Clear(); + PyErr_SetNone(PyExc_StopIteration); + } return retval; } } @@ -994,9 +1107,10 @@ __Pyx_async_gen_athrow_iternext(__pyx_PyAsyncGenAThrow *o) static PyObject * -__Pyx_async_gen_athrow_close(PyObject *g, CYTHON_UNUSED PyObject *args) +__Pyx_async_gen_athrow_close(PyObject *g, PyObject *args) { __pyx_PyAsyncGenAThrow *o = (__pyx_PyAsyncGenAThrow*) g; + CYTHON_UNUSED_VAR(args); o->agt_state = __PYX_AWAITABLE_STATE_CLOSED; Py_RETURN_NONE; } @@ -1011,6 +1125,27 @@ static PyMethodDef __Pyx_async_gen_athrow_methods[] = { }; +#if CYTHON_USE_TYPE_SPECS +static PyType_Slot __pyx__PyAsyncGenAThrowType_slots[] = { + {Py_tp_dealloc, (void *)__Pyx_async_gen_athrow_dealloc}, + {Py_am_await, (void *)PyObject_SelfIter}, + {Py_tp_traverse, (void *)__Pyx_async_gen_athrow_traverse}, + {Py_tp_iter, (void *)PyObject_SelfIter}, + {Py_tp_iternext, (void *)__Pyx_async_gen_athrow_iternext}, + {Py_tp_methods, (void *)__Pyx_async_gen_athrow_methods}, + {Py_tp_getattro, (void *)__Pyx_PyObject_GenericGetAttrNoDict}, + {0, 0}, +}; + +static PyType_Spec __pyx__PyAsyncGenAThrowType_spec = { + __PYX_TYPE_MODULE_PREFIX "async_generator_athrow", + sizeof(__pyx_PyAsyncGenAThrow), + 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /*tp_flags*/ + __pyx__PyAsyncGenAThrowType_slots +}; +#else /* CYTHON_USE_TYPE_SPECS */ + #if CYTHON_USE_ASYNC_SLOTS static __Pyx_PyAsyncMethodsStruct __Pyx_async_gen_athrow_as_async = { PyObject_SelfIter, /* am_await */ @@ -1022,14 +1157,13 @@ static __Pyx_PyAsyncMethodsStruct __Pyx_async_gen_athrow_as_async = { }; #endif - static PyTypeObject __pyx__PyAsyncGenAThrowType_type = { PyVarObject_HEAD_INIT(0, 0) "async_generator_athrow", /* tp_name */ sizeof(__pyx_PyAsyncGenAThrow), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)__Pyx_async_gen_athrow_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ #if CYTHON_USE_ASYNC_SLOTS @@ -1096,6 +1230,7 @@ static PyTypeObject __pyx__PyAsyncGenAThrowType_type = { 0, /*tp_pypy_flags*/ #endif }; +#endif /* CYTHON_USE_TYPE_SPECS */ static PyObject * @@ -1103,7 +1238,7 @@ __Pyx_async_gen_athrow_new(__pyx_PyAsyncGenObject *gen, PyObject *args) { __pyx_PyAsyncGenAThrow *o; o = PyObject_GC_New(__pyx_PyAsyncGenAThrow, __pyx__PyAsyncGenAThrowType); - if (o == NULL) { + if (unlikely(o == NULL)) { return NULL; } o->agt_gen = gen; @@ -1118,26 +1253,42 @@ __Pyx_async_gen_athrow_new(__pyx_PyAsyncGenObject *gen, PyObject *args) /* ---------- global type sharing ------------ */ -static int __pyx_AsyncGen_init(void) { +static int __pyx_AsyncGen_init(PyObject *module) { +#if CYTHON_USE_TYPE_SPECS + __pyx_AsyncGenType = __Pyx_FetchCommonTypeFromSpec(module, &__pyx_AsyncGenType_spec, NULL); +#else + CYTHON_MAYBE_UNUSED_VAR(module); // on Windows, C-API functions can't be used in slots statically __pyx_AsyncGenType_type.tp_getattro = __Pyx_PyObject_GenericGetAttrNoDict; - __pyx__PyAsyncGenWrappedValueType_type.tp_getattro = __Pyx_PyObject_GenericGetAttrNoDict; - __pyx__PyAsyncGenAThrowType_type.tp_getattro = __Pyx_PyObject_GenericGetAttrNoDict; - __pyx__PyAsyncGenASendType_type.tp_getattro = __Pyx_PyObject_GenericGetAttrNoDict; - __pyx_AsyncGenType = __Pyx_FetchCommonType(&__pyx_AsyncGenType_type); +#endif if (unlikely(!__pyx_AsyncGenType)) return -1; +#if CYTHON_USE_TYPE_SPECS + __pyx__PyAsyncGenAThrowType = __Pyx_FetchCommonTypeFromSpec(module, &__pyx__PyAsyncGenAThrowType_spec, NULL); +#else + __pyx__PyAsyncGenAThrowType_type.tp_getattro = __Pyx_PyObject_GenericGetAttrNoDict; __pyx__PyAsyncGenAThrowType = __Pyx_FetchCommonType(&__pyx__PyAsyncGenAThrowType_type); +#endif if (unlikely(!__pyx__PyAsyncGenAThrowType)) return -1; +#if CYTHON_USE_TYPE_SPECS + __pyx__PyAsyncGenWrappedValueType = __Pyx_FetchCommonTypeFromSpec(module, &__pyx__PyAsyncGenWrappedValueType_spec, NULL); +#else + __pyx__PyAsyncGenWrappedValueType_type.tp_getattro = __Pyx_PyObject_GenericGetAttrNoDict; __pyx__PyAsyncGenWrappedValueType = __Pyx_FetchCommonType(&__pyx__PyAsyncGenWrappedValueType_type); +#endif if (unlikely(!__pyx__PyAsyncGenWrappedValueType)) return -1; +#if CYTHON_USE_TYPE_SPECS + __pyx__PyAsyncGenASendType = __Pyx_FetchCommonTypeFromSpec(module, &__pyx__PyAsyncGenASendType_spec, NULL); +#else + __pyx__PyAsyncGenASendType_type.tp_getattro = __Pyx_PyObject_GenericGetAttrNoDict; __pyx__PyAsyncGenASendType = __Pyx_FetchCommonType(&__pyx__PyAsyncGenASendType_type); +#endif if (unlikely(!__pyx__PyAsyncGenASendType)) return -1; |