Coroutine.c 85.3 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 9 10 11 12 13 14
static void __PyxPyIter_CheckErrorAndDecref(PyObject *source) {
    PyErr_Format(PyExc_TypeError,
                 "iter() returned non-iterator of type '%.100s'",
                 Py_TYPE(source)->tp_name);
    Py_DECREF(source);
}

15
static CYTHON_INLINE PyObject* __Pyx_Generator_Yield_From(__pyx_CoroutineObject *gen, PyObject *source) {
16
    PyObject *source_gen, *retval;
17
#ifdef __Pyx_Coroutine_USED
18
    if (__Pyx_Coroutine_Check(source)) {
19 20 21 22 23 24 25
        // 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
    {
26
#if CYTHON_USE_TYPE_SLOTS
27 28 29 30 31
        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))) {
32
                __PyxPyIter_CheckErrorAndDecref(source_gen);
33 34
                return NULL;
            }
35
        } else
36
        // CPython also allows non-iterable sequences to be iterated over
37
#endif
38
        {
39
            source_gen = PyObject_GetIter(source);
40 41 42
            if (unlikely(!source_gen))
                return NULL;
        }
43
        // source_gen is now the iterator, make the first next() call
44
#if CYTHON_USE_TYPE_SLOTS
45
        retval = Py_TYPE(source_gen)->tp_iternext(source_gen);
46 47 48
#else
        retval = PyIter_Next(source_gen);
#endif
49
    }
50 51 52 53 54 55 56 57
    if (likely(retval)) {
        gen->yieldfrom = source_gen;
        return retval;
    }
    Py_DECREF(source_gen);
    return NULL;
}

58

59 60
//////////////////// CoroutineYieldFrom.proto ////////////////////

61
static CYTHON_INLINE PyObject* __Pyx_Coroutine_Yield_From(__pyx_CoroutineObject *gen, PyObject *source);
62 63 64 65 66

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

67
static PyObject* __Pyx__Coroutine_Yield_From_Generic(__pyx_CoroutineObject *gen, PyObject *source) {
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
74
    if (__Pyx_Coroutine_Check(source_gen)) {
75 76
        retval = __Pyx_Generator_Next(source_gen);
    } else {
77
#if CYTHON_USE_TYPE_SLOTS
78
        retval = Py_TYPE(source_gen)->tp_iternext(source_gen);
79 80 81
#else
        retval = PyIter_Next(source_gen);
#endif
82 83 84 85 86 87 88 89 90
    }
    if (retval) {
        gen->yieldfrom = source_gen;
        return retval;
    }
    Py_DECREF(source_gen);
    return NULL;
}

91
static CYTHON_INLINE PyObject* __Pyx_Coroutine_Yield_From(__pyx_CoroutineObject *gen, PyObject *source) {
92
    PyObject *retval;
93
    if (__Pyx_Coroutine_Check(source)) {
94 95 96 97
        if (unlikely(((__pyx_CoroutineObject*)source)->yieldfrom)) {
            PyErr_SetString(
                PyExc_RuntimeError,
                "coroutine is being awaited already");
Stefan Behnel's avatar
Stefan Behnel committed
98
            return NULL;
99
        }
Stefan Behnel's avatar
Stefan Behnel committed
100
        retval = __Pyx_Generator_Next(source);
101
#ifdef __Pyx_AsyncGen_USED
Stefan Behnel's avatar
Stefan Behnel committed
102
    // inlined "__pyx_PyAsyncGenASend" handling to avoid the series of generic calls
103
    } else if (__pyx_PyAsyncGenASend_CheckExact(source)) {
104
        retval = __Pyx_async_gen_asend_iternext(source);
105
#endif
106
    } else {
107
        return __Pyx__Coroutine_Yield_From_Generic(gen, source);
108
    }
Stefan Behnel's avatar
Stefan Behnel committed
109 110 111 112 113
    if (retval) {
        Py_INCREF(source);
        gen->yieldfrom = source;
    }
    return retval;
114 115 116
}


117 118 119 120 121 122
//////////////////// GetAwaitIter.proto ////////////////////

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

//////////////////// GetAwaitIter ////////////////////
123
//@requires: ObjectHandling.c::PyObjectGetMethod
124 125 126 127 128
//@requires: ObjectHandling.c::PyObjectCallNoArg
//@requires: ObjectHandling.c::PyObjectCallOneArg

static CYTHON_INLINE PyObject *__Pyx_Coroutine_GetAwaitableIter(PyObject *o) {
#ifdef __Pyx_Coroutine_USED
129
    if (__Pyx_Coroutine_Check(o)) {
130
        return __Pyx_NewRef(o);
131 132 133 134 135
    }
#endif
    return __Pyx__Coroutine_GetAwaitableIter(o);
}

136

Stefan Behnel's avatar
Stefan Behnel committed
137
static void __Pyx_Coroutine_AwaitableIterError(PyObject *source) {
138
#if PY_VERSION_HEX >= 0x030600B3 || defined(_PyErr_FormatFromCause)
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172
    _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
}

173 174
// adapted from genobject.c in Py3.5
static PyObject *__Pyx__Coroutine_GetAwaitableIter(PyObject *obj) {
175
    PyObject *res;
176
#if CYTHON_USE_ASYNC_SLOTS
177
    __Pyx_PyAsyncMethodsStruct* am = __Pyx_PyType_AsAsync(obj);
178 179
    if (likely(am && am->am_await)) {
        res = (*am->am_await)(obj);
180
    } else
181
#endif
182
#if PY_VERSION_HEX >= 0x030500B2 || defined(PyCoro_CheckExact)
183
    if (PyCoro_CheckExact(obj)) {
Stefan Behnel's avatar
Stefan Behnel committed
184
        return __Pyx_NewRef(obj);
185 186 187 188 189
    } 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
190
        return __Pyx_NewRef(obj);
191
    } else
192 193
#endif
    {
194 195 196 197 198
        PyObject *method = NULL;
        int is_method = __Pyx_PyObject_GetMethod(obj, PYIDENT("__await__"), &method);
        if (likely(is_method)) {
            res = __Pyx_PyObject_CallOneArg(method, obj);
        } else if (likely(method)) {
199
            res = __Pyx_PyObject_CallNoArg(method);
200 201
        } else
            goto slot_error;
202 203
        Py_DECREF(method);
    }
204 205
    if (unlikely(!res)) {
        // surprisingly, CPython replaces the exception here...
Stefan Behnel's avatar
Stefan Behnel committed
206
        __Pyx_Coroutine_AwaitableIterError(obj);
207 208
        goto bad;
    }
Stefan Behnel's avatar
Stefan Behnel committed
209
    if (unlikely(!PyIter_Check(res))) {
210 211 212 213 214 215 216
        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
217
        is_coroutine |= __Pyx_Coroutine_Check(res);
218
        #endif
219
        #if PY_VERSION_HEX >= 0x030500B2 || defined(PyCoro_CheckExact)
220
        is_coroutine |= PyCoro_CheckExact(res);
221 222 223 224 225 226 227 228 229 230 231 232 233
        #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",
234
                 Py_TYPE(obj)->tp_name);
235 236 237 238 239
bad:
    return NULL;
}


240 241 242 243 244 245 246 247 248
//////////////////// 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
249
static PyObject *__Pyx_Coroutine_GetAsyncIter_Generic(PyObject *obj) {
250 251 252 253 254 255
#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__'
256
        if (!PyErr_ExceptionMatches(PyExc_AttributeError))
257 258
            return NULL;
    }
259
#else
260
    // avoid C warning about 'unused function'
261
    if ((0)) (void) __Pyx_PyObject_CallMethod0(obj, PYIDENT("__aiter__"));
262 263 264 265 266 267 268
#endif

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

269

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


static PyObject *__Pyx__Coroutine_AsyncIterNext(PyObject *obj) {
289 290 291 292 293 294
#if PY_VERSION_HEX < 0x030500B1
    {
        PyObject *value = __Pyx_PyObject_CallMethod0(obj, PYIDENT("__anext__"));
        if (likely(value))
            return value;
    }
295
    // FIXME: for the sake of a nicely conforming exception message, assume any AttributeError meant '__anext__'
296
    if (PyErr_ExceptionMatches(PyExc_AttributeError))
297 298 299 300 301 302 303
#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
304 305 306
static CYTHON_INLINE PyObject *__Pyx_Coroutine_AsyncIterNext(PyObject *obj) {
#ifdef __Pyx_AsyncGen_USED
    if (__Pyx_AsyncGen_CheckExact(obj)) {
307
        return __Pyx_async_gen_anext(obj);
Stefan Behnel's avatar
Stefan Behnel committed
308 309 310 311 312 313 314 315 316 317 318 319 320 321
    }
#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);
}


322 323
//////////////////// pep479.proto ////////////////////

324
static void __Pyx_Generator_Replace_StopIteration(int in_async_gen); /*proto*/
325 326 327 328

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

329 330
static void __Pyx_Generator_Replace_StopIteration(CYTHON_UNUSED int in_async_gen) {
    PyObject *exc, *val, *tb, *cur_exc;
331
    __Pyx_PyThreadState_declare
332 333 334 335 336
    #ifdef __Pyx_StopAsyncIteration_USED
    int is_async_stopiteration = 0;
    #endif

    cur_exc = PyErr_Occurred();
337
    if (likely(!__Pyx_PyErr_GivenExceptionMatches(cur_exc, PyExc_StopIteration))) {
338
        #ifdef __Pyx_StopAsyncIteration_USED
339
        if (in_async_gen && unlikely(__Pyx_PyErr_GivenExceptionMatches(cur_exc, __Pyx_PyExc_StopAsyncIteration))) {
340 341 342 343 344 345
            is_async_stopiteration = 1;
        } else
        #endif
            return;
    }

346
    __Pyx_PyThreadState_assign
347 348
    // 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.
349 350 351 352
    __Pyx_GetException(&exc, &val, &tb);
    Py_XDECREF(exc);
    Py_XDECREF(val);
    Py_XDECREF(tb);
353 354 355 356 357 358
    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");
359 360 361
}


362
//////////////////// CoroutineBase.proto ////////////////////
363
//@substitute: naming
364

365 366
struct __pyx_CoroutineObject;
typedef PyObject *(*__pyx_coroutine_body_t)(struct __pyx_CoroutineObject *, PyThreadState *, PyObject *);
367

368 369 370 371 372
#if CYTHON_USE_EXC_INFO_STACK
// See  https://bugs.python.org/issue25612
#define __Pyx_ExcInfoStruct  _PyErr_StackItem
#else
// Minimal replacement struct for Py<3.7, without the Py3.7 exception state stack.
373 374 375 376
typedef struct {
    PyObject *exc_type;
    PyObject *exc_value;
    PyObject *exc_traceback;
377 378 379
} __Pyx_ExcInfoStruct;
#endif

380
typedef struct __pyx_CoroutineObject {
381 382 383 384
    PyObject_HEAD
    __pyx_coroutine_body_t body;
    PyObject *closure;
    __Pyx_ExcInfoStruct gi_exc_state;
385 386
    PyObject *gi_weakreflist;
    PyObject *classobj;
387
    PyObject *yieldfrom;
388 389
    PyObject *gi_name;
    PyObject *gi_qualname;
390
    PyObject *gi_modulename;
391
    PyObject *gi_code;
392
    PyObject *gi_frame;
393
    int resume_label;
394 395
    // using T_BOOL for property below requires char value
    char is_running;
396
} __pyx_CoroutineObject;
397

398
static __pyx_CoroutineObject *__Pyx__Coroutine_New(
399
    PyTypeObject *type, __pyx_coroutine_body_t body, PyObject *code, PyObject *closure,
400
    PyObject *name, PyObject *qualname, PyObject *module_name); /*proto*/
401 402

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

406
static CYTHON_INLINE void __Pyx_Coroutine_ExceptionClear(__Pyx_ExcInfoStruct *self);
407
static int __Pyx_Coroutine_clear(PyObject *self); /*proto*/
408 409 410
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*/
411

412
// macros for exception state swapping instead of inline functions to make use of the local thread state context
413
#if CYTHON_USE_EXC_INFO_STACK
414
#define __Pyx_Coroutine_SwapException(self)
415 416
#define __Pyx_Coroutine_ResetAndClearException(self)  __Pyx_Coroutine_ExceptionClear(&(self)->gi_exc_state)
#else
417
#define __Pyx_Coroutine_SwapException(self) { \
418
    __Pyx_ExceptionSwap(&(self)->gi_exc_state.exc_type, &(self)->gi_exc_state.exc_value, &(self)->gi_exc_state.exc_traceback); \
419
    __Pyx_Coroutine_ResetFrameBackpointer(&(self)->gi_exc_state); \
420 421
    }
