Coroutine.c 75.1 KB
Newer Older
1
//////////////////// GeneratorYieldFrom.proto ////////////////////
2

3
static CYTHON_INLINE PyObject* __Pyx_Generator_Yield_From(__pyx_CoroutineObject *gen, PyObject *source);
4

5
//////////////////// GeneratorYieldFrom ////////////////////
6 7
//@requires: Generator

8
static CYTHON_INLINE PyObject* __Pyx_Generator_Yield_From(__pyx_CoroutineObject *gen, PyObject *source) {
9
    PyObject *source_gen, *retval;
10 11 12 13 14 15 16 17 18
#ifdef __Pyx_Coroutine_USED
    if (__Pyx_Coroutine_CheckExact(source)) {
        // TODO: this should only happen for types.coroutine()ed generators, but we can't determine that here
        Py_INCREF(source);
        source_gen = source;
        retval = __Pyx_Generator_Next(source);
    } else
#endif
    {
19
#if CYTHON_USE_TYPE_SLOTS
20 21 22 23 24 25 26 27 28 29 30
        if (likely(Py_TYPE(source)->tp_iter)) {
            source_gen = Py_TYPE(source)->tp_iter(source);
            if (unlikely(!source_gen))
                return NULL;
            if (unlikely(!PyIter_Check(source_gen))) {
                PyErr_Format(PyExc_TypeError,
                             "iter() returned non-iterator of type '%.100s'",
                             Py_TYPE(source_gen)->tp_name);
                Py_DECREF(source_gen);
                return NULL;
            }
31
        } else
32 33 34 35
#endif
            source_gen = PyObject_GetIter(source);
        // source_gen is now the iterator, make the first next() call
        retval = Py_TYPE(source_gen)->tp_iternext(source_gen);
36
    }
37 38 39 40 41 42 43 44
    if (likely(retval)) {
        gen->yieldfrom = source_gen;
        return retval;
    }
    Py_DECREF(source_gen);
    return NULL;
}

45

46 47
//////////////////// CoroutineYieldFrom.proto ////////////////////

48
static CYTHON_INLINE PyObject* __Pyx_Coroutine_Yield_From(__pyx_CoroutineObject *gen, PyObject *source);
49 50 51 52 53

//////////////////// CoroutineYieldFrom ////////////////////
//@requires: Coroutine
//@requires: GetAwaitIter

54
static PyObject* __Pyx__Coroutine_Yield_From_Generic(__pyx_CoroutineObject *gen, PyObject *source) {
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
    PyObject *retval;
    PyObject *source_gen = __Pyx__Coroutine_GetAwaitableIter(source);
    if (unlikely(!source_gen)) {
        return NULL;
    }
    // source_gen is now the iterator, make the first next() call
    if (__Pyx_Coroutine_CheckExact(source_gen)) {
        retval = __Pyx_Generator_Next(source_gen);
    } else {
        retval = Py_TYPE(source_gen)->tp_iternext(source_gen);
    }
    if (retval) {
        gen->yieldfrom = source_gen;
        return retval;
    }
    Py_DECREF(source_gen);
    return NULL;
}

74
static CYTHON_INLINE PyObject* __Pyx_Coroutine_Yield_From(__pyx_CoroutineObject *gen, PyObject *source) {
75 76
    PyObject *retval;
    if (__Pyx_Coroutine_CheckExact(source)) {
77 78 79 80 81 82 83 84
        if (unlikely(((__pyx_CoroutineObject*)source)->yieldfrom)) {
            PyErr_SetString(
                PyExc_RuntimeError,
                "coroutine is being awaited already");
            retval = NULL;
        } else {
            retval = __Pyx_Generator_Next(source);
        }
85 86 87 88 89
        if (retval) {
            Py_INCREF(source);
            gen->yieldfrom = source;
            return retval;
        }
90 91 92
#ifdef __Pyx_AsyncGen_USED
    // inlined "__pyx_PyAsyncGenASend" handling to avoid the series of generic calls below
    } else if (__pyx_PyAsyncGenASend_CheckExact(source)) {
93
        retval = __Pyx_async_gen_asend_iternext(source);
94 95 96 97 98 99
        if (retval) {
            Py_INCREF(source);
            gen->yieldfrom = source;
            return retval;
        }
#endif
100
    } else {
101
        return __Pyx__Coroutine_Yield_From_Generic(gen, source);
102 103
    }
    return NULL;
104 105 106
}


107 108 109 110 111 112 113 114 115 116 117 118 119
//////////////////// GetAwaitIter.proto ////////////////////

static CYTHON_INLINE PyObject *__Pyx_Coroutine_GetAwaitableIter(PyObject *o); /*proto*/
static PyObject *__Pyx__Coroutine_GetAwaitableIter(PyObject *o); /*proto*/

//////////////////// GetAwaitIter ////////////////////
//@requires: ObjectHandling.c::PyObjectGetAttrStr
//@requires: ObjectHandling.c::PyObjectCallNoArg
//@requires: ObjectHandling.c::PyObjectCallOneArg

static CYTHON_INLINE PyObject *__Pyx_Coroutine_GetAwaitableIter(PyObject *o) {
#ifdef __Pyx_Coroutine_USED
    if (__Pyx_Coroutine_CheckExact(o)) {
120
        return __Pyx_NewRef(o);
121 122 123 124 125
    }
#endif
    return __Pyx__Coroutine_GetAwaitableIter(o);
}

126

Stefan Behnel's avatar
Stefan Behnel committed
127
static void __Pyx_Coroutine_AwaitableIterError(PyObject *source) {
128
#if PY_VERSION_HEX >= 0x030600B3 || defined(_PyErr_FormatFromCause)
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
    _PyErr_FormatFromCause(
        PyExc_TypeError,
        "'async for' received an invalid object "
        "from __anext__: %.100s",
        Py_TYPE(source)->tp_name);
#elif PY_MAJOR_VERSION >= 3
    PyObject *exc, *val, *val2, *tb;
    assert(PyErr_Occurred());
    PyErr_Fetch(&exc, &val, &tb);
    PyErr_NormalizeException(&exc, &val, &tb);
    if (tb != NULL) {
        PyException_SetTraceback(val, tb);
        Py_DECREF(tb);
    }
    Py_DECREF(exc);
    assert(!PyErr_Occurred());
    PyErr_Format(
        PyExc_TypeError,
        "'async for' received an invalid object "
        "from __anext__: %.100s",
        Py_TYPE(source)->tp_name);

    PyErr_Fetch(&exc, &val2, &tb);
    PyErr_NormalizeException(&exc, &val2, &tb);
    Py_INCREF(val);
    PyException_SetCause(val2, val);
    PyException_SetContext(val2, val);
    PyErr_Restore(exc, val2, tb);
#else
    // since Py2 does not have exception chaining, it's better to avoid shadowing exceptions there
    source++;
#endif
}

163 164
// adapted from genobject.c in Py3.5
static PyObject *__Pyx__Coroutine_GetAwaitableIter(PyObject *obj) {
165
    PyObject *res;
166
#if CYTHON_USE_ASYNC_SLOTS
167
    __Pyx_PyAsyncMethodsStruct* am = __Pyx_PyType_AsAsync(obj);
168 169
    if (likely(am && am->am_await)) {
        res = (*am->am_await)(obj);
170
    } else
171
#endif
172
#if PY_VERSION_HEX >= 0x030500B2 || defined(PyCoro_CheckExact)
173
    if (PyCoro_CheckExact(obj)) {
Stefan Behnel's avatar
Stefan Behnel committed
174
        return __Pyx_NewRef(obj);
175 176 177 178 179
    } else
#endif
#if CYTHON_COMPILING_IN_CPYTHON && defined(CO_ITERABLE_COROUTINE)
    if (PyGen_CheckExact(obj) && ((PyGenObject*)obj)->gi_code && ((PyCodeObject *)((PyGenObject*)obj)->gi_code)->co_flags & CO_ITERABLE_COROUTINE) {
        // Python generator marked with "@types.coroutine" decorator
Stefan Behnel's avatar
Stefan Behnel committed
180
        return __Pyx_NewRef(obj);
181
    } else
182 183 184 185
#endif
    {
        PyObject *method = __Pyx_PyObject_GetAttrStr(obj, PYIDENT("__await__"));
        if (unlikely(!method)) goto slot_error;
186
        #if CYTHON_UNPACK_METHODS
187 188 189 190 191 192 193
        if (likely(PyMethod_Check(method))) {
            PyObject *self = PyMethod_GET_SELF(method);
            if (likely(self)) {
                PyObject *function = PyMethod_GET_FUNCTION(method);
                res = __Pyx_PyObject_CallOneArg(function, self);
            } else
                res = __Pyx_PyObject_CallNoArg(method);
194
        } else
195
        #endif
196
            res = __Pyx_PyObject_CallNoArg(method);
197 198
        Py_DECREF(method);
    }
199 200
    if (unlikely(!res)) {
        // surprisingly, CPython replaces the exception here...
Stefan Behnel's avatar
Stefan Behnel committed
201
        __Pyx_Coroutine_AwaitableIterError(obj);
202 203
        goto bad;
    }
Stefan Behnel's avatar
Stefan Behnel committed
204
    if (unlikely(!PyIter_Check(res))) {
205 206 207 208 209 210 211 212 213
        PyErr_Format(PyExc_TypeError,
                     "__await__() returned non-iterator of type '%.100s'",
                     Py_TYPE(res)->tp_name);
        Py_CLEAR(res);
    } else {
        int is_coroutine = 0;
        #ifdef __Pyx_Coroutine_USED
        is_coroutine |= __Pyx_Coroutine_CheckExact(res);
        #endif
214
        #if PY_VERSION_HEX >= 0x030500B2 || defined(PyCoro_CheckExact)
215
        is_coroutine |= PyCoro_CheckExact(res);
216 217 218 219 220 221 222 223 224 225 226 227 228
        #endif
        if (unlikely(is_coroutine)) {
            /* __await__ must return an *iterator*, not
               a coroutine or another awaitable (see PEP 492) */
            PyErr_SetString(PyExc_TypeError,
                            "__await__() returned a coroutine");
            Py_CLEAR(res);
        }
    }
    return res;
slot_error:
    PyErr_Format(PyExc_TypeError,
                 "object %.100s can't be used in 'await' expression",
229
                 Py_TYPE(obj)->tp_name);
230 231 232 233 234
bad:
    return NULL;
}


235 236 237 238 239 240 241 242 243
//////////////////// AsyncIter.proto ////////////////////

static CYTHON_INLINE PyObject *__Pyx_Coroutine_GetAsyncIter(PyObject *o); /*proto*/
static CYTHON_INLINE PyObject *__Pyx_Coroutine_AsyncIterNext(PyObject *o); /*proto*/

//////////////////// AsyncIter ////////////////////
//@requires: GetAwaitIter
//@requires: ObjectHandling.c::PyObjectCallMethod0

