summaryrefslogtreecommitdiff
path: root/Cython/Utility/AsyncGen.c
diff options
context:
space:
mode:
Diffstat (limited to 'Cython/Utility/AsyncGen.c')
-rw-r--r--Cython/Utility/AsyncGen.c293
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;