#define __Pyx_Coroutine_ResetAndClearException(self) { \
422 423
    __Pyx_ExceptionReset((self)->gi_exc_state.exc_type, (self)->gi_exc_state.exc_value, (self)->gi_exc_state.exc_traceback); \
    (self)->gi_exc_state.exc_type = (self)->gi_exc_state.exc_value = (self)->gi_exc_state.exc_traceback = NULL; \
424
    }
425
#endif
426

427 428 429
#if CYTHON_FAST_THREAD_STATE
#define __Pyx_PyGen_FetchStopIterationValue(pvalue) \
    __Pyx_PyGen__FetchStopIterationValue($local_tstate_cname, pvalue)
430
#else
431 432
#define __Pyx_PyGen_FetchStopIterationValue(pvalue) \
    __Pyx_PyGen__FetchStopIterationValue(__Pyx_PyThreadState_Current, pvalue)
433
#endif
434
static int __Pyx_PyGen__FetchStopIterationValue(PyThreadState *tstate, PyObject **pvalue); /*proto*/
435
static CYTHON_INLINE void __Pyx_Coroutine_ResetFrameBackpointer(__Pyx_ExcInfoStruct *exc_state); /*proto*/
436

437 438 439 440 441

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

#define __Pyx_Coroutine_USED
static PyTypeObject *__pyx_CoroutineType = 0;
442
static PyTypeObject *__pyx_CoroutineAwaitType = 0;
443
#define __Pyx_Coroutine_CheckExact(obj) __Pyx_IS_TYPE(obj, __pyx_CoroutineType)
444 445
// __Pyx_Coroutine_Check(obj): see override for IterableCoroutine below
#define __Pyx_Coroutine_Check(obj) __Pyx_Coroutine_CheckExact(obj)
446
#define __Pyx_CoroutineAwait_CheckExact(obj) __Pyx_IS_TYPE(obj, __pyx_CoroutineAwaitType)
447

448 449
#define __Pyx_Coroutine_New(body, code, closure, name, qualname, module_name)  \
    __Pyx__Coroutine_New(__pyx_CoroutineType, body, code, closure, name, qualname, module_name)
450

Stefan Behnel's avatar
Stefan Behnel committed
451
static int __pyx_Coroutine_init(void); /*proto*/
452
static PyObject *__Pyx__Coroutine_await(PyObject *coroutine); /*proto*/
453

454 455 456 457 458
typedef struct {
    PyObject_HEAD
    PyObject *coroutine;
} __pyx_CoroutineAwaitObject;

459
static PyObject *__Pyx_CoroutineAwait_Close(__pyx_CoroutineAwaitObject *self, PyObject *arg); /*proto*/
460 461
static PyObject *__Pyx_CoroutineAwait_Throw(__pyx_CoroutineAwaitObject *self, PyObject *args); /*proto*/

462 463 464 465 466

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

#define __Pyx_Generator_USED
static PyTypeObject *__pyx_GeneratorType = 0;
467
#define __Pyx_Generator_CheckExact(obj) __Pyx_IS_TYPE(obj, __pyx_GeneratorType)
468

469 470
#define __Pyx_Generator_New(body, code, closure, name, qualname, module_name)  \
    __Pyx__Coroutine_New(__pyx_GeneratorType, body, code, closure, name, qualname, module_name)
471

472
static PyObject *__Pyx_Generator_Next(PyObject *self);
Stefan Behnel's avatar
Stefan Behnel committed
473
static int __pyx_Generator_init(void); /*proto*/
474 475


476 477 478 479 480
//////////////////// AsyncGen ////////////////////
//@requires: AsyncGen.c::AsyncGenerator
// -> empty, only delegates to separate file


481
//////////////////// CoroutineBase ////////////////////
482
//@substitute: naming
483
//@requires: Exceptions.c::PyErrFetchRestore
484
//@requires: Exceptions.c::PyThreadStateGet
485 486
//@requires: Exceptions.c::SwapException
//@requires: Exceptions.c::RaiseException
487
//@requires: Exceptions.c::SaveResetException
488
//@requires: ObjectHandling.c::PyObjectCallMethod1
489
//@requires: ObjectHandling.c::PyObjectGetAttrStr
490
//@requires: ObjectHandling.c::PyObjectGetAttrStrNoError
491
//@requires: CommonStructures.c::FetchCommonType
492

493 494
#include <structmember.h>
#include <frameobject.h>
495

496
#define __Pyx_Coroutine_Undelegate(gen) Py_CLEAR((gen)->yieldfrom)
497 498 499 500 501 502 503

//   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.
504
static int __Pyx_PyGen__FetchStopIterationValue(CYTHON_UNUSED PyThreadState *$local_tstate_cname, PyObject **pvalue) {
505 506 507 508 509 510 511 512 513 514 515 516 517 518 519
    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)) {
520 521 522 523
        if (!ev) {
            Py_INCREF(Py_None);
            value = Py_None;
        }
524
#if PY_VERSION_HEX >= 0x030300A0
525
        else if (likely(__Pyx_IS_TYPE(ev, (PyTypeObject*)PyExc_StopIteration))) {
526 527 528 529 530
            value = ((PyStopIterationObject *)ev)->value;
            Py_INCREF(value);
            Py_DECREF(ev);
        }
#endif
531 532 533 534
        // 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) {
535
#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
536 537
                value = PyTuple_GET_ITEM(ev, 0);
                Py_INCREF(value);
538 539
#else
                value = PySequence_ITEM(ev, 0);
540
#endif
541 542 543
            } else {
                Py_INCREF(Py_None);
                value = Py_None;
544
            }
545 546
            Py_DECREF(ev);
        }
547
        else if (!__Pyx_TypeCheck(ev, (PyTypeObject*)PyExc_StopIteration)) {
548 549 550 551
            // 'steal' reference to ev
            value = ev;
        }
        if (likely(value)) {
552 553
            Py_XDECREF(tb);
            Py_DECREF(et);
554
            *pvalue = value;
555 556
            return 0;
        }
557
    } else if (!__Pyx_PyErr_GivenExceptionMatches(et, PyExc_StopIteration)) {
558 559
        __Pyx_ErrRestore(et, ev, tb);
        return -1;
560
    }
561

562 563
    // otherwise: normalise and check what that gives us
    PyErr_NormalizeException(&et, &ev, &tb);
564
    if (unlikely(!PyObject_TypeCheck(ev, (PyTypeObject*)PyExc_StopIteration))) {
565 566 567 568 569 570 571 572 573 574 575 576
        // 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
    {
577
        PyObject* args = __Pyx_PyObject_GetAttrStr(ev, PYIDENT("args"));
578 579
        Py_DECREF(ev);
        if (likely(args)) {
580
            value = PySequence_GetItem(args, 0);
581 582 583 584 585 586 587 588 589 590 591 592 593
            Py_DECREF(args);
        }
        if (unlikely(!value)) {
            __Pyx_ErrRestore(NULL, NULL, NULL);
            Py_INCREF(Py_None);
            value = Py_None;
        }
    }
#endif
    *pvalue = value;
    return 0;
}

594
static CYTHON_INLINE
595 596 597 598 599 600 601 602 603 604 605 606 607
void __Pyx_Coroutine_ExceptionClear(__Pyx_ExcInfoStruct *exc_state) {
    PyObject *t, *v, *tb;
    t = exc_state->exc_type;
    v = exc_state->exc_value;
    tb = exc_state->exc_traceback;

    exc_state->exc_type = NULL;
    exc_state->exc_value = NULL;
    exc_state->exc_traceback = NULL;

    Py_XDECREF(t);
    Py_XDECREF(v);
    Py_XDECREF(tb);
608 609
}