Stefan Behnel's avatar
Stefan Behnel committed
244
static PyObject *__Pyx_Coroutine_GetAsyncIter_Generic(PyObject *obj) {
245 246 247 248 249 250
#if PY_VERSION_HEX < 0x030500B1
    {
        PyObject *iter = __Pyx_PyObject_CallMethod0(obj, PYIDENT("__aiter__"));
        if (likely(iter))
            return iter;
        // FIXME: for the sake of a nicely conforming exception message, assume any AttributeError meant '__aiter__'
251
        if (!PyErr_ExceptionMatches(PyExc_AttributeError))
252 253
            return NULL;
    }
254
#else
255
    // avoid C warning about 'unused function'
256
    if ((0)) (void) __Pyx_PyObject_CallMethod0(obj, PYIDENT("__aiter__"));
257 258 259 260 261 262 263
#endif

    PyErr_Format(PyExc_TypeError, "'async for' requires an object with __aiter__ method, got %.100s",
                 Py_TYPE(obj)->tp_name);
    return NULL;
}

264

Stefan Behnel's avatar
Stefan Behnel committed
265
static CYTHON_INLINE PyObject *__Pyx_Coroutine_GetAsyncIter(PyObject *obj) {
266 267
#ifdef __Pyx_AsyncGen_USED
    if (__Pyx_AsyncGen_CheckExact(obj)) {
Stefan Behnel's avatar
Stefan Behnel committed
268
        return __Pyx_NewRef(obj);
269 270
    }
#endif
271
#if CYTHON_USE_ASYNC_SLOTS
272 273
    {
        __Pyx_PyAsyncMethodsStruct* am = __Pyx_PyType_AsAsync(obj);
Stefan Behnel's avatar
Stefan Behnel committed
274 275
        if (likely(am && am->am_aiter)) {
            return (*am->am_aiter)(obj);
276
        }
277 278
    }
#endif
Stefan Behnel's avatar
Stefan Behnel committed
279 280 281 282 283
    return __Pyx_Coroutine_GetAsyncIter_Generic(obj);
}


static PyObject *__Pyx__Coroutine_AsyncIterNext(PyObject *obj) {
284 285 286 287 288 289
#if PY_VERSION_HEX < 0x030500B1
    {
        PyObject *value = __Pyx_PyObject_CallMethod0(obj, PYIDENT("__anext__"));
        if (likely(value))
            return value;
    }
290
    // FIXME: for the sake of a nicely conforming exception message, assume any AttributeError meant '__anext__'
291
    if (PyErr_ExceptionMatches(PyExc_AttributeError))
292 293 294 295 296 297 298
#endif
        PyErr_Format(PyExc_TypeError, "'async for' requires an object with __anext__ method, got %.100s",
                     Py_TYPE(obj)->tp_name);
    return NULL;
}


Stefan Behnel's avatar
Stefan Behnel committed
299 300 301
static CYTHON_INLINE PyObject *__Pyx_Coroutine_AsyncIterNext(PyObject *obj) {
#ifdef __Pyx_AsyncGen_USED
    if (__Pyx_AsyncGen_CheckExact(obj)) {
302
        return __Pyx_async_gen_anext(obj);
Stefan Behnel's avatar
Stefan Behnel committed
303 304 305 306 307 308 309 310 311 312 313 314 315 316
    }
#endif
#if CYTHON_USE_ASYNC_SLOTS
    {
        __Pyx_PyAsyncMethodsStruct* am = __Pyx_PyType_AsAsync(obj);
        if (likely(am && am->am_anext)) {
            return (*am->am_anext)(obj);
        }
    }
#endif
    return __Pyx__Coroutine_AsyncIterNext(obj);
}


317 318
//////////////////// pep479.proto ////////////////////

319
static void __Pyx_Generator_Replace_StopIteration(int in_async_gen); /*proto*/
320 321 322 323

//////////////////// pep479 ////////////////////
//@requires: Exceptions.c::GetException

324 325
static void __Pyx_Generator_Replace_StopIteration(CYTHON_UNUSED int in_async_gen) {
    PyObject *exc, *val, *tb, *cur_exc;
326
    __Pyx_PyThreadState_declare
327 328 329 330 331
    #ifdef __Pyx_StopAsyncIteration_USED
    int is_async_stopiteration = 0;
    #endif

    cur_exc = PyErr_Occurred();
332
    if (likely(!__Pyx_PyErr_GivenExceptionMatches(cur_exc, PyExc_StopIteration))) {
333
        #ifdef __Pyx_StopAsyncIteration_USED
334
        if (in_async_gen && unlikely(__Pyx_PyErr_GivenExceptionMatches(cur_exc, __Pyx_PyExc_StopAsyncIteration))) {
335 336 337 338 339 340
            is_async_stopiteration = 1;
        } else
        #endif
            return;
    }

341
    __Pyx_PyThreadState_assign
342 343
    // Chain exceptions by moving Stop(Async)Iteration to exc_info before creating the RuntimeError.
    // In Py2.x, no chaining happens, but the exception still stays visible in exc_info.
344 345 346 347
    __Pyx_GetException(&exc, &val, &tb);
    Py_XDECREF(exc);
    Py_XDECREF(val);
    Py_XDECREF(tb);
348 349 350 351 352 353
    PyErr_SetString(PyExc_RuntimeError,
        #ifdef __Pyx_StopAsyncIteration_USED
        is_async_stopiteration ? "async generator raised StopAsyncIteration" :
        in_async_gen ? "async generator raised StopIteration" :
        #endif
        "generator raised StopIteration");
354 355 356
}


357
//////////////////// CoroutineBase.proto ////////////////////
358
//@substitute: naming
359

360
typedef PyObject *(*__pyx_coroutine_body_t)(PyObject *, PyThreadState *, PyObject *);
361 362 363

typedef struct {
    PyObject_HEAD
364
    __pyx_coroutine_body_t body;
365 366 367 368 369 370
    PyObject *closure;
    PyObject *exc_type;
    PyObject *exc_value;
    PyObject *exc_traceback;
    PyObject *gi_weakreflist;
    PyObject *classobj;
371
    PyObject *yieldfrom;
372 373
    PyObject *gi_name;
    PyObject *gi_qualname;
374
    PyObject *gi_modulename;
375
    int resume_label;
376 377
    // using T_BOOL for property below requires char value
    char is_running;
378
} __pyx_CoroutineObject;
379

380 381 382
static __pyx_CoroutineObject *__Pyx__Coroutine_New(
    PyTypeObject *type, __pyx_coroutine_body_t body, PyObject *closure,
    PyObject *name, PyObject *qualname, PyObject *module_name); /*proto*/
383 384 385 386 387

static __pyx_CoroutineObject *__Pyx__Coroutine_NewInit(
            __pyx_CoroutineObject *gen, __pyx_coroutine_body_t body, PyObject *closure,
            PyObject *name, PyObject *qualname, PyObject *module_name); /*proto*/

388
static int __Pyx_Coroutine_clear(PyObject *self); /*proto*/
389 390 391
static PyObject *__Pyx_Coroutine_Send(PyObject *self, PyObject *value); /*proto*/
static PyObject *__Pyx_Coroutine_Close(PyObject *self); /*proto*/
static PyObject *__Pyx_Coroutine_Throw(PyObject *gen, PyObject *args); /*proto*/
392

393 394 395 396 397 398 399 400 401 402 403
// macros for exception state swapping instead of inline functions to make use of the local thread state context
#define __Pyx_Coroutine_SwapException(self) { \
    __Pyx_ExceptionSwap(&(self)->exc_type, &(self)->exc_value, &(self)->exc_traceback); \
    __Pyx_Coroutine_ResetFrameBackpointer(self); \
    }
#define __Pyx_Coroutine_ResetAndClearException(self) { \
    __Pyx_ExceptionReset((self)->exc_type, (self)->exc_value, (self)->exc_traceback); \
    __Pyx_Coroutine_ResetFrameBackpointer(self); \
    (self)->exc_type = (self)->exc_value = (self)->exc_traceback = NULL; \
    }

404 405 406
#if CYTHON_FAST_THREAD_STATE
#define __Pyx_PyGen_FetchStopIterationValue(pvalue) \
    __Pyx_PyGen__FetchStopIterationValue($local_tstate_cname, pvalue)
407 408
#define __Pyx_Coroutine_ResetFrameBackpointer(self) \
    __Pyx__Coroutine_ResetFrameBackpointer($local_tstate_cname, self)
409
#else
410 411
#define __Pyx_PyGen_FetchStopIterationValue(pvalue) \
    __Pyx_PyGen__FetchStopIterationValue(__Pyx_PyThreadState_Current, pvalue)
412 413
#define __Pyx_Coroutine_ResetFrameBackpointer(self) \
    __Pyx__Coroutine_ResetFrameBackpointer(__Pyx_PyThreadState_Current, self)
414
#endif
415
static int __Pyx_PyGen__FetchStopIterationValue(PyThreadState *tstate, PyObject **pvalue); /*proto*/
416 417
static CYTHON_INLINE void __Pyx__Coroutine_ResetFrameBackpointer(PyThreadState *tstate, __pyx_CoroutineObject *self);

418 419 420 421 422

//////////////////// Coroutine.proto ////////////////////

#define __Pyx_Coroutine_USED
static PyTypeObject *__pyx_CoroutineType = 0;
423
static PyTypeObject *__pyx_CoroutineAwaitType = 0;
424
#define __Pyx_Coroutine_CheckExact(obj) (Py_TYPE(obj) == __pyx_CoroutineType)
425
#define __Pyx_CoroutineAwait_CheckExact(obj) (Py_TYPE(obj) == __pyx_CoroutineAwaitType)
426

427 428
#define __Pyx_Coroutine_New(body, closure, name, qualname, module_name)  \
    __Pyx__Coroutine_New(__pyx_CoroutineType, body, closure, name, qualname, module_name)
429

Stefan Behnel's avatar
Stefan Behnel committed
430
static int __pyx_Coroutine_init(void); /*proto*/
431
static PyObject *__Pyx__Coroutine_await(PyObject *coroutine); /*proto*/
432

433 434 435 436 437 438 439 440
typedef struct {
    PyObject_HEAD
    PyObject *coroutine;
} __pyx_CoroutineAwaitObject;

static PyObject *__Pyx_CoroutineAwait_Close(__pyx_CoroutineAwaitObject *self); /*proto*/
static PyObject *__Pyx_CoroutineAwait_Throw(__pyx_CoroutineAwaitObject *self, PyObject *args); /*proto*/

441 442 443 444 445 446 447

//////////////////// Generator.proto ////////////////////

#define __Pyx_Generator_USED
static PyTypeObject *__pyx_GeneratorType = 0;
#define __Pyx_Generator_CheckExact(obj) (Py_TYPE(obj) == __pyx_GeneratorType)

448 449
#define __Pyx_Generator_New(body, closure, name, qualname, module_name)  \
    __Pyx__Coroutine_New(__pyx_GeneratorType, body, closure, name, qualname, module_name)
450

451
static PyObject *__Pyx_Generator_Next(PyObject *self);
Stefan Behnel's avatar
Stefan Behnel committed
452
static int __pyx_Generator_init(void); /*proto*/
453 454


455 456 457 458 459
//////////////////// AsyncGen ////////////////////
//@requires: AsyncGen.c::AsyncGenerator
// -> empty, only delegates to separate file


460
//////////////////// CoroutineBase ////////////////////
461
//@substitute: naming
462
//@requires: Exceptions.c::PyErrFetchRestore
463
//@requires: Exceptions.c::PyThreadStateGet
464 465
//@requires: Exceptions.c::SwapException
//@requires: Exceptions.c::RaiseException
466
//@requires: Exceptions.c::SaveResetException
467
//@requires: ObjectHandling.c::PyObjectCallMethod1
468
//@requires: ObjectHandling.c::PyObjectGetAttrStr
469
//@requires: CommonStructures.c::FetchCommonType
470

471 472
#include <structmember.h>
#include <frameobject.h>
473

474
#define __Pyx_Coroutine_Undelegate(gen) Py_CLEAR((gen)->yieldfrom)
475 476 477 478 479 480 481

//   If StopIteration exception is set, fetches its 'value'
//   attribute if any, otherwise sets pvalue to None.
//
//   Returns 0 if no exception or StopIteration is set.
//   If any other exception is set, returns -1 and leaves
//   pvalue unchanged.
482
static int __Pyx_PyGen__FetchStopIterationValue(CYTHON_UNUSED PyThreadState *$local_tstate_cname, PyObject **pvalue) {
483 484 485 486 487 488 489 490 491 492 493 494 495 496 497
    PyObject *et, *ev, *tb;
    PyObject *value = NULL;

    __Pyx_ErrFetch(&et, &ev, &tb);

    if (!et) {
        Py_XDECREF(tb);
        Py_XDECREF(ev);
        Py_INCREF(Py_None);
        *pvalue = Py_None;
        return 0;
    }

    // most common case: plain StopIteration without or with separate argument
    if (likely(et == PyExc_StopIteration)) {
498 499 500 501
        if (!ev) {
            Py_INCREF(Py_None);
            value = Py_None;
        }
502
#if PY_VERSION_HEX >= 0x030300A0
503
        else if (Py_TYPE(ev) == (PyTypeObject*)PyExc_StopIteration) {
504 505 506 507 508
            value = ((PyStopIterationObject *)ev)->value;
            Py_INCREF(value);
            Py_DECREF(ev);
        }
#endif
509 510 511 512
        // PyErr_SetObject() and friends put the value directly into ev
        else if (unlikely(PyTuple_Check(ev))) {
            // if it's a tuple, it is interpreted as separate constructor arguments (surprise!)
            if (PyTuple_GET_SIZE(ev) >= 1) {
513
#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
514 515
                value = PyTuple_GET_ITEM(ev, 0);
                Py_INCREF(value);
516 517
#else
                value = PySequence_ITEM(ev, 0);
518
#endif
519 520 521
            } else {
                Py_INCREF(Py_None);
                value = Py_None;
522
            }
523 524
            Py_DECREF(ev);
        }
525
        else if (!__Pyx_TypeCheck(ev, (PyTypeObject*)PyExc_StopIteration)) {
526 527 528 529
            // 'steal' reference to ev
            value = ev;
        }
        if (likely(value)) {
530 531
            Py_XDECREF(tb);
            Py_DECREF(et);
532
            *pvalue = value;
533 534
            return 0;
        }
535
    } else if (!__Pyx_PyErr_GivenExceptionMatches(et, PyExc_StopIteration)) {
536 537
        __Pyx_ErrRestore(et, ev, tb);
        return -1;
538
    }
539

540 541
    // otherwise: normalise and check what that gives us
    PyErr_NormalizeException(&et, &ev, &tb);
542
    if (unlikely(!PyObject_TypeCheck(ev, (PyTypeObject*)PyExc_StopIteration))) {
543 544 545 546 547 548 549 550 551 552 553 554
        // looks like normalisation failed - raise the new exception
        __Pyx_ErrRestore(et, ev, tb);
        return -1;
    }
    Py_XDECREF(tb);
    Py_DECREF(et);
#if PY_VERSION_HEX >= 0x030300A0
    value = ((PyStopIterationObject *)ev)->value;
    Py_INCREF(value);
    Py_DECREF(ev);
#else
    {
555
        PyObject* args = __Pyx_PyObject_GetAttrStr(ev, PYIDENT("args"));
556 557
        Py_DECREF(ev);
        if (likely(args)) {
558
            value = PySequence_GetItem(args, 0);
559 560 561 562 563 564 565 566 567 568 569 570 571
            Py_DECREF(args);
        }
        if (unlikely(!value)) {
            __Pyx_ErrRestore(NULL, NULL, NULL);
            Py_INCREF(Py_None);
            value = Py_None;
        }
    }
#endif
    *pvalue = value;
    return 0;
}

572
static CYTHON_INLINE
573
void __Pyx_Coroutine_ExceptionClear(__pyx_CoroutineObject *self) {
574 575 576
    PyObject *exc_type = self->exc_type;
    PyObject *exc_value = self->exc_value;
    PyObject *exc_traceback = self->exc_traceback;
577 578 579 580

    self->exc_type = NULL;
    self->exc_value = NULL;
    self->exc_traceback = NULL;
581 582 583 584

    Py_XDECREF(exc_type);
    Py_XDECREF(exc_value);
    Py_XDECREF(exc_traceback);
585 586
}

Stefan Behnel's avatar
Stefan Behnel committed
587
#define __Pyx_Coroutine_AlreadyRunningError(gen)  (__Pyx__Coroutine_AlreadyRunningError(gen), (PyObject*)NULL)
588
static void __Pyx__Coroutine_AlreadyRunningError(CYTHON_UNUSED __pyx_CoroutineObject *gen) {
Stefan Behnel's avatar
Stefan Behnel committed
589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605
    const char *msg;
    if (0) {
    #ifdef __Pyx_Coroutine_USED
    } else if (__Pyx_Coroutine_CheckExact((PyObject*)gen)) {
        msg = "coroutine already executing";
    #endif
    #ifdef __Pyx_AsyncGen_USED
    } else if (__Pyx_AsyncGen_CheckExact((PyObject*)gen)) {
        msg = "async generator already executing";
    #endif
    } else {
        msg = "generator already executing";
    }
    PyErr_SetString(PyExc_ValueError, msg);
}

#define __Pyx_Coroutine_NotStartedError(gen)  (__Pyx__Coroutine_NotStartedError(gen), (PyObject*)NULL)
Stefan Behnel's avatar
Stefan Behnel committed
606
static void __Pyx__Coroutine_NotStartedError(CYTHON_UNUSED PyObject *gen) {
Stefan Behnel's avatar
Stefan Behnel committed
607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623
    const char *msg;
    if (0) {
    #ifdef __Pyx_Coroutine_USED
    } else if (__Pyx_Coroutine_CheckExact(gen)) {
        msg = "can't send non-None value to a just-started coroutine";
    #endif
    #ifdef __Pyx_AsyncGen_USED
    } else if (__Pyx_AsyncGen_CheckExact(gen)) {
        msg = "can't send non-None value to a just-started async generator";
    #endif
    } else {
        msg = "can't send non-None value to a just-started generator";
    }
    PyErr_SetString(PyExc_TypeError, msg);
}

#define __Pyx_Coroutine_AlreadyTerminatedError(gen, value, closing)  (__Pyx__Coroutine_AlreadyTerminatedError(gen, value, closing), (PyObject*)NULL)
Stefan Behnel's avatar
Stefan Behnel committed
624
static void __Pyx__Coroutine_AlreadyTerminatedError(CYTHON_UNUSED PyObject *gen, PyObject *value, CYTHON_UNUSED int closing) {
Stefan Behnel's avatar
Stefan Behnel committed
625 626 627 628 629 630 631 632 633 634 635
    #ifdef __Pyx_Coroutine_USED
    if (!closing && __Pyx_Coroutine_CheckExact(gen)) {
        // `self` is an exhausted coroutine: raise an error,
        // except when called from gen_close(), which should
        // always be a silent method.
        PyErr_SetString(PyExc_RuntimeError, "cannot reuse already awaited coroutine");
    } else
    #endif
    if (value) {
        // `gen` is an exhausted generator:
        // only set exception if called from send().
636
        #ifdef __Pyx_AsyncGen_USED
Stefan Behnel's avatar
Stefan Behnel committed
637 638 639
        if (__Pyx_AsyncGen_CheckExact(gen))
            PyErr_SetNone(__Pyx_PyExc_StopAsyncIteration);
        else
640
        #endif
Stefan Behnel's avatar
Stefan Behnel committed
641
        PyErr_SetNone(PyExc_StopIteration);
642
    }
643 644
}

Stefan Behnel's avatar
Stefan Behnel committed
645 646
static
PyObject *__Pyx_Coroutine_SendEx(__pyx_CoroutineObject *self, PyObject *value, int closing) {
647
    __Pyx_PyThreadState_declare
648
    PyThreadState *tstate;
649
    PyObject *retval;
650 651

    assert(!self->is_running);
652

653 654
    if (unlikely(self->resume_label == 0)) {
        if (unlikely(value && value != Py_None)) {
Stefan Behnel's avatar
Stefan Behnel committed
655
            return __Pyx_Coroutine_NotStartedError((PyObject*)self);
656 657 658
        }
    }

659
    if (unlikely(self->resume_label == -1)) {
Stefan Behnel's avatar
Stefan Behnel committed
660
        return __Pyx_Coroutine_AlreadyTerminatedError((PyObject*)self, value, closing);
661 662
    }

663
#if CYTHON_FAST_THREAD_STATE
664
    __Pyx_PyThreadState_assign
665 666 667 668 669
    tstate = $local_tstate_cname;
#else
    tstate = __Pyx_PyThreadState_Current;
#endif

670
    if (self->exc_type && self->exc_type != Py_None) {
Boxiang Sun's avatar
Boxiang Sun committed
671
#if CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_PYSTON
672 673
        // FIXME: what to do in PyPy?
#else
674 675
        // Generators always return to their most recent caller, not
        // necessarily their creator.
676 677 678 679
        if (self->exc_traceback) {
            PyTracebackObject *tb = (PyTracebackObject *) self->exc_traceback;
            PyFrameObject *f = tb->tb_frame;

680
            Py_XINCREF(tstate->frame);
681
            assert(f->f_back == NULL);
682
            f->f_back = tstate->frame;
683
        }
684
#endif
685 686
        // We were in an except handler when we left,
        // restore the exception state which was put aside.
687 688
        __Pyx_ExceptionSwap(&self->exc_type, &self->exc_value,
                            &self->exc_traceback);
689
        // self->exc_* now holds the exception state of the caller
690
    } else {
691
        // save away the exception state of the caller
692
        __Pyx_Coroutine_ExceptionClear(self);
693
        __Pyx_ExceptionSave(&self->exc_type, &self->exc_value, &self->exc_traceback);
694
    }
695 696

    self->is_running = 1;
697
    retval = self->body((PyObject *) self, tstate, value);
698 699
    self->is_running = 0;

700 701 702
    return retval;
}

703
static CYTHON_INLINE void __Pyx__Coroutine_ResetFrameBackpointer(PyThreadState *tstate, __pyx_CoroutineObject *self) {
704 705 706
    // Don't keep the reference to f_back any longer than necessary.  It
    // may keep a chain of frames alive or it could create a reference
    // cycle.
707
    if (self->exc_traceback) {
708 709 710
#if CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_PYSTON
    // FIXME: what to do in PyPy?
#else
711 712
        PyTracebackObject *tb = (PyTracebackObject *) self->exc_traceback;
        PyFrameObject *f = tb->tb_frame;
713 714 715 716
        // do not accidentally break any other frame links
        // FIXME: any other cases? e.g. do we need to follow up the back link chain?
        if (f->f_back == tstate->frame)
            Py_CLEAR(f->f_back);
717
#endif
718
    }
719 720
}