Stefan Behnel's avatar
Stefan Behnel committed
610
#define __Pyx_Coroutine_AlreadyRunningError(gen)  (__Pyx__Coroutine_AlreadyRunningError(gen), (PyObject*)NULL)
611
static void __Pyx__Coroutine_AlreadyRunningError(CYTHON_UNUSED __pyx_CoroutineObject *gen) {
Stefan Behnel's avatar
Stefan Behnel committed
612
    const char *msg;
613
    if ((0)) {
Stefan Behnel's avatar
Stefan Behnel committed
614
    #ifdef __Pyx_Coroutine_USED
615
    } else if (__Pyx_Coroutine_Check((PyObject*)gen)) {
Stefan Behnel's avatar
Stefan Behnel committed
616 617 618 619 620 621 622 623 624 625 626 627 628
        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
629
static void __Pyx__Coroutine_NotStartedError(CYTHON_UNUSED PyObject *gen) {
Stefan Behnel's avatar
Stefan Behnel committed
630
    const char *msg;
631
    if ((0)) {
Stefan Behnel's avatar
Stefan Behnel committed
632
    #ifdef __Pyx_Coroutine_USED
633
    } else if (__Pyx_Coroutine_Check(gen)) {
Stefan Behnel's avatar
Stefan Behnel committed
634 635 636 637 638 639 640 641 642 643 644 645 646
        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
647
static void __Pyx__Coroutine_AlreadyTerminatedError(CYTHON_UNUSED PyObject *gen, PyObject *value, CYTHON_UNUSED int closing) {
Stefan Behnel's avatar
Stefan Behnel committed
648
    #ifdef __Pyx_Coroutine_USED
649
    if (!closing && __Pyx_Coroutine_Check(gen)) {
Stefan Behnel's avatar
Stefan Behnel committed
650 651 652 653 654 655 656 657 658
        // `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().
659
        #ifdef __Pyx_AsyncGen_USED
Stefan Behnel's avatar
Stefan Behnel committed
660 661 662
        if (__Pyx_AsyncGen_CheckExact(gen))
            PyErr_SetNone(__Pyx_PyExc_StopAsyncIteration);
        else
663
        #endif
Stefan Behnel's avatar
Stefan Behnel committed
664
        PyErr_SetNone(PyExc_StopIteration);
665
    }
666 667
}

Stefan Behnel's avatar
Stefan Behnel committed
668 669
static
PyObject *__Pyx_Coroutine_SendEx(__pyx_CoroutineObject *self, PyObject *value, int closing) {
670
    __Pyx_PyThreadState_declare
671
    PyThreadState *tstate;
672
    __Pyx_ExcInfoStruct *exc_state;
673
    PyObject *retval;
674 675

    assert(!self->is_running);
676

677 678
    if (unlikely(self->resume_label == 0)) {
        if (unlikely(value && value != Py_None)) {
Stefan Behnel's avatar
Stefan Behnel committed
679
            return __Pyx_Coroutine_NotStartedError((PyObject*)self);
680 681 682
        }
    }

683
    if (unlikely(self->resume_label == -1)) {
Stefan Behnel's avatar
Stefan Behnel committed
684
        return __Pyx_Coroutine_AlreadyTerminatedError((PyObject*)self, value, closing);
685 686
    }

687
#if CYTHON_FAST_THREAD_STATE
688
    __Pyx_PyThreadState_assign
689 690 691 692 693
    tstate = $local_tstate_cname;
#else
    tstate = __Pyx_PyThreadState_Current;
#endif

694
    // Traceback/Frame rules pre-Py3.7:
695 696
    // - on entry, save external exception state in self->gi_exc_state, restore it on exit
    // - on exit, keep internally generated exceptions in self->gi_exc_state, clear everything else
697 698 699 700
    // - on entry, set "f_back" pointer of internal exception traceback to (current) outer call frame
    // - on exit, clear "f_back" of internal exception traceback
    // - do not touch external frames and tracebacks

701 702 703 704 705 706 707
    // Traceback/Frame rules for Py3.7+ (CYTHON_USE_EXC_INFO_STACK):
    // - on entry, push internal exception state in self->gi_exc_state on the exception stack
    // - on exit, keep internally generated exceptions in self->gi_exc_state, clear everything else
    // - on entry, set "f_back" pointer of internal exception traceback to (current) outer call frame
    // - on exit, clear "f_back" of internal exception traceback
    // - do not touch external frames and tracebacks

708 709 710
    exc_state = &self->gi_exc_state;
    if (exc_state->exc_type) {
        #if CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_PYSTON
711
        // FIXME: what to do in PyPy?
712
        #else
713 714
        // Generators always return to their most recent caller, not
        // necessarily their creator.
715 716
        if (exc_state->exc_traceback) {
            PyTracebackObject *tb = (PyTracebackObject *) exc_state->exc_traceback;
717 718
            PyFrameObject *f = tb->tb_frame;

719
            Py_XINCREF(tstate->frame);
720
            assert(f->f_back == NULL);
721
            f->f_back = tstate->frame;
722
        }
723 724 725 726 727 728 729 730 731
        #endif
    }

#if CYTHON_USE_EXC_INFO_STACK
    // See  https://bugs.python.org/issue25612
    exc_state->previous_item = tstate->exc_info;
    tstate->exc_info = exc_state;
#else
    if (exc_state->exc_type) {
732 733
        // We were in an except handler when we left,
        // restore the exception state which was put aside.
734
        __Pyx_ExceptionSwap(&exc_state->exc_type, &exc_state->exc_value, &exc_state->exc_traceback);
735
        // self->exc_* now holds the exception state of the caller
736
    } else {
737
        // save away the exception state of the caller
738 739
        __Pyx_Coroutine_ExceptionClear(exc_state);
        __Pyx_ExceptionSave(&exc_state->exc_type, &exc_state->exc_value, &exc_state->exc_traceback);
740
    }
741
#endif
742 743

    self->is_running = 1;
744
    retval = self->body(self, tstate, value);
745 746
    self->is_running = 0;

747 748 749 750 751
#if CYTHON_USE_EXC_INFO_STACK
    // See  https://bugs.python.org/issue25612
    exc_state = &self->gi_exc_state;
    tstate->exc_info = exc_state->previous_item;
    exc_state->previous_item = NULL;
752 753
    // Cut off the exception frame chain so that we can reconnect it on re-entry above.
    __Pyx_Coroutine_ResetFrameBackpointer(exc_state);
754 755
#endif

756 757 758
    return retval;
}

759
static CYTHON_INLINE void __Pyx_Coroutine_ResetFrameBackpointer(__Pyx_ExcInfoStruct *exc_state) {
760 761 762
    // 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.
763
    PyObject *exc_tb = exc_state->exc_traceback;
764

765
    if (likely(exc_tb)) {
766 767 768
#if CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_PYSTON
    // FIXME: what to do in PyPy?
#else
769
        PyTracebackObject *tb = (PyTracebackObject *) exc_tb;
770
        PyFrameObject *f = tb->tb_frame;
771
        Py_CLEAR(f->f_back);
772
#endif
773
    }
774 775
}

776
static CYTHON_INLINE
777
PyObject *__Pyx_Coroutine_MethodReturn(CYTHON_UNUSED PyObject* gen, PyObject *retval) {
778 779 780 781 782 783 784 785 786 787 788 789
    if (unlikely(!retval)) {
        __Pyx_PyThreadState_declare
        __Pyx_PyThreadState_assign
        if (!__Pyx_PyErr_Occurred()) {
            // method call must not terminate with NULL without setting an exception
            PyObject *exc = PyExc_StopIteration;
            #ifdef __Pyx_AsyncGen_USED
            if (__Pyx_AsyncGen_CheckExact(gen))
                exc = __Pyx_PyExc_StopAsyncIteration;
            #endif
            __Pyx_PyErr_SetNone(exc);
        }
790 791 792 793
    }
    return retval;
}

794
static CYTHON_INLINE
795
PyObject *__Pyx_Coroutine_FinishDelegation(__pyx_CoroutineObject *gen) {
796 797
    PyObject *ret;
    PyObject *val = NULL;
798
    __Pyx_Coroutine_Undelegate(gen);
799
    __Pyx_PyGen__FetchStopIterationValue(__Pyx_PyThreadState_Current, &val);
800
    // val == NULL on failure => pass on exception
801
    ret = __Pyx_Coroutine_SendEx(gen, val, 0);
802 803
    Py_XDECREF(val);
    return ret;
804 805
}

806
static PyObject *__Pyx_Coroutine_Send(PyObject *self, PyObject *value) {
807
    PyObject *retval;
808
    __pyx_CoroutineObject *gen = (__pyx_CoroutineObject*) self;
809
    PyObject *yf = gen->yieldfrom;
Stefan Behnel's avatar
Stefan Behnel committed
810 811
    if (unlikely(gen->is_running))
        return __Pyx_Coroutine_AlreadyRunningError(gen);
812 813 814 815 816
    if (yf) {
        PyObject *ret;
        // FIXME: does this really need an INCREF() ?
        //Py_INCREF(yf);
        gen->is_running = 1;
817
        #ifdef __Pyx_Generator_USED
818
        if (__Pyx_Generator_CheckExact(yf)) {
819 820 821 822
            ret = __Pyx_Coroutine_Send(yf, value);
        } else
        #endif
        #ifdef __Pyx_Coroutine_USED
823
        if (__Pyx_Coroutine_Check(yf)) {
824 825 826
            ret = __Pyx_Coroutine_Send(yf, value);
        } else
        #endif
827 828
        #ifdef __Pyx_AsyncGen_USED
        if (__pyx_PyAsyncGenASend_CheckExact(yf)) {
829
            ret = __Pyx_async_gen_asend_send(yf, value);
830 831
        } else
        #endif
832
        #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x03030000 && (defined(__linux__) || PY_VERSION_HEX >= 0x030600B3)
833
        // _PyGen_Send() is not exported before Py3.6
834 835 836 837
        if (PyGen_CheckExact(yf)) {
            ret = _PyGen_Send((PyGenObject*)yf, value == Py_None ? NULL : value);
        } else
        #endif
838
        #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x03050000 && defined(PyCoro_CheckExact) && (defined(__linux__) || PY_VERSION_HEX >= 0x030600B3)
839
        // _PyGen_Send() is not exported before Py3.6
840 841 842 843
        if (PyCoro_CheckExact(yf)) {
            ret = _PyGen_Send((PyGenObject*)yf, value == Py_None ? NULL : value);
        } else
        #endif
844
        {
845
            if (value == Py_None)
846
                ret = Py_TYPE(yf)->tp_iternext(yf);
847
            else
848
                ret = __Pyx_PyObject_CallMethod1(yf, PYIDENT("send"), value);
849 850 851 852 853 854
        }
        gen->is_running = 0;
        //Py_DECREF(yf);
        if (likely(ret)) {
            return ret;
        }
855
        retval = __Pyx_Coroutine_FinishDelegation(gen);
856
    } else {
857
        retval = __Pyx_Coroutine_SendEx(gen, value, 0);
858
    }
859
    return __Pyx_Coroutine_MethodReturn(self, retval);
860 861 862 863
}

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

868
    #ifdef __Pyx_Generator_USED
869
    if (__Pyx_Generator_CheckExact(yf)) {
870
        retval = __Pyx_Coroutine_Close(yf);
871 872
        if (!retval)
            return -1;
873 874 875
    } else
    #endif
    #ifdef __Pyx_Coroutine_USED
876
    if (__Pyx_Coroutine_Check(yf)) {
877 878 879 880
        retval = __Pyx_Coroutine_Close(yf);
        if (!retval)
            return -1;
    } else
881
    if (__Pyx_CoroutineAwait_CheckExact(yf)) {
882
        retval = __Pyx_CoroutineAwait_Close((__pyx_CoroutineAwaitObject*)yf, NULL);
883 884 885 886 887 888 889 890 891 892 893 894 895
        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
896 897
    #endif
    {
898 899
        PyObject *meth;
        gen->is_running = 1;
900
        meth = __Pyx_PyObject_GetAttrStrNoError(yf, PYIDENT("close"));
901
        if (unlikely(!meth)) {
902
            if (unlikely(PyErr_Occurred())) {
903 904 905
                PyErr_WriteUnraisable(yf);
            }
        } else {
906
            retval = PyObject_CallFunction(meth, NULL);
907
            Py_DECREF(meth);
908
            if (unlikely(!retval))
909 910 911 912 913 914 915 916
                err = -1;
        }
        gen->is_running = 0;
    }
    Py_XDECREF(retval);
    return err;
}

917 918 919
static PyObject *__Pyx_Generator_Next(PyObject *self) {
    __pyx_CoroutineObject *gen = (__pyx_CoroutineObject*) self;
    PyObject *yf = gen->yieldfrom;
Stefan Behnel's avatar
Stefan Behnel committed
920 921
    if (unlikely(gen->is_running))
        return __Pyx_Coroutine_AlreadyRunningError(gen);
922 923 924 925 926 927
    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;
928 929 930 931
        #ifdef __Pyx_Generator_USED
        if (__Pyx_Generator_CheckExact(yf)) {
            ret = __Pyx_Generator_Next(yf);
        } else
932
        #endif
933
        #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x03030000 && (defined(__linux__) || PY_VERSION_HEX >= 0x030600B3)
934
        // _PyGen_Send() is not exported before Py3.6
935 936 937
        if (PyGen_CheckExact(yf)) {
            ret = _PyGen_Send((PyGenObject*)yf, NULL);
        } else
Yury Selivanov's avatar
Yury Selivanov committed
938 939 940 941 942
        #endif
        #ifdef __Pyx_Coroutine_USED
        if (__Pyx_Coroutine_Check(yf)) {
            ret = __Pyx_Coroutine_Send(yf, Py_None);
        } else
943 944
        #endif
            ret = Py_TYPE(yf)->tp_iternext(yf);
945 946 947 948 949 950 951
        gen->is_running = 0;
        //Py_DECREF(yf);
        if (likely(ret)) {
            return ret;
        }
        return __Pyx_Coroutine_FinishDelegation(gen);
    }
952
    return __Pyx_Coroutine_SendEx(gen, Py_None, 0);
953 954
}

955 956 957 958
static PyObject *__Pyx_Coroutine_Close_Method(PyObject *self, CYTHON_UNUSED PyObject *arg) {
    return __Pyx_Coroutine_Close(self);
}

959 960
static PyObject *__Pyx_Coroutine_Close(PyObject *self) {
    __pyx_CoroutineObject *gen = (__pyx_CoroutineObject *) self;
961 962 963 964
    PyObject *retval, *raised_exception;
    PyObject *yf = gen->yieldfrom;
    int err = 0;

Stefan Behnel's avatar
Stefan Behnel committed
965 966
    if (unlikely(gen->is_running))
        return __Pyx_Coroutine_AlreadyRunningError(gen);
967 968 969

    if (yf) {
        Py_INCREF(yf);
970 971
        err = __Pyx_Coroutine_CloseIter(gen, yf);
        __Pyx_Coroutine_Undelegate(gen);
972 973 974 975
        Py_DECREF(yf);
    }
    if (err == 0)
        PyErr_SetNone(PyExc_GeneratorExit);
976
    retval = __Pyx_Coroutine_SendEx(gen, NULL, 1);
977
    if (unlikely(retval)) {
978
        const char *msg;
979
        Py_DECREF(retval);
980
        if ((0)) {
981
        #ifdef __Pyx_Coroutine_USED
982
        } else if (__Pyx_Coroutine_Check(self)) {
983 984 985 986
            msg = "coroutine ignored GeneratorExit";
        #endif
        #ifdef __Pyx_AsyncGen_USED
        } else if (__Pyx_AsyncGen_CheckExact(self)) {
987 988 989
#if PY_VERSION_HEX < 0x03060000
            msg = "async generator ignored GeneratorExit - might require Python 3.6+ finalisation (PEP 525)";
#else
990
            msg = "async generator ignored GeneratorExit";
991
#endif
992 993 994 995 996
        #endif
        } else {
            msg = "generator ignored GeneratorExit";
        }
        PyErr_SetString(PyExc_RuntimeError, msg);
997 998
        return NULL;
    }
999
    raised_exception = PyErr_Occurred();
1000
    if (likely(!raised_exception || __Pyx_PyErr_GivenExceptionMatches2(raised_exception, PyExc_GeneratorExit, PyExc_StopIteration))) {
1001 1002
        // ignore these errors
        if (raised_exception) PyErr_Clear();
1003 1004 1005 1006 1007 1008
        Py_INCREF(Py_None);
        return Py_None;
    }
    return NULL;
}

1009 1010
static PyObject *__Pyx__Coroutine_Throw(PyObject *self, PyObject *typ, PyObject *val, PyObject *tb,
                                        PyObject *args, int close_on_genexit) {
1011
    __pyx_CoroutineObject *gen = (__pyx_CoroutineObject *) self;
1012
    PyObject *yf = gen->yieldfrom;
1013

Stefan Behnel's avatar
Stefan Behnel committed
1014 1015
    if (unlikely(gen->is_running))
        return __Pyx_Coroutine_AlreadyRunningError(gen);
1016 1017 1018 1019

    if (yf) {
        PyObject *ret;
        Py_INCREF(yf);
1020
        if (__Pyx_PyErr_GivenExceptionMatches(typ, PyExc_GeneratorExit) && close_on_genexit) {
1021 1022 1023
            // 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.
1024
            int err = __Pyx_Coroutine_CloseIter(gen, yf);
1025
            Py_DECREF(yf);
1026
            __Pyx_Coroutine_Undelegate(gen);
1027
            if (err < 0)
1028
                return __Pyx_Coroutine_MethodReturn(self, __Pyx_Coroutine_SendEx(gen, NULL, 0));
1029 1030 1031
            goto throw_here;
        }
        gen->is_running = 1;
1032
        if (0
1033
        #ifdef __Pyx_Generator_USED
1034
            || __Pyx_Generator_CheckExact(yf)
1035 1036
        #endif
        #ifdef __Pyx_Coroutine_USED
1037
            || __Pyx_Coroutine_Check(yf)
1038 1039 1040
        #endif
            ) {
            ret = __Pyx__Coroutine_Throw(yf, typ, val, tb, args, close_on_genexit);
1041 1042 1043 1044
        #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
1045
        } else {
1046
            PyObject *meth = __Pyx_PyObject_GetAttrStrNoError(yf, PYIDENT("throw"));
1047 1048
            if (unlikely(!meth)) {
                Py_DECREF(yf);
1049
                if (unlikely(PyErr_Occurred())) {
1050 1051 1052
                    gen->is_running = 0;
                    return NULL;
                }
1053
                __Pyx_Coroutine_Undelegate(gen);
1054 1055 1056
                gen->is_running = 0;
                goto throw_here;
            }
1057 1058 1059 1060 1061 1062
            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);
            }
1063 1064 1065 1066 1067
            Py_DECREF(meth);
        }
        gen->is_running = 0;
        Py_DECREF(yf);
        if (!ret) {
1068
            ret = __Pyx_Coroutine_FinishDelegation(gen);
1069
        }
1070
        return __Pyx_Coroutine_MethodReturn(self, ret);
1071 1072
    }
throw_here:
1073
    __Pyx_Raise(typ, val, tb, NULL);
1074
    return __Pyx_Coroutine_MethodReturn(self, __Pyx_Coroutine_SendEx(gen, NULL, 0));
1075 1076
}

1077 1078 1079 1080
static PyObject *__Pyx_Coroutine_Throw(PyObject *self, PyObject *args) {
    PyObject *typ;
    PyObject *val = NULL;
    PyObject *tb = NULL;
1081

1082
    if (unlikely(!PyArg_UnpackTuple(args, (char *)"throw", 1, 3, &typ, &val, &tb)))
1083 1084 1085 1086 1087
        return NULL;

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

1088 1089 1090 1091 1092 1093 1094
static CYTHON_INLINE int __Pyx_Coroutine_traverse_excstate(__Pyx_ExcInfoStruct *exc_state, visitproc visit, void *arg) {
    Py_VISIT(exc_state->exc_type);
    Py_VISIT(exc_state->exc_value);
    Py_VISIT(exc_state->exc_traceback);
    return 0;
}

1095
static int __Pyx_Coroutine_traverse(__pyx_CoroutineObject *gen, visitproc visit, void *arg) {
1096 1097
    Py_VISIT(gen->closure);
    Py_VISIT(gen->classobj);
1098
    Py_VISIT(gen->yieldfrom);
1099
    return __Pyx_Coroutine_traverse_excstate(&gen->gi_exc_state, visit, arg);
1100 1101
}

1102 1103
static int __Pyx_Coroutine_clear(PyObject *self) {
    __pyx_CoroutineObject *gen = (__pyx_CoroutineObject *) self;
1104 1105 1106 1107

    Py_CLEAR(gen->closure);
    Py_CLEAR(gen->classobj);
    Py_CLEAR(gen->yieldfrom);
1108
    __Pyx_Coroutine_ExceptionClear(&gen->gi_exc_state);
1109 1110
#ifdef __Pyx_AsyncGen_USED
    if (__Pyx_AsyncGen_CheckExact(self)) {
1111
        Py_CLEAR(((__pyx_PyAsyncGenObject*)gen)->ag_finalizer);
1112 1113
    }
#endif
1114
    Py_CLEAR(gen->gi_code);
1115
    Py_CLEAR(gen->gi_frame);
1116 1117
    Py_CLEAR(gen->gi_name);
    Py_CLEAR(gen->gi_qualname);
1118
    Py_CLEAR(gen->gi_modulename);
1119 1120 1121
    return 0;
}

1122 1123
static void __Pyx_Coroutine_dealloc(PyObject *self) {
    __pyx_CoroutineObject *gen = (__pyx_CoroutineObject *) self;
1124

1125 1126 1127 1128
    PyObject_GC_UnTrack(gen);
    if (gen->gi_weakreflist != NULL)
        PyObject_ClearWeakRefs(self);

1129 1130
    if (gen->resume_label >= 0) {
        // Generator is paused or unstarted, so we need to close
1131
        PyObject_GC_Track(self);
1132
#if PY_VERSION_HEX >= 0x030400a1 && CYTHON_USE_TP_FINALIZE
1133
        if (unlikely(PyObject_CallFinalizerFromDealloc(self)))
1134
#else
1135
        Py_TYPE(gen)->tp_del(self);
1136
        if (unlikely(self->ob_refcnt > 0))
1137
#endif
1138 1139 1140 1141
        {
            // resurrected.  :(
            return;
        }
1142
        PyObject_GC_UnTrack(self);
1143 1144
    }

1145 1146 1147 1148 1149 1150 1151 1152
#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
1153
    __Pyx_Coroutine_clear(self);
1154 1155 1156
    PyObject_GC_Del(gen);
}

1157
static void __Pyx_Coroutine_del(PyObject *self) {
1158
    PyObject *error_type, *error_value, *error_traceback;
1159
    __pyx_CoroutineObject *gen = (__pyx_CoroutineObject *) self;
1160
    __Pyx_PyThreadState_declare
1161

1162
    if (gen->resume_label < 0) {
Stefan Behnel's avatar
Stefan Behnel committed
1163
        // already terminated => nothing to clean up
1164 1165
        return;
    }
1166

1167
#if !CYTHON_USE_TP_FINALIZE
1168
    // Temporarily resurrect the object.
1169 1170
    assert(self->ob_refcnt == 0);
    self->ob_refcnt = 1;
1171
#endif
1172

1173
    __Pyx_PyThreadState_assign
1174

1175 1176 1177
    // Save the current exception, if any.
    __Pyx_ErrFetch(&error_type, &error_value, &error_traceback);

1178 1179 1180 1181 1182
#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) {
1183 1184
            PyObject *res = __Pyx_PyObject_CallOneArg(finalizer, self);
            if (unlikely(!res)) {
1185 1186 1187 1188
                PyErr_WriteUnraisable(self);
            } else {
                Py_DECREF(res);
            }
1189
            // Restore the saved exception.
1190 1191 1192 1193 1194 1195
            __Pyx_ErrRestore(error_type, error_value, error_traceback);
            return;
        }
    }
#endif

1196
    if (unlikely(gen->resume_label == 0 && !error_value)) {
1197 1198 1199 1200 1201 1202
#ifdef __Pyx_Coroutine_USED
#ifdef __Pyx_Generator_USED
    // only warn about (async) coroutines
    if (!__Pyx_Generator_CheckExact(self))
#endif
        {
1203 1204
        // untrack dead object as we are executing Python code (which might trigger GC)
        PyObject_GC_UnTrack(self);
1205
#if PY_MAJOR_VERSION >= 3 /* PY_VERSION_HEX >= 0x03030000*/ || defined(PyErr_WarnFormat)
1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218
        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;
        qualname = gen->gi_qualname;
        cname = PyString_AS_STRING(qualname);
1219
        msg = PyString_FromFormat("coroutine '%.50s' was never awaited", cname);
1220

1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232
        if (unlikely(!msg)) {
            PyErr_Clear();
            cmsg = (char*) "coroutine was never awaited";
        } else {
            cmsg = PyString_AS_STRING(msg);
        }
        #endif
        if (unlikely(PyErr_WarnEx(PyExc_RuntimeWarning, cmsg, 1) < 0))
            PyErr_WriteUnraisable(self);
        Py_XDECREF(msg);}
#endif
        PyObject_GC_Track(self);
1233 1234
        }
#endif /*__Pyx_Coroutine_USED*/
1235 1236 1237 1238 1239 1240 1241 1242 1243
    } else {
        PyObject *res = __Pyx_Coroutine_Close(self);
        if (unlikely(!res)) {
            if (PyErr_Occurred())
                PyErr_WriteUnraisable(self);
        } else {
            Py_DECREF(res);
        }
    }