721
static CYTHON_INLINE
722
PyObject *__Pyx_Coroutine_MethodReturn(CYTHON_UNUSED PyObject* gen, PyObject *retval) {
723 724
    if (unlikely(!retval && !PyErr_Occurred())) {
        // method call must not terminate with NULL without setting an exception
725 726 727 728 729
        #ifdef __Pyx_AsyncGen_USED
        if (__Pyx_AsyncGen_CheckExact(gen)) {
            PyErr_SetNone(__Pyx_PyExc_StopAsyncIteration);
        } else
        #endif
730 731 732 733 734
        PyErr_SetNone(PyExc_StopIteration);
    }
    return retval;
}

735
static CYTHON_INLINE
736
PyObject *__Pyx_Coroutine_FinishDelegation(__pyx_CoroutineObject *gen) {
737 738
    PyObject *ret;
    PyObject *val = NULL;
739
    __Pyx_Coroutine_Undelegate(gen);
740
    __Pyx_PyGen__FetchStopIterationValue(__Pyx_PyThreadState_Current, &val);
741
    // val == NULL on failure => pass on exception
742
    ret = __Pyx_Coroutine_SendEx(gen, val, 0);
743 744
    Py_XDECREF(val);
    return ret;
745 746
}

747
static PyObject *__Pyx_Coroutine_Send(PyObject *self, PyObject *value) {
748
    PyObject *retval;
749
    __pyx_CoroutineObject *gen = (__pyx_CoroutineObject*) self;
750
    PyObject *yf = gen->yieldfrom;
Stefan Behnel's avatar
Stefan Behnel committed
751 752
    if (unlikely(gen->is_running))
        return __Pyx_Coroutine_AlreadyRunningError(gen);
753 754 755 756 757
    if (yf) {
        PyObject *ret;
        // FIXME: does this really need an INCREF() ?
        //Py_INCREF(yf);
        gen->is_running = 1;
758
        #ifdef __Pyx_Generator_USED
759
        if (__Pyx_Generator_CheckExact(yf)) {
760 761 762 763 764 765 766 767
            ret = __Pyx_Coroutine_Send(yf, value);
        } else
        #endif
        #ifdef __Pyx_Coroutine_USED
        if (__Pyx_Coroutine_CheckExact(yf)) {
            ret = __Pyx_Coroutine_Send(yf, value);
        } else
        #endif
768 769
        #ifdef __Pyx_AsyncGen_USED
        if (__pyx_PyAsyncGenASend_CheckExact(yf)) {
770
            ret = __Pyx_async_gen_asend_send(yf, value);
771 772
        } else
        #endif
773 774 775 776 777
        #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x03030000
        if (PyGen_CheckExact(yf)) {
            ret = _PyGen_Send((PyGenObject*)yf, value == Py_None ? NULL : value);
        } else
        #endif
778 779 780 781 782
        #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x03050000 && defined(PyCoro_CheckExact)
        if (PyCoro_CheckExact(yf)) {
            ret = _PyGen_Send((PyGenObject*)yf, value == Py_None ? NULL : value);
        } else
        #endif
783
        {
784
            if (value == Py_None)
785
                ret = Py_TYPE(yf)->tp_iternext(yf);
786
            else
787
                ret = __Pyx_PyObject_CallMethod1(yf, PYIDENT("send"), value);
788 789 790 791 792 793
        }
        gen->is_running = 0;
        //Py_DECREF(yf);
        if (likely(ret)) {
            return ret;
        }
794
        retval = __Pyx_Coroutine_FinishDelegation(gen);
795
    } else {
796
        retval = __Pyx_Coroutine_SendEx(gen, value, 0);
797
    }
798
    return __Pyx_Coroutine_MethodReturn(self, retval);
799 800 801 802
}

//   This helper function is used by gen_close and gen_throw to
//   close a subiterator being delegated to by yield-from.
803
static int __Pyx_Coroutine_CloseIter(__pyx_CoroutineObject *gen, PyObject *yf) {
804 805 806
    PyObject *retval = NULL;
    int err = 0;

807
    #ifdef __Pyx_Generator_USED
808
    if (__Pyx_Generator_CheckExact(yf)) {
809
        retval = __Pyx_Coroutine_Close(yf);
810 811
        if (!retval)
            return -1;
812 813 814 815 816 817 818 819
    } else
    #endif
    #ifdef __Pyx_Coroutine_USED
    if (__Pyx_Coroutine_CheckExact(yf)) {
        retval = __Pyx_Coroutine_Close(yf);
        if (!retval)
            return -1;
    } else
820 821 822 823 824 825 826 827 828 829 830 831 832 833 834
    if (__Pyx_CoroutineAwait_CheckExact(yf)) {
        retval = __Pyx_CoroutineAwait_Close((__pyx_CoroutineAwaitObject*)yf);
        if (!retval)
            return -1;
    } else
    #endif
    #ifdef __Pyx_AsyncGen_USED
    if (__pyx_PyAsyncGenASend_CheckExact(yf)) {
        retval = __Pyx_async_gen_asend_close(yf, NULL);
        // cannot fail
    } else
    if (__pyx_PyAsyncGenAThrow_CheckExact(yf)) {
        retval = __Pyx_async_gen_athrow_close(yf, NULL);
        // cannot fail
    } else
835 836
    #endif
    {
837 838
        PyObject *meth;
        gen->is_running = 1;
839
        meth = __Pyx_PyObject_GetAttrStr(yf, PYIDENT("close"));
840
        if (unlikely(!meth)) {
841
            if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
842 843 844 845
                PyErr_WriteUnraisable(yf);
            }
            PyErr_Clear();
        } else {
846
            retval = PyObject_CallFunction(meth, NULL);
847 848 849 850 851 852 853 854 855 856
            Py_DECREF(meth);
            if (!retval)
                err = -1;
        }
        gen->is_running = 0;
    }
    Py_XDECREF(retval);
    return err;
}

857 858 859
static PyObject *__Pyx_Generator_Next(PyObject *self) {
    __pyx_CoroutineObject *gen = (__pyx_CoroutineObject*) self;
    PyObject *yf = gen->yieldfrom;
Stefan Behnel's avatar
Stefan Behnel committed
860 861
    if (unlikely(gen->is_running))
        return __Pyx_Coroutine_AlreadyRunningError(gen);
862 863 864 865 866 867
    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;
868 869 870 871
        #ifdef __Pyx_Generator_USED
        if (__Pyx_Generator_CheckExact(yf)) {
            ret = __Pyx_Generator_Next(yf);
        } else
872 873 874 875 876
        #endif
        #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x03030000
        if (PyGen_CheckExact(yf)) {
            ret = _PyGen_Send((PyGenObject*)yf, NULL);
        } else
877 878
        #endif
            ret = Py_TYPE(yf)->tp_iternext(yf);
879 880 881 882 883 884 885
        gen->is_running = 0;
        //Py_DECREF(yf);
        if (likely(ret)) {
            return ret;
        }
        return __Pyx_Coroutine_FinishDelegation(gen);
    }
886
    return __Pyx_Coroutine_SendEx(gen, Py_None, 0);
887 888
}

889 890
static PyObject *__Pyx_Coroutine_Close(PyObject *self) {
    __pyx_CoroutineObject *gen = (__pyx_CoroutineObject *) self;
891 892 893 894
    PyObject *retval, *raised_exception;
    PyObject *yf = gen->yieldfrom;
    int err = 0;

Stefan Behnel's avatar
Stefan Behnel committed
895 896
    if (unlikely(gen->is_running))
        return __Pyx_Coroutine_AlreadyRunningError(gen);
897 898 899

    if (yf) {
        Py_INCREF(yf);
900 901
        err = __Pyx_Coroutine_CloseIter(gen, yf);
        __Pyx_Coroutine_Undelegate(gen);
902 903 904 905
        Py_DECREF(yf);
    }
    if (err == 0)
        PyErr_SetNone(PyExc_GeneratorExit);
906
    retval = __Pyx_Coroutine_SendEx(gen, NULL, 1);
907
    if (unlikely(retval)) {
908
        const char *msg;
909
        Py_DECREF(retval);
910
        if ((0)) {
911 912 913 914 915 916
        #ifdef __Pyx_Coroutine_USED
        } else if (__Pyx_Coroutine_CheckExact(self)) {
            msg = "coroutine ignored GeneratorExit";
        #endif
        #ifdef __Pyx_AsyncGen_USED
        } else if (__Pyx_AsyncGen_CheckExact(self)) {
917 918 919
#if PY_VERSION_HEX < 0x03060000
            msg = "async generator ignored GeneratorExit - might require Python 3.6+ finalisation (PEP 525)";
#else
920
            msg = "async generator ignored GeneratorExit";
921
#endif
922 923 924 925 926
        #endif
        } else {
            msg = "generator ignored GeneratorExit";
        }
        PyErr_SetString(PyExc_RuntimeError, msg);
927 928
        return NULL;
    }
929
    raised_exception = PyErr_Occurred();
930
    if (likely(!raised_exception || __Pyx_PyErr_GivenExceptionMatches2(raised_exception, PyExc_GeneratorExit, PyExc_StopIteration))) {
931 932
        // ignore these errors
        if (raised_exception) PyErr_Clear();
933 934 935 936 937 938
        Py_INCREF(Py_None);
        return Py_None;
    }
    return NULL;
}

939 940
static PyObject *__Pyx__Coroutine_Throw(PyObject *self, PyObject *typ, PyObject *val, PyObject *tb,
                                        PyObject *args, int close_on_genexit) {
941
    __pyx_CoroutineObject *gen = (__pyx_CoroutineObject *) self;
942
    PyObject *yf = gen->yieldfrom;
943

Stefan Behnel's avatar
Stefan Behnel committed
944 945
    if (unlikely(gen->is_running))
        return __Pyx_Coroutine_AlreadyRunningError(gen);
946 947 948 949

    if (yf) {
        PyObject *ret;
        Py_INCREF(yf);
950
        if (__Pyx_PyErr_GivenExceptionMatches(typ, PyExc_GeneratorExit) && close_on_genexit) {
951 952 953
            // Asynchronous generators *should not* be closed right away.
            // We have to allow some awaits to work it through, hence the
            // `close_on_genexit` parameter here.
954
            int err = __Pyx_Coroutine_CloseIter(gen, yf);
955
            Py_DECREF(yf);
956
            __Pyx_Coroutine_Undelegate(gen);
957
            if (err < 0)
958
                return __Pyx_Coroutine_MethodReturn(self, __Pyx_Coroutine_SendEx(gen, NULL, 0));
959 960 961
            goto throw_here;
        }
        gen->is_running = 1;
962
        if (0
963
        #ifdef __Pyx_Generator_USED
964
            || __Pyx_Generator_CheckExact(yf)
965 966
        #endif
        #ifdef __Pyx_Coroutine_USED
967 968 969 970
            || __Pyx_Coroutine_CheckExact(yf)
        #endif
            ) {
            ret = __Pyx__Coroutine_Throw(yf, typ, val, tb, args, close_on_genexit);
971 972 973 974
        #ifdef __Pyx_Coroutine_USED
        } else if (__Pyx_CoroutineAwait_CheckExact(yf)) {
            ret = __Pyx__Coroutine_Throw(((__pyx_CoroutineAwaitObject*)yf)->coroutine, typ, val, tb, args, close_on_genexit);
        #endif
975
        } else {
976
            PyObject *meth = __Pyx_PyObject_GetAttrStr(yf, PYIDENT("throw"));
977 978
            if (unlikely(!meth)) {
                Py_DECREF(yf);
979
                if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
980 981 982 983
                    gen->is_running = 0;
                    return NULL;
                }
                PyErr_Clear();
984
                __Pyx_Coroutine_Undelegate(gen);
985 986 987
                gen->is_running = 0;
                goto throw_here;
            }
988 989 990 991 992 993
            if (likely(args)) {
                ret = PyObject_CallObject(meth, args);
            } else {
                // "tb" or even "val" might be NULL, but that also correctly terminates the argument list
                ret = PyObject_CallFunctionObjArgs(meth, typ, val, tb, NULL);
            }
994 995 996 997 998
            Py_DECREF(meth);
        }
        gen->is_running = 0;
        Py_DECREF(yf);
        if (!ret) {
999
            ret = __Pyx_Coroutine_FinishDelegation(gen);
1000
        }
1001
        return __Pyx_Coroutine_MethodReturn(self, ret);
1002 1003
    }
throw_here:
1004
    __Pyx_Raise(typ, val, tb, NULL);
1005
    return __Pyx_Coroutine_MethodReturn(self, __Pyx_Coroutine_SendEx(gen, NULL, 0));
1006 1007
}

1008 1009 1010 1011
static PyObject *__Pyx_Coroutine_Throw(PyObject *self, PyObject *args) {
    PyObject *typ;
    PyObject *val = NULL;
    PyObject *tb = NULL;
1012

1013 1014 1015 1016 1017 1018 1019
    if (!PyArg_UnpackTuple(args, (char *)"throw", 1, 3, &typ, &val, &tb))
        return NULL;

    return __Pyx__Coroutine_Throw(self, typ, val, tb, args, 1);
}

static int __Pyx_Coroutine_traverse(__pyx_CoroutineObject *gen, visitproc visit, void *arg) {
1020 1021
    Py_VISIT(gen->closure);
    Py_VISIT(gen->classobj);
1022
    Py_VISIT(gen->yieldfrom);
1023 1024 1025 1026 1027 1028
    Py_VISIT(gen->exc_type);
    Py_VISIT(gen->exc_value);
    Py_VISIT(gen->exc_traceback);
    return 0;
}

1029 1030
static int __Pyx_Coroutine_clear(PyObject *self) {
    __pyx_CoroutineObject *gen = (__pyx_CoroutineObject *) self;
1031 1032 1033 1034 1035 1036 1037

    Py_CLEAR(gen->closure);
    Py_CLEAR(gen->classobj);
    Py_CLEAR(gen->yieldfrom);
    Py_CLEAR(gen->exc_type);
    Py_CLEAR(gen->exc_value);
    Py_CLEAR(gen->exc_traceback);
1038 1039
#ifdef __Pyx_AsyncGen_USED
    if (__Pyx_AsyncGen_CheckExact(self)) {
1040
        Py_CLEAR(((__pyx_PyAsyncGenObject*)gen)->ag_finalizer);
1041 1042
    }
#endif
1043 1044
    Py_CLEAR(gen->gi_name);
    Py_CLEAR(gen->gi_qualname);
1045 1046 1047
    return 0;
}

1048 1049
static void __Pyx_Coroutine_dealloc(PyObject *self) {
    __pyx_CoroutineObject *gen = (__pyx_CoroutineObject *) self;
1050

1051 1052 1053 1054
    PyObject_GC_UnTrack(gen);
    if (gen->gi_weakreflist != NULL)
        PyObject_ClearWeakRefs(self);

1055 1056
    if (gen->resume_label >= 0) {
        // Generator is paused or unstarted, so we need to close
1057 1058 1059 1060
        PyObject_GC_Track(self);
#if PY_VERSION_HEX >= 0x030400a1
        if (PyObject_CallFinalizerFromDealloc(self))
#else
1061 1062
        Py_TYPE(gen)->tp_del(self);
        if (self->ob_refcnt > 0)
1063
#endif
1064 1065 1066 1067
        {
            // resurrected.  :(
            return;
        }
1068
        PyObject_GC_UnTrack(self);
1069 1070
    }

1071 1072 1073 1074 1075 1076 1077 1078
#ifdef __Pyx_AsyncGen_USED
    if (__Pyx_AsyncGen_CheckExact(self)) {
        /* We have to handle this case for asynchronous generators
           right here, because this code has to be between UNTRACK
           and GC_Del. */
        Py_CLEAR(((__pyx_PyAsyncGenObject*)self)->ag_finalizer);
    }
#endif
1079
    __Pyx_Coroutine_clear(self);
1080 1081 1082
    PyObject_GC_Del(gen);
}