1244

1245
    // Restore the saved exception.
1246 1247
    __Pyx_ErrRestore(error_type, error_value, error_traceback);

1248
#if !CYTHON_USE_TP_FINALIZE
1249 1250
    // Undo the temporary resurrection; can't use DECREF here, it would
    // cause a recursive call.
1251
    assert(self->ob_refcnt > 0);
1252
    if (likely(--self->ob_refcnt == 0)) {
1253 1254 1255
        // this is the normal path out
        return;
    }
1256

1257 1258
    // close() resurrected it!  Make it look like the original Py_DECREF
    // never happened.
1259 1260 1261 1262 1263
    {
        Py_ssize_t refcnt = self->ob_refcnt;
        _Py_NewReference(self);
        self->ob_refcnt = refcnt;
    }
1264
#if CYTHON_COMPILING_IN_CPYTHON
1265 1266 1267
    assert(PyType_IS_GC(self->ob_type) &&
           _Py_AS_GC(self)->gc.gc_refs != _PyGC_REFS_UNTRACKED);

1268 1269
    // If Py_REF_DEBUG, _Py_NewReference bumped _Py_RefTotal, so
    // we need to undo that.
1270
    _Py_DEC_REFTOTAL;
1271
#endif
1272 1273 1274 1275 1276
    // 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.
1277
#ifdef COUNT_ALLOCS
1278 1279
    --Py_TYPE(self)->tp_frees;
    --Py_TYPE(self)->tp_allocs;
1280
#endif
1281
#endif
1282
}
1283

1284
static PyObject *
1285
__Pyx_Coroutine_get_name(__pyx_CoroutineObject *self, CYTHON_UNUSED void *context)
1286
{
1287 1288 1289 1290 1291
    PyObject *name = self->gi_name;
    // avoid NULL pointer dereference during garbage collection
    if (unlikely(!name)) name = Py_None;
    Py_INCREF(name);
    return name;
1292 1293 1294
}

static int
1295
__Pyx_Coroutine_set_name(__pyx_CoroutineObject *self, PyObject *value, CYTHON_UNUSED void *context)
1296 1297
{
#if PY_MAJOR_VERSION >= 3
1298
    if (unlikely(value == NULL || !PyUnicode_Check(value)))
1299
#else
1300
    if (unlikely(value == NULL || !PyString_Check(value)))
1301
#endif
1302
    {
1303 1304 1305 1306 1307
        PyErr_SetString(PyExc_TypeError,
                        "__name__ must be set to a string object");
        return -1;
    }
    Py_INCREF(value);
1308
    __Pyx_Py_XDECREF_SET(self->gi_name, value);
1309 1310 1311 1312
    return 0;
}

static PyObject *
1313
__Pyx_Coroutine_get_qualname(__pyx_CoroutineObject *self, CYTHON_UNUSED void *context)
1314
{
1315 1316 1317 1318 1319
    PyObject *name = self->gi_qualname;
    // avoid NULL pointer dereference during garbage collection
    if (unlikely(!name)) name = Py_None;
    Py_INCREF(name);
    return name;
1320 1321 1322
}

static int
1323
__Pyx_Coroutine_set_qualname(__pyx_CoroutineObject *self, PyObject *value, CYTHON_UNUSED void *context)
1324 1325
{
#if PY_MAJOR_VERSION >= 3
1326
    if (unlikely(value == NULL || !PyUnicode_Check(value)))
1327
#else
1328
    if (unlikely(value == NULL || !PyString_Check(value)))
1329
#endif
1330
    {
1331 1332 1333 1334 1335
        PyErr_SetString(PyExc_TypeError,
                        "__qualname__ must be set to a string object");
        return -1;
    }
    Py_INCREF(value);
1336
    __Pyx_Py_XDECREF_SET(self->gi_qualname, value);
1337 1338 1339
    return 0;
}

1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363
static PyObject *
__Pyx_Coroutine_get_frame(__pyx_CoroutineObject *self, CYTHON_UNUSED void *context)
{
    PyObject *frame = self->gi_frame;
    if (!frame) {
        if (unlikely(!self->gi_code)) {
            // Avoid doing something stupid, e.g. during garbage collection.
            Py_RETURN_NONE;
        }
        frame = (PyObject *) PyFrame_New(
            PyThreadState_Get(),            /*PyThreadState *tstate,*/
            (PyCodeObject*) self->gi_code,  /*PyCodeObject *code,*/
            $moddict_cname,                 /*PyObject *globals,*/
            0                               /*PyObject *locals*/
        );
        if (unlikely(!frame))
            return NULL;
        // keep the frame cached once it's created
        self->gi_frame = frame;
    }
    Py_INCREF(frame);
    return frame;
}

1364
static __pyx_CoroutineObject *__Pyx__Coroutine_New(
1365
            PyTypeObject* type, __pyx_coroutine_body_t body, PyObject *code, PyObject *closure,
1366
            PyObject *name, PyObject *qualname, PyObject *module_name) {
1367
    __pyx_CoroutineObject *gen = PyObject_GC_New(__pyx_CoroutineObject, type);
1368
    if (unlikely(!gen))
1369
        return NULL;
1370
    return __Pyx__Coroutine_NewInit(gen, body, code, closure, name, qualname, module_name);
1371
}
1372