1083
static void __Pyx_Coroutine_del(PyObject *self) {
1084
    PyObject *error_type, *error_value, *error_traceback;
1085
    __pyx_CoroutineObject *gen = (__pyx_CoroutineObject *) self;
1086
    __Pyx_PyThreadState_declare
1087

1088
    if (gen->resume_label < 0) {
Stefan Behnel's avatar
Stefan Behnel committed
1089
        // already terminated => nothing to clean up
1090 1091
        return;
    }
1092

1093
#if PY_VERSION_HEX < 0x030400a1
1094
    // Temporarily resurrect the object.
1095 1096
    assert(self->ob_refcnt == 0);
    self->ob_refcnt = 1;
1097
#endif
1098

1099
    __Pyx_PyThreadState_assign
1100

1101 1102 1103
    // Save the current exception, if any.
    __Pyx_ErrFetch(&error_type, &error_value, &error_traceback);

1104 1105 1106 1107 1108
#ifdef __Pyx_AsyncGen_USED
    if (__Pyx_AsyncGen_CheckExact(self)) {
        __pyx_PyAsyncGenObject *agen = (__pyx_PyAsyncGenObject*)self;
        PyObject *finalizer = agen->ag_finalizer;
        if (finalizer && !agen->ag_closed) {
1109 1110
            PyObject *res = __Pyx_PyObject_CallOneArg(finalizer, self);
            if (unlikely(!res)) {
1111 1112 1113 1114
                PyErr_WriteUnraisable(self);
            } else {
                Py_DECREF(res);
            }
1115
            // Restore the saved exception.
1116 1117 1118 1119 1120 1121
            __Pyx_ErrRestore(error_type, error_value, error_traceback);
            return;
        }
    }
#endif

1122
    if (unlikely(gen->resume_label == 0 && !error_value)) {
1123 1124 1125 1126 1127 1128
#ifdef __Pyx_Coroutine_USED
#ifdef __Pyx_Generator_USED
    // only warn about (async) coroutines
    if (!__Pyx_Generator_CheckExact(self))
#endif
        {
1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157
        // untrack dead object as we are executing Python code (which might trigger GC)
        PyObject_GC_UnTrack(self);
#if PY_VERSION_HEX >= 0x03030000 || defined(PyErr_WarnFormat)
        if (unlikely(PyErr_WarnFormat(PyExc_RuntimeWarning, 1, "coroutine '%.50S' was never awaited", gen->gi_qualname) < 0))
            PyErr_WriteUnraisable(self);
#else
        {PyObject *msg;
        char *cmsg;
        #if CYTHON_COMPILING_IN_PYPY
        msg = NULL;
        cmsg = (char*) "coroutine was never awaited";
        #else
        char *cname;
        PyObject *qualname;
        #if PY_MAJOR_VERSION >= 3
        qualname = PyUnicode_AsUTF8String(gen->gi_qualname);
        if (likely(qualname)) {
            cname = PyBytes_AS_STRING(qualname);
        } else {
            PyErr_Clear();
            cname = (char*) "?";
        }
        msg = PyBytes_FromFormat(
        #else
        qualname = gen->gi_qualname;
        cname = PyString_AS_STRING(qualname);
        msg = PyString_FromFormat(
        #endif
            "coroutine '%.50s' was never awaited", cname);
1158

1159 1160 1161
        #if PY_MAJOR_VERSION >= 3
        Py_XDECREF(qualname);
        #endif
1162

1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178
        if (unlikely(!msg)) {
            PyErr_Clear();
            cmsg = (char*) "coroutine was never awaited";
        } else {
            #if PY_MAJOR_VERSION >= 3
            cmsg = PyBytes_AS_STRING(msg);
            #else
            cmsg = PyString_AS_STRING(msg);
            #endif
        }
        #endif
        if (unlikely(PyErr_WarnEx(PyExc_RuntimeWarning, cmsg, 1) < 0))
            PyErr_WriteUnraisable(self);
        Py_XDECREF(msg);}
#endif
        PyObject_GC_Track(self);
1179 1180
        }
#endif /*__Pyx_Coroutine_USED*/
1181 1182 1183 1184 1185 1186 1187 1188 1189
    } else {
        PyObject *res = __Pyx_Coroutine_Close(self);
        if (unlikely(!res)) {
            if (PyErr_Occurred())
                PyErr_WriteUnraisable(self);
        } else {
            Py_DECREF(res);
        }
    }
1190

1191
    // Restore the saved exception.
1192 1193
    __Pyx_ErrRestore(error_type, error_value, error_traceback);

1194
#if PY_VERSION_HEX < 0x030400a1
1195 1196
    // Undo the temporary resurrection; can't use DECREF here, it would
    // cause a recursive call.
1197
    assert(self->ob_refcnt > 0);
1198 1199 1200 1201
    if (--self->ob_refcnt == 0) {
        // this is the normal path out
        return;
    }
1202

1203 1204
    // close() resurrected it!  Make it look like the original Py_DECREF
    // never happened.
1205 1206 1207 1208 1209
    {
        Py_ssize_t refcnt = self->ob_refcnt;
        _Py_NewReference(self);
        self->ob_refcnt = refcnt;
    }
1210
#if CYTHON_COMPILING_IN_CPYTHON
1211 1212 1213
    assert(PyType_IS_GC(self->ob_type) &&
           _Py_AS_GC(self)->gc.gc_refs != _PyGC_REFS_UNTRACKED);

1214 1215
    // If Py_REF_DEBUG, _Py_NewReference bumped _Py_RefTotal, so
    // we need to undo that.
1216
    _Py_DEC_REFTOTAL;
1217
#endif
1218 1219 1220 1221 1222
    // If Py_TRACE_REFS, _Py_NewReference re-added self to the object
    // chain, so no more to do there.
    // If COUNT_ALLOCS, the original decref bumped tp_frees, and
    // _Py_NewReference bumped tp_allocs:  both of those need to be
    // undone.
1223
#ifdef COUNT_ALLOCS
1224 1225
    --Py_TYPE(self)->tp_frees;
    --Py_TYPE(self)->tp_allocs;
1226
#endif
1227
#endif
1228
}
1229

1230
static PyObject *
1231
__Pyx_Coroutine_get_name(__pyx_CoroutineObject *self)
1232
{
1233 1234 1235 1236 1237
    PyObject *name = self->gi_name;
    // avoid NULL pointer dereference during garbage collection
    if (unlikely(!name)) name = Py_None;
    Py_INCREF(name);
    return name;
1238 1239 1240
}

static int
1241
__Pyx_Coroutine_set_name(__pyx_CoroutineObject *self, PyObject *value)
1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261
{
    PyObject *tmp;

#if PY_MAJOR_VERSION >= 3
    if (unlikely(value == NULL || !PyUnicode_Check(value))) {
#else
    if (unlikely(value == NULL || !PyString_Check(value))) {
#endif
        PyErr_SetString(PyExc_TypeError,
                        "__name__ must be set to a string object");
        return -1;
    }
    tmp = self->gi_name;
    Py_INCREF(value);
    self->gi_name = value;
    Py_XDECREF(tmp);
    return 0;
}

static PyObject *
1262
__Pyx_Coroutine_get_qualname(__pyx_CoroutineObject *self)
1263
{
1264 1265 1266 1267 1268
    PyObject *name = self->gi_qualname;
    // avoid NULL pointer dereference during garbage collection
    if (unlikely(!name)) name = Py_None;
    Py_INCREF(name);
    return name;
1269 1270 1271
}

static int
1272
__Pyx_Coroutine_set_qualname(__pyx_CoroutineObject *self, PyObject *value)
1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291
{
    PyObject *tmp;

#if PY_MAJOR_VERSION >= 3
    if (unlikely(value == NULL || !PyUnicode_Check(value))) {
#else
    if (unlikely(value == NULL || !PyString_Check(value))) {
#endif
        PyErr_SetString(PyExc_TypeError,
                        "__qualname__ must be set to a string object");
        return -1;
    }
    tmp = self->gi_qualname;
    Py_INCREF(value);
    self->gi_qualname = value;
    Py_XDECREF(tmp);
    return 0;
}

1292 1293 1294
static __pyx_CoroutineObject *__Pyx__Coroutine_New(
            PyTypeObject* type, __pyx_coroutine_body_t body, PyObject *closure,
            PyObject *name, PyObject *qualname, PyObject *module_name) {
1295
    __pyx_CoroutineObject *gen = PyObject_GC_New(__pyx_CoroutineObject, type);
1296
    if (unlikely(!gen))
1297
        return NULL;
1298 1299
    return __Pyx__Coroutine_NewInit(gen, body, closure, name, qualname, module_name);
}
1300

1301 1302 1303
static __pyx_CoroutineObject *__Pyx__Coroutine_NewInit(
            __pyx_CoroutineObject *gen, __pyx_coroutine_body_t body, PyObject *closure,
            PyObject *name, PyObject *qualname, PyObject *module_name) {
1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318
    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;
1319 1320
    Py_XINCREF(module_name);
    gen->gi_modulename = module_name;
1321 1322 1323 1324 1325 1326 1327 1328 1329 1330

    PyObject_GC_Track(gen);
    return gen;
}


//////////////////// Coroutine ////////////////////
//@requires: CoroutineBase
//@requires: PatchGeneratorABC

1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367
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_Send(__pyx_CoroutineAwaitObject *self, PyObject *value) {
    return __Pyx_Coroutine_Send(self->coroutine, value);
}

static PyObject *__Pyx_CoroutineAwait_Throw(__pyx_CoroutineAwaitObject *self, PyObject *args) {
    return __Pyx_Coroutine_Throw(self->coroutine, args);
}

static PyObject *__Pyx_CoroutineAwait_Close(__pyx_CoroutineAwaitObject *self) {
    return __Pyx_Coroutine_Close(self->coroutine);
}

static PyObject *__Pyx_CoroutineAwait_self(PyObject *self) {
    Py_INCREF(self);
    return self;
}

1368
#if !CYTHON_COMPILING_IN_PYPY
1369
static PyObject *__Pyx_CoroutineAwait_no_new(CYTHON_UNUSED PyTypeObject *type, CYTHON_UNUSED PyObject *args, CYTHON_UNUSED PyObject *kwargs) {
Stefan Behnel's avatar
Stefan Behnel committed
1370
    PyErr_SetString(PyExc_TypeError, "cannot instantiate type, use 'await coroutine' instead");
1371 1372
    return NULL;
}
1373
#endif
1374 1375

static PyMethodDef __pyx_CoroutineAwait_methods[] = {
1376 1377 1378 1379 1380 1381
    {"send", (PyCFunction) __Pyx_CoroutineAwait_Send, METH_O,
     (char*) PyDoc_STR("send(arg) -> send 'arg' into coroutine,\nreturn next yielded value or raise StopIteration.")},
    {"throw", (PyCFunction) __Pyx_CoroutineAwait_Throw, METH_VARARGS,
     (char*) PyDoc_STR("throw(typ[,val[,tb]]) -> raise exception in coroutine,\nreturn next yielded value or raise StopIteration.")},
    {"close", (PyCFunction) __Pyx_CoroutineAwait_Close, METH_NOARGS,
     (char*) PyDoc_STR("close() -> raise GeneratorExit inside coroutine.")},
1382 1383 1384 1385 1386
    {0, 0, 0, 0}
};

static PyTypeObject __pyx_CoroutineAwaitType_type = {
    PyVarObject_HEAD_INIT(0, 0)
1387
    "coroutine_wrapper",                /*tp_name*/
1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422
    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, /*tp_flags*/
    PyDoc_STR("A wrapper object implementing __await__ for coroutines."), /*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*/
    __pyx_CoroutineAwait_methods,       /*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*/
1423
#if !CYTHON_COMPILING_IN_PYPY
1424
    __Pyx_CoroutineAwait_no_new,        /*tp_new*/
1425 1426 1427
#else
    0,                                  /*tp_new*/
#endif
1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446
    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) {
    __pyx_CoroutineAwaitObject *await = PyObject_GC_New(__pyx_CoroutineAwaitObject, __pyx_CoroutineAwaitType);
    if (unlikely(!await)) return NULL;
    Py_INCREF(coroutine);
    await->coroutine = coroutine;
1447
    PyObject_GC_Track(await);
1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458
    return (PyObject*)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);
}

1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472
#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3 && PY_VERSION_HEX < 0x030500B1
static PyObject *__Pyx_Coroutine_compare(PyObject *obj, PyObject *other, int op) {
    PyObject* result;
    switch (op) {
        case Py_EQ: result = (other == obj) ? Py_True : Py_False; break;
        case Py_NE: result = (other != obj) ? Py_True : Py_False; break;
        default:
            result = Py_NotImplemented;
    }
    Py_INCREF(result);
    return result;
}
#endif

1473
static PyMethodDef __pyx_Coroutine_methods[] = {
1474
    {"send", (PyCFunction) __Pyx_Coroutine_Send, METH_O,
1475
     (char*) PyDoc_STR("send(arg) -> send 'arg' into coroutine,\nreturn next iterated value or raise StopIteration.")},
1476
    {"throw", (PyCFunction) __Pyx_Coroutine_Throw, METH_VARARGS,
1477
     (char*) PyDoc_STR("throw(typ[,val[,tb]]) -> raise exception in coroutine,\nreturn next iterated value or raise StopIteration.")},
1478 1479
    {"close", (PyCFunction) __Pyx_Coroutine_Close, METH_NOARGS,
     (char*) PyDoc_STR("close() -> raise GeneratorExit inside coroutine.")},
1480
#if PY_VERSION_HEX < 0x030500B1
1481
    {"__await__", (PyCFunction) __Pyx_Coroutine_await, METH_NOARGS,
1482
     (char*) PyDoc_STR("__await__() -> return an iterator to be used in await expression.")},
1483 1484 1485 1486
#endif
    {0, 0, 0, 0}
};

1487 1488
static PyMemberDef __pyx_Coroutine_memberlist[] = {
    {(char *) "cr_running", T_BOOL, offsetof(__pyx_CoroutineObject, is_running), READONLY, NULL},
1489
    {(char*) "cr_await", T_OBJECT, offsetof(__pyx_CoroutineObject, yieldfrom), READONLY,
1490
     (char*) PyDoc_STR("object being awaited, or None")},
1491
    {(char *) "__module__", T_OBJECT, offsetof(__pyx_CoroutineObject, gi_modulename), PY_WRITE_RESTRICTED, 0},
1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502
    {0, 0, 0, 0, 0}
};

static PyGetSetDef __pyx_Coroutine_getsets[] = {
    {(char *) "__name__", (getter)__Pyx_Coroutine_get_name, (setter)__Pyx_Coroutine_set_name,
     (char*) PyDoc_STR("name of the coroutine"), 0},
    {(char *) "__qualname__", (getter)__Pyx_Coroutine_get_qualname, (setter)__Pyx_Coroutine_set_qualname,
     (char*) PyDoc_STR("qualified name of the coroutine"), 0},
    {0, 0, 0, 0, 0}
};

1503
#if CYTHON_USE_ASYNC_SLOTS
1504
static __Pyx_PyAsyncMethodsStruct __pyx_Coroutine_as_async = {
Stefan Behnel's avatar
Stefan Behnel committed
1505
    __Pyx_Coroutine_await, /*am_await*/
1506 1507
    0, /*am_aiter*/
    0, /*am_anext*/
1508
};
1509 1510
#endif

1511
static PyTypeObject __pyx_CoroutineType_type = {
1512
    PyVarObject_HEAD_INIT(0, 0)
1513 1514
    "coroutine",                        /*tp_name*/
    sizeof(__pyx_CoroutineObject),      /*tp_basicsize*/
1515
    0,                                  /*tp_itemsize*/
1516
    (destructor) __Pyx_Coroutine_dealloc,/*tp_dealloc*/
1517 1518 1519
    0,                                  /*tp_print*/
    0,                                  /*tp_getattr*/
    0,                                  /*tp_setattr*/
1520 1521
#if CYTHON_USE_ASYNC_SLOTS
    &__pyx_Coroutine_as_async,          /*tp_as_async (tp_reserved) - Py3 only! */
1522
#else
1523
    0,                                  /*tp_reserved*/
1524
#endif
1525
    0,                                  /*tp_repr*/
1526 1527 1528 1529 1530 1531
    0,                                  /*tp_as_number*/
    0,                                  /*tp_as_sequence*/
    0,                                  /*tp_as_mapping*/
    0,                                  /*tp_hash*/
    0,                                  /*tp_call*/
    0,                                  /*tp_str*/
Stefan Behnel's avatar
Stefan Behnel committed
1532
    0,                                  /*tp_getattro*/
1533 1534
    0,                                  /*tp_setattro*/
    0,                                  /*tp_as_buffer*/
1535
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
1536
    0,                                  /*tp_doc*/
1537
    (traverseproc) __Pyx_Coroutine_traverse,   /*tp_traverse*/
1538
    0,                                  /*tp_clear*/
1539
#if CYTHON_USE_ASYNC_SLOTS && CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3 && PY_VERSION_HEX < 0x030500B1
1540 1541 1542
    // in order to (mis-)use tp_reserved above, we must also implement tp_richcompare
    __Pyx_Coroutine_compare,            /*tp_richcompare*/
#else
1543
    0,                                  /*tp_richcompare*/
1544
#endif
1545
    offsetof(__pyx_CoroutineObject, gi_weakreflist), /*tp_weaklistoffset*/
Stefan Behnel's avatar
Stefan Behnel committed
1546
    // no tp_iter() as iterator is only available through __await__()
Stefan Behnel's avatar
Stefan Behnel committed
1547
    0,                                  /*tp_iter*/
1548
    0,                                  /*tp_iternext*/
1549 1550 1551
    __pyx_Coroutine_methods,            /*tp_methods*/
    __pyx_Coroutine_memberlist,         /*tp_members*/
    __pyx_Coroutine_getsets,            /*tp_getset*/
1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566
    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*/
1567 1568 1569
#if PY_VERSION_HEX >= 0x030400a1
    0,                                  /*tp_del*/
#else
1570
    __Pyx_Coroutine_del,                /*tp_del*/
1571
#endif
1572
    0,                                  /*tp_version_tag*/
1573
#if PY_VERSION_HEX >= 0x030400a1
1574
    __Pyx_Coroutine_del,                /*tp_finalize*/
1575
#endif
1576 1577
};

1578
static int __pyx_Coroutine_init(void) {
1579 1580
    // on Windows, C-API functions can't be used in slots statically
    __pyx_CoroutineType_type.tp_getattro = PyObject_GenericGetAttr;
1581

1582
    __pyx_CoroutineType = __Pyx_FetchCommonType(&__pyx_CoroutineType_type);
1583 1584 1585 1586 1587
    if (unlikely(!__pyx_CoroutineType))
        return -1;

    __pyx_CoroutineAwaitType = __Pyx_FetchCommonType(&__pyx_CoroutineAwaitType_type);
    if (unlikely(!__pyx_CoroutineAwaitType))
1588 1589 1590
        return -1;
    return 0;
}
1591

1592 1593 1594 1595
//////////////////// Generator ////////////////////
//@requires: CoroutineBase
//@requires: PatchGeneratorABC

1596
static PyMethodDef __pyx_Generator_methods[] = {
1597 1598 1599 1600 1601 1602
    {"send", (PyCFunction) __Pyx_Coroutine_Send, METH_O,
     (char*) PyDoc_STR("send(arg) -> send 'arg' into generator,\nreturn next yielded value or raise StopIteration.")},
    {"throw", (PyCFunction) __Pyx_Coroutine_Throw, METH_VARARGS,
     (char*) PyDoc_STR("throw(typ[,val[,tb]]) -> raise exception in generator,\nreturn next yielded value or raise StopIteration.")},
    {"close", (PyCFunction) __Pyx_Coroutine_Close, METH_NOARGS,
     (char*) PyDoc_STR("close() -> raise GeneratorExit inside generator.")},
1603 1604 1605
    {0, 0, 0, 0}
};

1606 1607
static PyMemberDef __pyx_Generator_memberlist[] = {
    {(char *) "gi_running", T_BOOL, offsetof(__pyx_CoroutineObject, is_running), READONLY, NULL},
1608 1609
    {(char*) "gi_yieldfrom", T_OBJECT, offsetof(__pyx_CoroutineObject, yieldfrom), READONLY,
     (char*) PyDoc_STR("object being iterated by 'yield from', or None")},
1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620
    {0, 0, 0, 0, 0}
};

static PyGetSetDef __pyx_Generator_getsets[] = {
    {(char *) "__name__", (getter)__Pyx_Coroutine_get_name, (setter)__Pyx_Coroutine_set_name,
     (char*) PyDoc_STR("name of the generator"), 0},
    {(char *) "__qualname__", (getter)__Pyx_Coroutine_get_qualname, (setter)__Pyx_Coroutine_set_qualname,
     (char*) PyDoc_STR("qualified name of the generator"), 0},
    {0, 0, 0, 0, 0}
};

1621 1622 1623 1624 1625 1626 1627 1628 1629
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*/
1630
    0,                                  /*tp_compare / tp_as_async*/
1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648
    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*/
1649
    __pyx_Generator_methods,            /*tp_methods*/
1650 1651
    __pyx_Generator_memberlist,         /*tp_members*/
    __pyx_Generator_getsets,            /*tp_getset*/
1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677
    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
};

1678
static int __pyx_Generator_init(void) {
1679
    // on Windows, C-API functions can't be used in slots statically
Stefan Behnel's avatar
Stefan Behnel committed
1680 1681
    __pyx_GeneratorType_type.tp_getattro = PyObject_GenericGetAttr;
    __pyx_GeneratorType_type.tp_iter = PyObject_SelfIter;
1682 1683

    __pyx_GeneratorType = __Pyx_FetchCommonType(&__pyx_GeneratorType_type);
1684
    if (unlikely(!__pyx_GeneratorType)) {
1685 1686 1687
        return -1;
    }
    return 0;
1688
}
1689 1690


1691 1692
/////////////// ReturnWithStopIteration.proto ///////////////

1693 1694
#define __Pyx_ReturnWithStopIteration(value)  \
    if (value == Py_None) PyErr_SetNone(PyExc_StopIteration); else __Pyx__ReturnWithStopIteration(value)
1695 1696 1697
static void __Pyx__ReturnWithStopIteration(PyObject* value); /*proto*/

/////////////// ReturnWithStopIteration ///////////////
1698
//@requires: Exceptions.c::PyErrFetchRestore
1699
//@requires: Exceptions.c::PyThreadStateGet
1700 1701 1702 1703 1704
//@substitute: naming

// 1) Instantiating an exception just to pass back a value is costly.
// 2) CPython 3.3 <= x < 3.5b1 crash in yield-from when the StopIteration is not instantiated.
// 3) Passing a tuple as value into PyErr_SetObject() passes its items on as arguments.
1705 1706
// 4) Passing an exception as value will interpret it as an exception on unpacking and raise it (or unpack its value).
// 5) If there is currently an exception being handled, we need to chain it.
1707 1708 1709

static void __Pyx__ReturnWithStopIteration(PyObject* value) {
    PyObject *exc, *args;
1710
#if CYTHON_COMPILING_IN_CPYTHON || CYTHON_COMPILING_IN_PYSTON
1711
    __Pyx_PyThreadState_declare
1712 1713
    if ((PY_VERSION_HEX >= 0x03030000 && PY_VERSION_HEX < 0x030500B1)
            || unlikely(PyTuple_Check(value) || PyExceptionInstance_Check(value))) {
1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725
        args = PyTuple_New(1);
        if (unlikely(!args)) return;
        Py_INCREF(value);
        PyTuple_SET_ITEM(args, 0, value);
        exc = PyType_Type.tp_call(PyExc_StopIteration, args, NULL);
        Py_DECREF(args);
        if (!exc) return;
    } else {
        // it's safe to avoid instantiating the exception
        Py_INCREF(value);
        exc = value;
    }
1726 1727
    __Pyx_PyThreadState_assign
    if (!$local_tstate_cname->exc_type) {
1728 1729 1730 1731 1732 1733 1734 1735
        // no chaining needed => avoid the overhead in PyErr_SetObject()
        Py_INCREF(PyExc_StopIteration);
        __Pyx_ErrRestore(PyExc_StopIteration, exc, NULL);
        return;
    }
#else
    args = PyTuple_Pack(1, value);
    if (unlikely(!args)) return;
1736 1737
    exc = PyObject_Call(PyExc_StopIteration, args, NULL);
    Py_DECREF(args);
1738
    if (unlikely(!exc)) return;
1739
#endif
1740 1741 1742
    PyErr_SetObject(PyExc_StopIteration, exc);
    Py_DECREF(exc);
}
1743 1744


1745
//////////////////// PatchModuleWithCoroutine.proto ////////////////////
1746

1747
static PyObject* __Pyx_Coroutine_patch_module(PyObject* module, const char* py_code); /*proto*/
1748

1749
//////////////////// PatchModuleWithCoroutine ////////////////////
1750 1751
//@substitute: naming

1752 1753
static PyObject* __Pyx_Coroutine_patch_module(PyObject* module, const char* py_code) {
#if defined(__Pyx_Generator_USED) || defined(__Pyx_Coroutine_USED)
1754
    int result;
1755 1756
    PyObject *globals, *result_obj;
    globals = PyDict_New();  if (unlikely(!globals)) goto ignore;
1757
    result = PyDict_SetItemString(globals, "_cython_coroutine_type",
1758
    #ifdef __Pyx_Coroutine_USED
1759 1760 1761
        (PyObject*)__pyx_CoroutineType);
    #else
        Py_None);
1762
    #endif
1763 1764
    if (unlikely(result < 0)) goto ignore;
    result = PyDict_SetItemString(globals, "_cython_generator_type",
1765
    #ifdef __Pyx_Generator_USED
1766 1767 1768
        (PyObject*)__pyx_GeneratorType);
    #else
        Py_None);
1769
    #endif
1770
    if (unlikely(result < 0)) goto ignore;
1771
    if (unlikely(PyDict_SetItemString(globals, "_module", module) < 0)) goto ignore;
1772
    if (unlikely(PyDict_SetItemString(globals, "__builtins__", $builtins_cname) < 0)) goto ignore;
1773 1774 1775 1776 1777 1778 1779 1780
    result_obj = PyRun_String(py_code, Py_file_input, globals, globals);
    if (unlikely(!result_obj)) goto ignore;
    Py_DECREF(result_obj);
    Py_DECREF(globals);
    return module;

ignore:
    Py_XDECREF(globals);
1781
    PyErr_WriteUnraisable(module);
1782 1783 1784 1785
    if (unlikely(PyErr_WarnEx(PyExc_RuntimeWarning, "Cython module failed to patch module with custom type", 1) < 0)) {
        Py_DECREF(module);
        module = NULL;
    }
1786 1787 1788 1789
#else
    // avoid "unused" warning
    py_code++;
#endif
1790 1791
    return module;
}
1792

1793

1794 1795
//////////////////// PatchGeneratorABC.proto ////////////////////

1796
// register with Generator/Coroutine ABCs in 'collections.abc'
1797 1798 1799 1800
// see https://bugs.python.org/issue24018
static int __Pyx_patch_abc(void); /*proto*/

//////////////////// PatchGeneratorABC ////////////////////
1801
//@requires: PatchModuleWithCoroutine
1802

1803 1804 1805 1806
#ifndef CYTHON_REGISTER_ABCS
#define CYTHON_REGISTER_ABCS 1
#endif

1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825
#if defined(__Pyx_Generator_USED) || defined(__Pyx_Coroutine_USED)
static PyObject* __Pyx_patch_abc_module(PyObject *module); /*proto*/
static PyObject* __Pyx_patch_abc_module(PyObject *module) {
    module = __Pyx_Coroutine_patch_module(
        module, CSTRING("""\
if _cython_generator_type is not None:
    try: Generator = _module.Generator
    except AttributeError: pass
    else: Generator.register(_cython_generator_type)
if _cython_coroutine_type is not None:
    try: Coroutine = _module.Coroutine
    except AttributeError: pass
    else: Coroutine.register(_cython_coroutine_type)
""")
    );
    return module;
}
#endif