1373
static __pyx_CoroutineObject *__Pyx__Coroutine_NewInit(
1374
            __pyx_CoroutineObject *gen, __pyx_coroutine_body_t body, PyObject *code, PyObject *closure,
1375
            PyObject *name, PyObject *qualname, PyObject *module_name) {
1376 1377 1378 1379 1380 1381 1382
    gen->body = body;
    gen->closure = closure;
    Py_XINCREF(closure);
    gen->is_running = 0;
    gen->resume_label = 0;
    gen->classobj = NULL;
    gen->yieldfrom = NULL;
1383 1384 1385 1386 1387 1388
    gen->gi_exc_state.exc_type = NULL;
    gen->gi_exc_state.exc_value = NULL;
    gen->gi_exc_state.exc_traceback = NULL;
#if CYTHON_USE_EXC_INFO_STACK
    gen->gi_exc_state.previous_item = NULL;
#endif
1389 1390 1391 1392 1393
    gen->gi_weakreflist = NULL;
    Py_XINCREF(qualname);
    gen->gi_qualname = qualname;
    Py_XINCREF(name);
    gen->gi_name = name;
1394 1395
    Py_XINCREF(module_name);
    gen->gi_modulename = module_name;
1396 1397
    Py_XINCREF(code);
    gen->gi_code = code;
1398
    gen->gi_frame = NULL;
1399 1400 1401 1402 1403 1404 1405 1406 1407

    PyObject_GC_Track(gen);
    return gen;
}


//////////////////// Coroutine ////////////////////
//@requires: CoroutineBase
//@requires: PatchGeneratorABC
1408
//@requires: ObjectHandling.c::PyObject_GenericGetAttrNoDict
1409

1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437
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);
}

1438
static PyObject *__Pyx_CoroutineAwait_Close(__pyx_CoroutineAwaitObject *self, CYTHON_UNUSED PyObject *arg) {
1439 1440 1441 1442 1443 1444 1445 1446
    return __Pyx_Coroutine_Close(self->coroutine);
}

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

1447
#if !CYTHON_COMPILING_IN_PYPY
1448
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
1449
    PyErr_SetString(PyExc_TypeError, "cannot instantiate type, use 'await coroutine' instead");
1450 1451
    return NULL;
}
1452
#endif
1453 1454

static PyMethodDef __pyx_CoroutineAwait_methods[] = {
1455 1456 1457 1458 1459 1460
    {"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.")},
1461 1462 1463 1464 1465
    {0, 0, 0, 0}
};

static PyTypeObject __pyx_CoroutineAwaitType_type = {
    PyVarObject_HEAD_INIT(0, 0)
1466
    "coroutine_wrapper",                /*tp_name*/
1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501
    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*/
1502
#if !CYTHON_COMPILING_IN_PYPY
1503
    __Pyx_CoroutineAwait_no_new,        /*tp_new*/
1504 1505 1506
#else
    0,                                  /*tp_new*/
#endif
1507 1508 1509 1510 1511 1512 1513 1514 1515
    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*/
1516
#if PY_VERSION_HEX >= 0x030400a1
1517 1518
    0,                                  /*tp_finalize*/
#endif
1519 1520 1521
#if PY_VERSION_HEX >= 0x030800b1
    0,                                  /*tp_vectorcall*/
#endif
1522 1523 1524
#if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000
    0,                                  /*tp_print*/
#endif
1525 1526
};

Stefan Behnel's avatar
Stefan Behnel committed
1527
#if PY_VERSION_HEX < 0x030500B1 || defined(__Pyx_IterableCoroutine_USED) || CYTHON_USE_ASYNC_SLOTS
1528 1529 1530 1531 1532
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;
1533
    PyObject_GC_Track(await);
1534 1535
    return (PyObject*)await;
}
1536
#endif
1537

1538 1539 1540 1541 1542 1543
#if PY_VERSION_HEX < 0x030500B1
static PyObject *__Pyx_Coroutine_await_method(PyObject *coroutine, CYTHON_UNUSED PyObject *arg) {
    return __Pyx__Coroutine_await(coroutine);
}
#endif

Stefan Behnel's avatar
Stefan Behnel committed
1544
#if defined(__Pyx_IterableCoroutine_USED) || CYTHON_USE_ASYNC_SLOTS
1545
static PyObject *__Pyx_Coroutine_await(PyObject *coroutine) {
1546
    if (unlikely(!coroutine || !__Pyx_Coroutine_Check(coroutine))) {
1547 1548 1549 1550 1551
        PyErr_SetString(PyExc_TypeError, "invalid input, expected coroutine");
        return NULL;
    }
    return __Pyx__Coroutine_await(coroutine);
}
1552
#endif
1553

1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567
#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

1568
static PyMethodDef __pyx_Coroutine_methods[] = {
1569
    {"send", (PyCFunction) __Pyx_Coroutine_Send, METH_O,
1570
     (char*) PyDoc_STR("send(arg) -> send 'arg' into coroutine,\nreturn next iterated value or raise StopIteration.")},
1571
    {"throw", (PyCFunction) __Pyx_Coroutine_Throw, METH_VARARGS,
1572
     (char*) PyDoc_STR("throw(typ[,val[,tb]]) -> raise exception in coroutine,\nreturn next iterated value or raise StopIteration.")},
1573
    {"close", (PyCFunction) __Pyx_Coroutine_Close_Method, METH_NOARGS,
1574
     (char*) PyDoc_STR("close() -> raise GeneratorExit inside coroutine.")},
1575
#if PY_VERSION_HEX < 0x030500B1
1576
    {"__await__", (PyCFunction) __Pyx_Coroutine_await_method, METH_NOARGS,
1577
     (char*) PyDoc_STR("__await__() -> return an iterator to be used in await expression.")},
1578 1579 1580 1581
#endif
    {0, 0, 0, 0}
};

1582 1583
static PyMemberDef __pyx_Coroutine_memberlist[] = {
    {(char *) "cr_running", T_BOOL, offsetof(__pyx_CoroutineObject, is_running), READONLY, NULL},
1584
    {(char*) "cr_await", T_OBJECT, offsetof(__pyx_CoroutineObject, yieldfrom), READONLY,
1585
     (char*) PyDoc_STR("object being awaited, or None")},
1586
    {(char*) "cr_code", T_OBJECT, offsetof(__pyx_CoroutineObject, gi_code), READONLY, NULL},
1587
    {(char *) "__module__", T_OBJECT, offsetof(__pyx_CoroutineObject, gi_modulename), PY_WRITE_RESTRICTED, 0},
1588 1589 1590 1591 1592 1593 1594 1595
    {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},
1596 1597
    {(char *) "cr_frame", (getter)__Pyx_Coroutine_get_frame, NULL,
     (char*) PyDoc_STR("Frame of the coroutine"), 0},
1598 1599 1600
    {0, 0, 0, 0, 0}
};

1601
#if CYTHON_USE_ASYNC_SLOTS
1602
static __Pyx_PyAsyncMethodsStruct __pyx_Coroutine_as_async = {
Stefan Behnel's avatar
Stefan Behnel committed
1603
    __Pyx_Coroutine_await, /*am_await*/
1604 1605
    0, /*am_aiter*/
    0, /*am_anext*/
1606
};
1607 1608
#endif

1609
static PyTypeObject __pyx_CoroutineType_type = {
1610
    PyVarObject_HEAD_INIT(0, 0)
1611 1612
    "coroutine",                        /*tp_name*/
    sizeof(__pyx_CoroutineObject),      /*tp_basicsize*/
1613
    0,                                  /*tp_itemsize*/
1614
    (destructor) __Pyx_Coroutine_dealloc,/*tp_dealloc*/
1615 1616 1617
    0,                                  /*tp_print*/
    0,                                  /*tp_getattr*/
    0,                                  /*tp_setattr*/
1618 1619
#if CYTHON_USE_ASYNC_SLOTS
    &__pyx_Coroutine_as_async,          /*tp_as_async (tp_reserved) - Py3 only! */
1620
#else
1621
    0,                                  /*tp_reserved*/
1622
#endif
1623
    0,                                  /*tp_repr*/
1624 1625 1626 1627 1628 1629
    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
1630
    0,                                  /*tp_getattro*/
1631 1632
    0,                                  /*tp_setattro*/
    0,                                  /*tp_as_buffer*/
1633
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
1634
    0,                                  /*tp_doc*/
1635
    (traverseproc) __Pyx_Coroutine_traverse,   /*tp_traverse*/
1636
    0,                                  /*tp_clear*/
1637
#if CYTHON_USE_ASYNC_SLOTS && CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3 && PY_VERSION_HEX < 0x030500B1
1638 1639 1640
    // in order to (mis-)use tp_reserved above, we must also implement tp_richcompare
    __Pyx_Coroutine_compare,            /*tp_richcompare*/
#else
1641
    0,                                  /*tp_richcompare*/
1642
#endif
1643
    offsetof(__pyx_CoroutineObject, gi_weakreflist), /*tp_weaklistoffset*/
Stefan Behnel's avatar
Stefan Behnel committed
1644
    // no tp_iter() as iterator is only available through __await__()
Stefan Behnel's avatar
Stefan Behnel committed
1645
    0,                                  /*tp_iter*/
1646
    0,                                  /*tp_iternext*/
1647 1648 1649
    __pyx_Coroutine_methods,            /*tp_methods*/
    __pyx_Coroutine_memberlist,         /*tp_members*/
    __pyx_Coroutine_getsets,            /*tp_getset*/
1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664
    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*/
1665
#if CYTHON_USE_TP_FINALIZE
1666 1667
    0,                                  /*tp_del*/
#else
1668
    __Pyx_Coroutine_del,                /*tp_del*/
1669
#endif
1670
    0,                                  /*tp_version_tag*/
1671
#if CYTHON_USE_TP_FINALIZE
1672
    __Pyx_Coroutine_del,                /*tp_finalize*/
1673 1674
#elif PY_VERSION_HEX >= 0x030400a1
    0,                                  /*tp_finalize*/
1675
#endif
1676 1677 1678
#if PY_VERSION_HEX >= 0x030800b1
    0,                                  /*tp_vectorcall*/
#endif
1679 1680 1681
#if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000
    0,                                  /*tp_print*/
#endif
1682 1683
};

1684
static int __pyx_Coroutine_init(void) {
1685
    // on Windows, C-API functions can't be used in slots statically
1686
    __pyx_CoroutineType_type.tp_getattro = __Pyx_PyObject_GenericGetAttrNoDict;
1687 1688 1689
    __pyx_CoroutineType = __Pyx_FetchCommonType(&__pyx_CoroutineType_type);
    if (unlikely(!__pyx_CoroutineType))
        return -1;
1690

1691
#ifdef __Pyx_IterableCoroutine_USED
1692
    if (unlikely(__pyx_IterableCoroutine_init() == -1))
1693 1694 1695
        return -1;
#endif

1696 1697
    __pyx_CoroutineAwaitType = __Pyx_FetchCommonType(&__pyx_CoroutineAwaitType_type);
    if (unlikely(!__pyx_CoroutineAwaitType))
1698 1699 1700
        return -1;
    return 0;
}
1701

1702 1703 1704 1705 1706 1707 1708 1709

//////////////////// IterableCoroutine.proto ////////////////////

#define __Pyx_IterableCoroutine_USED

static PyTypeObject *__pyx_IterableCoroutineType = 0;

#undef __Pyx_Coroutine_Check
1710
#define __Pyx_Coroutine_Check(obj) (__Pyx_Coroutine_CheckExact(obj) || __Pyx_IS_TYPE(obj, __pyx_IterableCoroutineType))
1711

Yury Selivanov's avatar
Yury Selivanov committed
1712 1713
#define __Pyx_IterableCoroutine_New(body, code, closure, name, qualname, module_name)  \
    __Pyx__Coroutine_New(__pyx_IterableCoroutineType, body, code, closure, name, qualname, module_name)
1714

1715 1716
static int __pyx_IterableCoroutine_init(void);/*proto*/

1717 1718 1719

//////////////////// IterableCoroutine ////////////////////
//@requires: Coroutine
1720
//@requires: CommonStructures.c::FetchCommonType
1721 1722 1723

static PyTypeObject __pyx_IterableCoroutineType_type = {
    PyVarObject_HEAD_INIT(0, 0)
1724
    "iterable_coroutine",               /*tp_name*/
1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786
    sizeof(__pyx_CoroutineObject),      /*tp_basicsize*/
    0,                                  /*tp_itemsize*/
    (destructor) __Pyx_Coroutine_dealloc,/*tp_dealloc*/
    0,                                  /*tp_print*/
    0,                                  /*tp_getattr*/
    0,                                  /*tp_setattr*/
#if CYTHON_USE_ASYNC_SLOTS
    &__pyx_Coroutine_as_async,          /*tp_as_async (tp_reserved) - Py3 only! */
#else
    0,                                  /*tp_reserved*/
#endif
    0,                                  /*tp_repr*/
    0,                                  /*tp_as_number*/
    0,                                  /*tp_as_sequence*/
    0,                                  /*tp_as_mapping*/
    0,                                  /*tp_hash*/
    0,                                  /*tp_call*/
    0,                                  /*tp_str*/
    0,                                  /*tp_getattro*/
    0,                                  /*tp_setattro*/
    0,                                  /*tp_as_buffer*/
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
    0,                                  /*tp_doc*/
    (traverseproc) __Pyx_Coroutine_traverse,   /*tp_traverse*/
    0,                                  /*tp_clear*/
#if CYTHON_USE_ASYNC_SLOTS && CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3 && PY_VERSION_HEX < 0x030500B1
    // in order to (mis-)use tp_reserved above, we must also implement tp_richcompare
    __Pyx_Coroutine_compare,            /*tp_richcompare*/
#else
    0,                                  /*tp_richcompare*/
#endif
    offsetof(__pyx_CoroutineObject, gi_weakreflist), /*tp_weaklistoffset*/
    // enable iteration for legacy support of asyncio yield-from protocol
    __Pyx_Coroutine_await,              /*tp_iter*/
    (iternextfunc) __Pyx_Generator_Next, /*tp_iternext*/
    __pyx_Coroutine_methods,            /*tp_methods*/
    __pyx_Coroutine_memberlist,         /*tp_members*/
    __pyx_Coroutine_getsets,            /*tp_getset*/
    0,                                  /*tp_base*/
    0,                                  /*tp_dict*/
    0,                                  /*tp_descr_get*/
    0,                                  /*tp_descr_set*/
    0,                                  /*tp_dictoffset*/
    0,                                  /*tp_init*/
    0,                                  /*tp_alloc*/
    0,                                  /*tp_new*/
    0,                                  /*tp_free*/
    0,                                  /*tp_is_gc*/
    0,                                  /*tp_bases*/
    0,                                  /*tp_mro*/
    0,                                  /*tp_cache*/
    0,                                  /*tp_subclasses*/
    0,                                  /*tp_weaklist*/
#if PY_VERSION_HEX >= 0x030400a1
    0,                                  /*tp_del*/
#else
    __Pyx_Coroutine_del,                /*tp_del*/
#endif
    0,                                  /*tp_version_tag*/
#if PY_VERSION_HEX >= 0x030400a1
    __Pyx_Coroutine_del,                /*tp_finalize*/
#endif
1787 1788 1789
#if PY_VERSION_HEX >= 0x030800b1
    0,                                  /*tp_vectorcall*/
#endif
1790 1791 1792
#if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000
    0,                                  /*tp_print*/
#endif
1793 1794 1795
};


1796 1797 1798 1799 1800 1801 1802 1803 1804
static int __pyx_IterableCoroutine_init(void) {
    __pyx_IterableCoroutineType_type.tp_getattro = __Pyx_PyObject_GenericGetAttrNoDict;
    __pyx_IterableCoroutineType = __Pyx_FetchCommonType(&__pyx_IterableCoroutineType_type);
    if (unlikely(!__pyx_IterableCoroutineType))
        return -1;
    return 0;
}


1805 1806 1807
//////////////////// Generator ////////////////////
//@requires: CoroutineBase
//@requires: PatchGeneratorABC
1808
//@requires: ObjectHandling.c::PyObject_GenericGetAttrNoDict
1809

1810
static PyMethodDef __pyx_Generator_methods[] = {
1811 1812 1813 1814
    {"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.")},
1815
    {"close", (PyCFunction) __Pyx_Coroutine_Close_Method, METH_NOARGS,
1816
     (char*) PyDoc_STR("close() -> raise GeneratorExit inside generator.")},
1817 1818 1819
    {0, 0, 0, 0}
};

1820 1821
static PyMemberDef __pyx_Generator_memberlist[] = {
    {(char *) "gi_running", T_BOOL, offsetof(__pyx_CoroutineObject, is_running), READONLY, NULL},
1822 1823
    {(char*) "gi_yieldfrom", T_OBJECT, offsetof(__pyx_CoroutineObject, yieldfrom), READONLY,
     (char*) PyDoc_STR("object being iterated by 'yield from', or None")},
1824
    {(char*) "gi_code", T_OBJECT, offsetof(__pyx_CoroutineObject, gi_code), READONLY, NULL},
1825 1826 1827 1828 1829 1830 1831 1832
    {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},
1833 1834
    {(char *) "gi_frame", (getter)__Pyx_Coroutine_get_frame, NULL,
     (char*) PyDoc_STR("Frame of the coroutine"), 0},
1835 1836 1837
    {0, 0, 0, 0, 0}
};

1838 1839 1840 1841 1842 1843 1844 1845 1846
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*/
1847
    0,                                  /*tp_compare / tp_as_async*/
1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865
    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*/
1866
    __pyx_Generator_methods,            /*tp_methods*/
1867 1868
    __pyx_Generator_memberlist,         /*tp_members*/
    __pyx_Generator_getsets,            /*tp_getset*/
1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883
    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*/
1884
#if CYTHON_USE_TP_FINALIZE
1885 1886 1887 1888 1889
    0,                                  /*tp_del*/
#else
    __Pyx_Coroutine_del,                /*tp_del*/
#endif
    0,                                  /*tp_version_tag*/
1890
#if CYTHON_USE_TP_FINALIZE
1891
    __Pyx_Coroutine_del,                /*tp_finalize*/
1892 1893
#elif PY_VERSION_HEX >= 0x030400a1
    0,                                  /*tp_finalize*/
1894
#endif
1895 1896 1897
#if PY_VERSION_HEX >= 0x030800b1
    0,                                  /*tp_vectorcall*/
#endif
1898 1899 1900
#if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000
    0,                                  /*tp_print*/
#endif
1901 1902
};

1903
static int __pyx_Generator_init(void) {
1904
    // on Windows, C-API functions can't be used in slots statically
1905
    __pyx_GeneratorType_type.tp_getattro = __Pyx_PyObject_GenericGetAttrNoDict;
Stefan Behnel's avatar
Stefan Behnel committed
1906
    __pyx_GeneratorType_type.tp_iter = PyObject_SelfIter;
1907 1908

    __pyx_GeneratorType = __Pyx_FetchCommonType(&__pyx_GeneratorType_type);
1909
    if (unlikely(!__pyx_GeneratorType)) {
1910 1911 1912
        return -1;
    }
    return 0;
1913
}
1914 1915


1916 1917
/////////////// ReturnWithStopIteration.proto ///////////////

1918 1919
#define __Pyx_ReturnWithStopIteration(value)  \
    if (value == Py_None) PyErr_SetNone(PyExc_StopIteration); else __Pyx__ReturnWithStopIteration(value)
1920 1921 1922
static void __Pyx__ReturnWithStopIteration(PyObject* value); /*proto*/

/////////////// ReturnWithStopIteration ///////////////
1923
//@requires: Exceptions.c::PyErrFetchRestore
1924
//@requires: Exceptions.c::PyThreadStateGet
1925 1926 1927 1928 1929
//@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.
1930 1931
// 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.
1932 1933 1934