1826
static int __Pyx_patch_abc(void) {
1827
#if defined(__Pyx_Generator_USED) || defined(__Pyx_Coroutine_USED)
1828
    static int abc_patched = 0;
1829
    if (CYTHON_REGISTER_ABCS && !abc_patched) {
1830
        PyObject *module;
1831
        module = PyImport_ImportModule((PY_VERSION_HEX >= 0x03030000) ? "collections.abc" : "collections");
1832
        if (!module) {
1833
            PyErr_WriteUnraisable(NULL);
1834 1835
            if (unlikely(PyErr_WarnEx(PyExc_RuntimeWarning,
                    ((PY_VERSION_HEX >= 0x03030000) ?
1836 1837
                        "Cython module failed to register with collections.abc module" :
                        "Cython module failed to register with collections module"), 1) < 0)) {
1838 1839 1840
                return -1;
            }
        } else {
1841
            module = __Pyx_patch_abc_module(module);
1842 1843 1844
            abc_patched = 1;
            if (unlikely(!module))
                return -1;
1845 1846
            Py_DECREF(module);
        }
1847 1848 1849 1850 1851 1852 1853 1854 1855
        // also register with "backports_abc" module if available, just in case
        module = PyImport_ImportModule("backports_abc");
        if (module) {
            module = __Pyx_patch_abc_module(module);
            Py_XDECREF(module);
        }
        if (!module) {
            PyErr_Clear();
        }
1856 1857
    }
#else
1858
    // avoid "unused" warning for __Pyx_Coroutine_patch_module()
1859
    if ((0)) __Pyx_Coroutine_patch_module(NULL, NULL);
1860 1861 1862 1863 1864
#endif
    return 0;
}


1865 1866 1867 1868 1869 1870
//////////////////// PatchAsyncIO.proto ////////////////////

// run after importing "asyncio" to patch Cython generator support into it
static PyObject* __Pyx_patch_asyncio(PyObject* module); /*proto*/

//////////////////// PatchAsyncIO ////////////////////
1871
//@requires: ImportExport.c::Import
1872
//@requires: PatchModuleWithCoroutine
1873 1874 1875
//@requires: PatchInspect

static PyObject* __Pyx_patch_asyncio(PyObject* module) {
1876
#if PY_VERSION_HEX < 0x030500B2 && \
1877 1878
        (defined(__Pyx_Coroutine_USED) || defined(__Pyx_Generator_USED)) && \
        (!defined(CYTHON_PATCH_ASYNCIO) || CYTHON_PATCH_ASYNCIO)
1879 1880 1881 1882 1883 1884
    PyObject *patch_module = NULL;
    static int asyncio_patched = 0;
    if (unlikely((!asyncio_patched) && module)) {
        PyObject *package;
        package = __Pyx_Import(PYIDENT("asyncio.coroutines"), NULL, 0);
        if (package) {
1885
            patch_module = __Pyx_Coroutine_patch_module(
1886
                PyObject_GetAttrString(package, "coroutines"), CSTRING("""\
1887 1888 1889 1890 1891 1892 1893 1894
try:
    coro_types = _module._COROUTINE_TYPES
except AttributeError: pass
else:
    if _cython_coroutine_type is not None and _cython_coroutine_type not in coro_types:
        coro_types = tuple(coro_types) + (_cython_coroutine_type,)
    if _cython_generator_type is not None and _cython_generator_type not in coro_types:
        coro_types = tuple(coro_types) + (_cython_generator_type,)
1895
_module._COROUTINE_TYPES = coro_types
1896
""")
1897 1898 1899
            );
        } else {
            PyErr_Clear();
1900 1901
#if PY_VERSION_HEX < 0x03040200
            // Py3.4.1 used to have asyncio.tasks instead of asyncio.coroutines
1902 1903
            package = __Pyx_Import(PYIDENT("asyncio.tasks"), NULL, 0);
            if (unlikely(!package)) goto asyncio_done;
1904
            patch_module = __Pyx_Coroutine_patch_module(
1905
                PyObject_GetAttrString(package, "tasks"), CSTRING("""\
1906
if hasattr(_module, 'iscoroutine'):
1907 1908 1909 1910
    old_types = getattr(_module.iscoroutine, '_cython_coroutine_types', None)
    if old_types is None or not isinstance(old_types, set):
        old_types = set()
        def cy_wrap(orig_func, type=type, cython_coroutine_types=old_types):
1911 1912 1913 1914
            def cy_iscoroutine(obj): return type(obj) in cython_coroutine_types or orig_func(obj)
            cy_iscoroutine._cython_coroutine_types = cython_coroutine_types
            return cy_iscoroutine
        _module.iscoroutine = cy_wrap(_module.iscoroutine)
1915 1916 1917 1918
    if _cython_coroutine_type is not None:
        old_types.add(_cython_coroutine_type)
    if _cython_generator_type is not None:
        old_types.add(_cython_generator_type)
1919
""")
1920
            );
Stefan Behnel's avatar
Stefan Behnel committed
1921
#endif
1922
// Py < 0x03040200
1923 1924 1925
        }
        Py_DECREF(package);
        if (unlikely(!patch_module)) goto ignore;
1926
#if PY_VERSION_HEX < 0x03040200
1927 1928 1929 1930
asyncio_done:
        PyErr_Clear();
#endif
        asyncio_patched = 1;
1931
#ifdef __Pyx_Generator_USED
1932 1933 1934 1935
        // now patch inspect.isgenerator() by looking up the imported module in the patched asyncio module
        {
            PyObject *inspect_module;
            if (patch_module) {
1936
                inspect_module = PyObject_GetAttr(patch_module, PYIDENT("inspect"));
1937 1938 1939 1940 1941 1942 1943 1944 1945 1946
                Py_DECREF(patch_module);
            } else {
                inspect_module = __Pyx_Import(PYIDENT("inspect"), NULL, 0);
            }
            if (unlikely(!inspect_module)) goto ignore;
            inspect_module = __Pyx_patch_inspect(inspect_module);
            if (unlikely(!inspect_module)) {
                Py_DECREF(module);
                module = NULL;
            }
1947
            Py_XDECREF(inspect_module);
1948
        }
1949 1950
#else
        // avoid "unused" warning for __Pyx_patch_inspect()
1951
        if ((0)) return __Pyx_patch_inspect(module);
1952
#endif
1953 1954 1955 1956 1957 1958 1959 1960
    }
    return module;
ignore:
    PyErr_WriteUnraisable(module);
    if (unlikely(PyErr_WarnEx(PyExc_RuntimeWarning, "Cython module failed to patch asyncio package with custom generator type", 1) < 0)) {
        Py_DECREF(module);
        module = NULL;
    }
1961
#else
1962
    // avoid "unused" warning for __Pyx_Coroutine_patch_module()
1963
    if ((0)) return __Pyx_patch_inspect(__Pyx_Coroutine_patch_module(module, NULL));
1964
#endif
1965 1966 1967 1968 1969 1970 1971 1972 1973 1974
    return module;
}


//////////////////// PatchInspect.proto ////////////////////

// run after importing "inspect" to patch Cython generator support into it
static PyObject* __Pyx_patch_inspect(PyObject* module); /*proto*/

//////////////////// PatchInspect ////////////////////
1975
//@requires: PatchModuleWithCoroutine
1976 1977

static PyObject* __Pyx_patch_inspect(PyObject* module) {
1978
#if defined(__Pyx_Generator_USED) && (!defined(CYTHON_PATCH_INSPECT) || CYTHON_PATCH_INSPECT)
1979 1980
    static int inspect_patched = 0;
    if (unlikely((!inspect_patched) && module)) {
1981
        module = __Pyx_Coroutine_patch_module(
1982 1983 1984 1985 1986 1987 1988
            module, CSTRING("""\
old_types = getattr(_module.isgenerator, '_cython_generator_types', None)
if old_types is None or not isinstance(old_types, set):
    old_types = set()
    def cy_wrap(orig_func, type=type, cython_generator_types=old_types):
        def cy_isgenerator(obj): return type(obj) in cython_generator_types or orig_func(obj)
        cy_isgenerator._cython_generator_types = cython_generator_types
1989 1990
        return cy_isgenerator
    _module.isgenerator = cy_wrap(_module.isgenerator)
1991
old_types.add(_cython_generator_type)
1992
""")
1993 1994 1995
        );
        inspect_patched = 1;
    }
1996
#else
1997
    // avoid "unused" warning for __Pyx_Coroutine_patch_module()
1998
    if ((0)) return __Pyx_Coroutine_patch_module(module, NULL);
1999
#endif
2000 2001
    return module;
}
2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021


//////////////////// StopAsyncIteration.proto ////////////////////

#define __Pyx_StopAsyncIteration_USED
static PyObject *__Pyx_PyExc_StopAsyncIteration;
static int __pyx_StopAsyncIteration_init(void); /*proto*/

//////////////////// StopAsyncIteration ////////////////////

#if PY_VERSION_HEX < 0x030500B1
static PyTypeObject __Pyx__PyExc_StopAsyncIteration_type = {
    PyVarObject_HEAD_INIT(0, 0)
    "StopAsyncIteration",               /*tp_name*/
    sizeof(PyBaseExceptionObject),      /*tp_basicsize*/
    0,                                  /*tp_itemsize*/
    0,                                  /*tp_dealloc*/
    0,                                  /*tp_print*/
    0,                                  /*tp_getattr*/
    0,                                  /*tp_setattr*/
Stefan Behnel's avatar
Stefan Behnel committed
2022
    0,                                  /*tp_compare / reserved*/
2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072
    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_BASETYPE | Py_TPFLAGS_HAVE_GC,  /*tp_flags*/
    PyDoc_STR("Signal the end from iterator.__anext__()."),  /*tp_doc*/
    0,                                  /*tp_traverse*/
    0,                                  /*tp_clear*/
    0,                                  /*tp_richcompare*/
    0,                                  /*tp_weaklistoffset*/
    0,                                  /*tp_iter*/
    0,                                  /*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
};
#endif

static int __pyx_StopAsyncIteration_init(void) {
#if PY_VERSION_HEX >= 0x030500B1
    __Pyx_PyExc_StopAsyncIteration = PyExc_StopAsyncIteration;
#else
    PyObject *builtins = PyEval_GetBuiltins();
    if (likely(builtins)) {
Stefan Behnel's avatar
Stefan Behnel committed
2073
        PyObject *exc = PyMapping_GetItemString(builtins, (char*) "StopAsyncIteration");
2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088
        if (exc) {
            __Pyx_PyExc_StopAsyncIteration = exc;
            return 0;
        }
    }
    PyErr_Clear();

    __Pyx__PyExc_StopAsyncIteration_type.tp_traverse = ((PyTypeObject*)PyExc_BaseException)->tp_traverse;
    __Pyx__PyExc_StopAsyncIteration_type.tp_clear = ((PyTypeObject*)PyExc_BaseException)->tp_clear;
    __Pyx__PyExc_StopAsyncIteration_type.tp_dictoffset = ((PyTypeObject*)PyExc_BaseException)->tp_dictoffset;
    __Pyx__PyExc_StopAsyncIteration_type.tp_base = (PyTypeObject*)PyExc_Exception;

    __Pyx_PyExc_StopAsyncIteration = (PyObject*) __Pyx_FetchCommonType(&__Pyx__PyExc_StopAsyncIteration_type);
    if (unlikely(!__Pyx_PyExc_StopAsyncIteration))
        return -1;
Stefan Behnel's avatar
Stefan Behnel committed
2089
    if (builtins && unlikely(PyMapping_SetItemString(builtins, (char*) "StopAsyncIteration", __Pyx_PyExc_StopAsyncIteration) < 0))
2090 2091 2092 2093
        return -1;
#endif
    return 0;
}