static void __Pyx__ReturnWithStopIteration(PyObject* value) {
    PyObject *exc, *args;
1935
#if CYTHON_COMPILING_IN_CPYTHON || CYTHON_COMPILING_IN_PYSTON
1936
    __Pyx_PyThreadState_declare
1937 1938
    if ((PY_VERSION_HEX >= 0x03030000 && PY_VERSION_HEX < 0x030500B1)
            || unlikely(PyTuple_Check(value) || PyExceptionInstance_Check(value))) {
1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950
        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;
    }
1951
    #if CYTHON_FAST_THREAD_STATE
1952
    __Pyx_PyThreadState_assign
1953 1954
    #if CYTHON_USE_EXC_INFO_STACK
    if (!$local_tstate_cname->exc_info->exc_type)
1955 1956 1957 1958
    #else
    if (!$local_tstate_cname->exc_type)
    #endif
    {
1959 1960 1961 1962 1963
        // no chaining needed => avoid the overhead in PyErr_SetObject()
        Py_INCREF(PyExc_StopIteration);
        __Pyx_ErrRestore(PyExc_StopIteration, exc, NULL);
        return;
    }
1964
    #endif
1965 1966 1967
#else
    args = PyTuple_Pack(1, value);
    if (unlikely(!args)) return;
1968 1969
    exc = PyObject_Call(PyExc_StopIteration, args, NULL);
    Py_DECREF(args);
1970
    if (unlikely(!exc)) return;
1971
#endif
1972 1973 1974
    PyErr_SetObject(PyExc_StopIteration, exc);
    Py_DECREF(exc);
}
1975 1976


1977
//////////////////// PatchModuleWithCoroutine.proto ////////////////////
1978

1979
static PyObject* __Pyx_Coroutine_patch_module(PyObject* module, const char* py_code); /*proto*/
1980

1981
//////////////////// PatchModuleWithCoroutine ////////////////////
1982 1983
//@substitute: naming

1984 1985
static PyObject* __Pyx_Coroutine_patch_module(PyObject* module, const char* py_code) {
#if defined(__Pyx_Generator_USED) || defined(__Pyx_Coroutine_USED)
1986
    int result;
1987
    PyObject *globals, *result_obj;
1988
    globals = PyDict_New();  if (unlikely(!globals)) goto ignore;
1989
    result = PyDict_SetItemString(globals, "_cython_coroutine_type",
1990
    #ifdef __Pyx_Coroutine_USED
1991 1992 1993
        (PyObject*)__pyx_CoroutineType);
    #else
        Py_None);
1994
    #endif
1995 1996
    if (unlikely(result < 0)) goto ignore;
    result = PyDict_SetItemString(globals, "_cython_generator_type",
1997
    #ifdef __Pyx_Generator_USED
1998 1999 2000
        (PyObject*)__pyx_GeneratorType);
    #else
        Py_None);
2001
    #endif
2002
    if (unlikely(result < 0)) goto ignore;
2003
    if (unlikely(PyDict_SetItemString(globals, "_module", module) < 0)) goto ignore;
2004
    if (unlikely(PyDict_SetItemString(globals, "__builtins__", $builtins_cname) < 0)) goto ignore;
2005 2006 2007 2008 2009 2010 2011 2012
    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);
2013
    PyErr_WriteUnraisable(module);
2014 2015 2016 2017
    if (unlikely(PyErr_WarnEx(PyExc_RuntimeWarning, "Cython module failed to patch module with custom type", 1) < 0)) {
        Py_DECREF(module);
        module = NULL;
    }
2018 2019 2020 2021
#else
    // avoid "unused" warning
    py_code++;
#endif
2022 2023
    return module;
}
2024

2025

2026 2027
//////////////////// PatchGeneratorABC.proto ////////////////////

2028
// register with Generator/Coroutine ABCs in 'collections.abc'
2029 2030 2031 2032
// see https://bugs.python.org/issue24018
static int __Pyx_patch_abc(void); /*proto*/

//////////////////// PatchGeneratorABC ////////////////////
2033
//@requires: PatchModuleWithCoroutine
2034

2035 2036 2037 2038
#ifndef CYTHON_REGISTER_ABCS
#define CYTHON_REGISTER_ABCS 1
#endif

2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057
#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

2058
static int __Pyx_patch_abc(void) {
2059
#if defined(__Pyx_Generator_USED) || defined(__Pyx_Coroutine_USED)
2060
    static int abc_patched = 0;
2061
    if (CYTHON_REGISTER_ABCS && !abc_patched) {
2062
        PyObject *module;
2063
        module = PyImport_ImportModule((PY_MAJOR_VERSION >= 3) ? "collections.abc" : "collections");
2064
        if (unlikely(!module)) {
2065
            PyErr_WriteUnraisable(NULL);
2066
            if (unlikely(PyErr_WarnEx(PyExc_RuntimeWarning,
2067
                    ((PY_MAJOR_VERSION >= 3) ?
2068 2069
                        "Cython module failed to register with collections.abc module" :
                        "Cython module failed to register with collections module"), 1) < 0)) {
2070 2071 2072
                return -1;
            }
        } else {
2073
            module = __Pyx_patch_abc_module(module);
2074 2075 2076
            abc_patched = 1;
            if (unlikely(!module))
                return -1;
2077 2078
            Py_DECREF(module);
        }
2079 2080 2081 2082 2083 2084 2085 2086 2087
        // 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();
        }
2088 2089
    }
#else
2090
    // avoid "unused" warning for __Pyx_Coroutine_patch_module()
2091
    if ((0)) __Pyx_Coroutine_patch_module(NULL, NULL);
2092 2093 2094 2095 2096
#endif
    return 0;
}


2097 2098 2099 2100 2101 2102
//////////////////// PatchAsyncIO.proto ////////////////////

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

//////////////////// PatchAsyncIO ////////////////////
2103
//@requires: ImportExport.c::Import
2104
//@requires: PatchModuleWithCoroutine
2105 2106 2107
//@requires: PatchInspect

static PyObject* __Pyx_patch_asyncio(PyObject* module) {
2108
#if PY_VERSION_HEX < 0x030500B2 && \
2109 2110
        (defined(__Pyx_Coroutine_USED) || defined(__Pyx_Generator_USED)) && \
        (!defined(CYTHON_PATCH_ASYNCIO) || CYTHON_PATCH_ASYNCIO)
2111 2112 2113 2114 2115 2116
    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) {
2117
            patch_module = __Pyx_Coroutine_patch_module(
2118
                PyObject_GetAttrString(package, "coroutines"), CSTRING("""\
2119 2120 2121 2122 2123 2124 2125 2126
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,)
2127
_module._COROUTINE_TYPES = coro_types
2128
""")
2129 2130 2131
            );
        } else {
            PyErr_Clear();
2132 2133
// Always enable fallback: even if we compile against 3.4.2, we might be running on 3.4.1 at some point.
//#if PY_VERSION_HEX < 0x03040200
2134
            // Py3.4.1 used to have asyncio.tasks instead of asyncio.coroutines
2135 2136
            package = __Pyx_Import(PYIDENT("asyncio.tasks"), NULL, 0);
            if (unlikely(!package)) goto asyncio_done;
2137
            patch_module = __Pyx_Coroutine_patch_module(
2138
                PyObject_GetAttrString(package, "tasks"), CSTRING("""\
2139
if hasattr(_module, 'iscoroutine'):
2140 2141 2142 2143
    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):
2144 2145 2146 2147
            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)
2148 2149 2150 2151
    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)
2152
""")
2153
            );
2154
//#endif
2155
// Py < 0x03040200
2156 2157 2158
        }
        Py_DECREF(package);
        if (unlikely(!patch_module)) goto ignore;
2159
//#if PY_VERSION_HEX < 0x03040200
2160 2161
asyncio_done:
        PyErr_Clear();
2162
//#endif
2163
        asyncio_patched = 1;
2164
#ifdef __Pyx_Generator_USED
2165 2166 2167 2168
        // now patch inspect.isgenerator() by looking up the imported module in the patched asyncio module
        {
            PyObject *inspect_module;
            if (patch_module) {
2169
                inspect_module = PyObject_GetAttr(patch_module, PYIDENT("inspect"));
2170 2171 2172 2173 2174 2175 2176 2177 2178 2179
                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;
            }
2180
            Py_XDECREF(inspect_module);
2181
        }
2182 2183
#else
        // avoid "unused" warning for __Pyx_patch_inspect()
2184
        if ((0)) return __Pyx_patch_inspect(module);
2185
#endif
2186 2187 2188 2189 2190 2191 2192 2193
    }
    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;
    }
2194
#else
2195
    // avoid "unused" warning for __Pyx_Coroutine_patch_module()
2196
    if ((0)) return __Pyx_patch_inspect(__Pyx_Coroutine_patch_module(module, NULL));
2197
#endif
2198 2199 2200 2201 2202 2203 2204 2205 2206 2207
    return module;
}


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

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

//////////////////// PatchInspect ////////////////////
2208
//@requires: PatchModuleWithCoroutine
2209 2210

static PyObject* __Pyx_patch_inspect(PyObject* module) {
2211
#if defined(__Pyx_Generator_USED) && (!defined(CYTHON_PATCH_INSPECT) || CYTHON_PATCH_INSPECT)
2212 2213
    static int inspect_patched = 0;
    if (unlikely((!inspect_patched) && module)) {
2214
        module = __Pyx_Coroutine_patch_module(
2215 2216 2217 2218 2219 2220 2221
            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
2222 2223
        return cy_isgenerator
    _module.isgenerator = cy_wrap(_module.isgenerator)
2224
old_types.add(_cython_generator_type)
2225
""")
2226 2227 2228
        );
        inspect_patched = 1;
    }
2229
#else
2230
    // avoid "unused" warning for __Pyx_Coroutine_patch_module()
2231
    if ((0)) return __Pyx_Coroutine_patch_module(module, NULL);
2232
#endif
2233 2234
    return module;
}
2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254


//////////////////// 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
2255
    0,                                  /*tp_compare / reserved*/
2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293
    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*/
2294
#if PY_VERSION_HEX >= 0x030400a1
2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305
    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
2306
        PyObject *exc = PyMapping_GetItemString(builtins, (char*) "StopAsyncIteration");
2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321
        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;
2322
    if (likely(builtins) && unlikely(PyMapping_SetItemString(builtins, (char*) "StopAsyncIteration", __Pyx_PyExc_StopAsyncIteration) < 0))
2323 2324 2325 2326
        return -1;
#endif
    return 0;
}