Generator.c 33.8 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12
//////////////////// YieldFrom.proto ////////////////////

static CYTHON_INLINE PyObject* __Pyx_Generator_Yield_From(__pyx_GeneratorObject *gen, PyObject *source);

//////////////////// YieldFrom ////////////////////
//@requires: Generator

static CYTHON_INLINE PyObject* __Pyx_Generator_Yield_From(__pyx_GeneratorObject *gen, PyObject *source) {
    PyObject *source_gen, *retval;
    source_gen = PyObject_GetIter(source);
    if (unlikely(!source_gen))
        return NULL;
13
    // source_gen is now the iterator, make the first next() call
14 15 16 17 18 19 20 21 22
    retval = Py_TYPE(source_gen)->tp_iternext(source_gen);
    if (likely(retval)) {
        gen->yieldfrom = source_gen;
        return retval;
    }
    Py_DECREF(source_gen);
    return NULL;
}

23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42

//////////////////// pep479.proto ////////////////////

static void __Pyx_Generator_Replace_StopIteration(void); /*proto*/

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

static void __Pyx_Generator_Replace_StopIteration(void) {
    PyObject *exc, *val, *tb;
    // Chain exceptions by moving StopIteration to exc_info before creating the RuntimeError.
    // In Py2.x, no chaining happens, but the exception still stays visible in exc_info.
    __Pyx_GetException(&exc, &val, &tb);
    Py_XDECREF(exc);
    Py_XDECREF(val);
    Py_XDECREF(tb);
    PyErr_SetString(PyExc_RuntimeError, "generator raised StopIteration");
}


43 44 45
//////////////////// Generator.proto ////////////////////
#define __Pyx_Generator_USED
#include <structmember.h>
46
#include <frameobject.h>
47 48 49 50 51 52 53 54 55 56 57 58

typedef PyObject *(*__pyx_generator_body_t)(PyObject *, PyObject *);

typedef struct {
    PyObject_HEAD
    __pyx_generator_body_t body;
    PyObject *closure;
    PyObject *exc_type;
    PyObject *exc_value;
    PyObject *exc_traceback;
    PyObject *gi_weakreflist;
    PyObject *classobj;
59
    PyObject *yieldfrom;
60 61
    PyObject *gi_name;
    PyObject *gi_qualname;
62
    int resume_label;
63 64
    // using T_BOOL for property below requires char value
    char is_running;
65 66
} __pyx_GeneratorObject;

67 68
static PyTypeObject *__pyx_GeneratorType = 0;

69
static __pyx_GeneratorObject *__Pyx_Generator_New(__pyx_generator_body_t body,
70
                                                  PyObject *closure, PyObject *name, PyObject *qualname);
71
static int __pyx_Generator_init(void);
72
static int __Pyx_Generator_clear(PyObject* self);
73

74 75 76 77 78 79
#if 1 || PY_VERSION_HEX < 0x030300B0
static int __Pyx_PyGen_FetchStopIterationValue(PyObject **pvalue);
#else
#define __Pyx_PyGen_FetchStopIterationValue(pvalue) PyGen_FetchStopIterationValue(pvalue)
#endif

80
//////////////////// Generator ////////////////////
81 82 83
//@requires: Exceptions.c::PyErrFetchRestore
//@requires: Exceptions.c::SwapException
//@requires: Exceptions.c::RaiseException
84
//@requires: ObjectHandling.c::PyObjectCallMethod1
85
//@requires: ObjectHandling.c::PyObjectGetAttrStr
86
//@requires: CommonTypes.c::FetchCommonType
87
//@requires: PatchGeneratorABC
88

89 90 91 92 93
static PyObject *__Pyx_Generator_Next(PyObject *self);
static PyObject *__Pyx_Generator_Send(PyObject *self, PyObject *value);
static PyObject *__Pyx_Generator_Close(PyObject *self);
static PyObject *__Pyx_Generator_Throw(PyObject *gen, PyObject *args);

94
#define __Pyx_Generator_CheckExact(obj) (Py_TYPE(obj) == __pyx_GeneratorType)
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
#define __Pyx_Generator_Undelegate(gen) Py_CLEAR((gen)->yieldfrom)

//   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.
#if 1 || PY_VERSION_HEX < 0x030300B0
static int __Pyx_PyGen_FetchStopIterationValue(PyObject **pvalue) {
    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)) {
120 121 122 123 124 125 126 127 128 129 130 131
#if PY_VERSION_HEX >= 0x030300A0
        if (ev && Py_TYPE(ev) == (PyTypeObject*)PyExc_StopIteration) {
            value = ((PyStopIterationObject *)ev)->value;
            Py_INCREF(value);
            Py_DECREF(ev);
            Py_XDECREF(tb);
            Py_DECREF(et);
            *pvalue = value;
            return 0;
        }
#endif
        if (!ev || !PyObject_IsInstance(ev, PyExc_StopIteration)) {
132 133 134 135 136 137 138 139 140 141
            // PyErr_SetObject() and friends put the value directly into ev
            if (!ev) {
                Py_INCREF(Py_None);
                ev = Py_None;
            }
            Py_XDECREF(tb);
            Py_DECREF(et);
            *pvalue = ev;
            return 0;
        }
142 143 144
    } else if (!PyErr_GivenExceptionMatches(et, PyExc_StopIteration)) {
        __Pyx_ErrRestore(et, ev, tb);
        return -1;
145
    }
146

147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
    // otherwise: normalise and check what that gives us
    PyErr_NormalizeException(&et, &ev, &tb);
    if (unlikely(!PyObject_IsInstance(ev, PyExc_StopIteration))) {
        // 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
    {
162
        PyObject* args = __Pyx_PyObject_GetAttrStr(ev, PYIDENT("args"));
163 164
        Py_DECREF(ev);
        if (likely(args)) {
165
            value = PySequence_GetItem(args, 0);
166 167 168 169 170 171 172 173 174 175 176 177 178 179
            Py_DECREF(args);
        }
        if (unlikely(!value)) {
            __Pyx_ErrRestore(NULL, NULL, NULL);
            Py_INCREF(Py_None);
            value = Py_None;
        }
    }
#endif
    *pvalue = value;
    return 0;
}
#endif

180
static CYTHON_INLINE
181
void __Pyx_Generator_ExceptionClear(__pyx_GeneratorObject *self) {
182 183 184
    PyObject *exc_type = self->exc_type;
    PyObject *exc_value = self->exc_value;
    PyObject *exc_traceback = self->exc_traceback;
185 186 187 188

    self->exc_type = NULL;
    self->exc_value = NULL;
    self->exc_traceback = NULL;
189 190 191 192

    Py_XDECREF(exc_type);
    Py_XDECREF(exc_value);
    Py_XDECREF(exc_traceback);
193 194 195
}

static CYTHON_INLINE
196 197
int __Pyx_Generator_CheckRunning(__pyx_GeneratorObject *gen) {
    if (unlikely(gen->is_running)) {
198 199
        PyErr_SetString(PyExc_ValueError,
                        "generator already executing");
200
        return 1;
201
    }
202 203 204 205 206 207 208 209
    return 0;
}

static CYTHON_INLINE
PyObject *__Pyx_Generator_SendEx(__pyx_GeneratorObject *self, PyObject *value) {
    PyObject *retval;

    assert(!self->is_running);
210

211 212
    if (unlikely(self->resume_label == 0)) {
        if (unlikely(value && value != Py_None)) {
213 214 215 216 217 218 219
            PyErr_SetString(PyExc_TypeError,
                            "can't send non-None value to a "
                            "just-started generator");
            return NULL;
        }
    }

220
    if (unlikely(self->resume_label == -1)) {
221 222 223 224 225
        PyErr_SetNone(PyExc_StopIteration);
        return NULL;
    }


226
    if (value) {
227 228 229
#if CYTHON_COMPILING_IN_PYPY
        // FIXME: what to do in PyPy?
#else
230 231
        // Generators always return to their most recent caller, not
        // necessarily their creator.
232 233 234 235 236 237 238 239 240
        if (self->exc_traceback) {
            PyThreadState *tstate = PyThreadState_GET();
            PyTracebackObject *tb = (PyTracebackObject *) self->exc_traceback;
            PyFrameObject *f = tb->tb_frame;

            Py_XINCREF(tstate->frame);
            assert(f->f_back == NULL);
            f->f_back = tstate->frame;
        }
241
#endif
242 243 244
        __Pyx_ExceptionSwap(&self->exc_type, &self->exc_value,
                            &self->exc_traceback);
    } else {
245
        __Pyx_Generator_ExceptionClear(self);
246
    }
247 248 249 250 251

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

252 253 254
    if (retval) {
        __Pyx_ExceptionSwap(&self->exc_type, &self->exc_value,
                            &self->exc_traceback);
255 256 257
#if CYTHON_COMPILING_IN_PYPY
        // FIXME: what to do in PyPy?
#else
258 259 260
        // 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.
261 262 263 264 265
        if (self->exc_traceback) {
            PyTracebackObject *tb = (PyTracebackObject *) self->exc_traceback;
            PyFrameObject *f = tb->tb_frame;
            Py_CLEAR(f->f_back);
        }
266
#endif
267
    } else {
268
        __Pyx_Generator_ExceptionClear(self);
269
    }
270 271 272 273

    return retval;
}

274 275 276 277 278 279 280 281 282
static CYTHON_INLINE
PyObject *__Pyx_Generator_MethodReturn(PyObject *retval) {
    if (unlikely(!retval && !PyErr_Occurred())) {
        // method call must not terminate with NULL without setting an exception
        PyErr_SetNone(PyExc_StopIteration);
    }
    return retval;
}

283 284 285 286 287 288 289 290 291 292
static CYTHON_INLINE
PyObject *__Pyx_Generator_FinishDelegation(__pyx_GeneratorObject *gen) {
    PyObject *ret;
    PyObject *val = NULL;
    __Pyx_Generator_Undelegate(gen);
    __Pyx_PyGen_FetchStopIterationValue(&val);
    // val == NULL on failure => pass on exception
    ret = __Pyx_Generator_SendEx(gen, val);
    Py_XDECREF(val);
    return ret;
293 294
}

295 296 297 298 299 300 301 302 303
static PyObject *__Pyx_Generator_Next(PyObject *self) {
    __pyx_GeneratorObject *gen = (__pyx_GeneratorObject*) self;
    PyObject *yf = gen->yieldfrom;
    if (unlikely(__Pyx_Generator_CheckRunning(gen)))
        return NULL;
    if (yf) {
        PyObject *ret;
        // FIXME: does this really need an INCREF() ?
        //Py_INCREF(yf);
304
        // YieldFrom code ensures that yf is an iterator
305 306 307 308 309 310 311 312 313 314
        gen->is_running = 1;
        ret = Py_TYPE(yf)->tp_iternext(yf);
        gen->is_running = 0;
        //Py_DECREF(yf);
        if (likely(ret)) {
            return ret;
        }
        return __Pyx_Generator_FinishDelegation(gen);
    }
    return __Pyx_Generator_SendEx(gen, Py_None);
315 316
}

317
static PyObject *__Pyx_Generator_Send(PyObject *self, PyObject *value) {
318
    PyObject *retval;
319 320 321 322 323 324 325 326 327 328 329 330 331 332 333
    __pyx_GeneratorObject *gen = (__pyx_GeneratorObject*) self;
    PyObject *yf = gen->yieldfrom;
    if (unlikely(__Pyx_Generator_CheckRunning(gen)))
        return NULL;
    if (yf) {
        PyObject *ret;
        // FIXME: does this really need an INCREF() ?
        //Py_INCREF(yf);
        gen->is_running = 1;
        if (__Pyx_Generator_CheckExact(yf)) {
            ret = __Pyx_Generator_Send(yf, value);
        } else {
            if (value == Py_None)
                ret = PyIter_Next(yf);
            else
334
                ret = __Pyx_PyObject_CallMethod1(yf, PYIDENT("send"), value);
335 336 337 338 339 340
        }
        gen->is_running = 0;
        //Py_DECREF(yf);
        if (likely(ret)) {
            return ret;
        }
341 342 343
        retval = __Pyx_Generator_FinishDelegation(gen);
    } else {
        retval = __Pyx_Generator_SendEx(gen, value);
344
    }
345
    return __Pyx_Generator_MethodReturn(retval);
346 347 348 349 350 351 352 353 354 355 356 357 358 359 360
}

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

    if (__Pyx_Generator_CheckExact(yf)) {
        retval = __Pyx_Generator_Close(yf);
        if (!retval)
            return -1;
    } else {
        PyObject *meth;
        gen->is_running = 1;
361
        meth = __Pyx_PyObject_GetAttrStr(yf, PYIDENT("close"));
362 363 364 365 366 367
        if (unlikely(!meth)) {
            if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
                PyErr_WriteUnraisable(yf);
            }
            PyErr_Clear();
        } else {
368
            retval = PyObject_CallFunction(meth, NULL);
369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396
            Py_DECREF(meth);
            if (!retval)
                err = -1;
        }
        gen->is_running = 0;
    }
    Py_XDECREF(retval);
    return err;
}

static PyObject *__Pyx_Generator_Close(PyObject *self) {
    __pyx_GeneratorObject *gen = (__pyx_GeneratorObject *) self;
    PyObject *retval, *raised_exception;
    PyObject *yf = gen->yieldfrom;
    int err = 0;

    if (unlikely(__Pyx_Generator_CheckRunning(gen)))
        return NULL;

    if (yf) {
        Py_INCREF(yf);
        err = __Pyx_Generator_CloseIter(gen, yf);
        __Pyx_Generator_Undelegate(gen);
        Py_DECREF(yf);
    }
    if (err == 0)
        PyErr_SetNone(PyExc_GeneratorExit);
    retval = __Pyx_Generator_SendEx(gen, NULL);
397 398 399 400 401 402
    if (retval) {
        Py_DECREF(retval);
        PyErr_SetString(PyExc_RuntimeError,
                        "generator ignored GeneratorExit");
        return NULL;
    }
403 404 405 406 407 408
    raised_exception = PyErr_Occurred();
    if (!raised_exception
        || raised_exception == PyExc_StopIteration
        || raised_exception == PyExc_GeneratorExit
        || PyErr_GivenExceptionMatches(raised_exception, PyExc_GeneratorExit)
        || PyErr_GivenExceptionMatches(raised_exception, PyExc_StopIteration))
409
    {
410 411
        // ignore these errors
        if (raised_exception) PyErr_Clear();
412 413 414 415 416 417
        Py_INCREF(Py_None);
        return Py_None;
    }
    return NULL;
}

418 419
static PyObject *__Pyx_Generator_Throw(PyObject *self, PyObject *args) {
    __pyx_GeneratorObject *gen = (__pyx_GeneratorObject *) self;
420 421 422
    PyObject *typ;
    PyObject *tb = NULL;
    PyObject *val = NULL;
423
    PyObject *yf = gen->yieldfrom;
424 425 426

    if (!PyArg_UnpackTuple(args, (char *)"throw", 1, 3, &typ, &val, &tb))
        return NULL;
427 428 429 430 431 432 433 434 435 436 437 438

    if (unlikely(__Pyx_Generator_CheckRunning(gen)))
        return NULL;

    if (yf) {
        PyObject *ret;
        Py_INCREF(yf);
        if (PyErr_GivenExceptionMatches(typ, PyExc_GeneratorExit)) {
            int err = __Pyx_Generator_CloseIter(gen, yf);
            Py_DECREF(yf);
            __Pyx_Generator_Undelegate(gen);
            if (err < 0)
439
                return __Pyx_Generator_MethodReturn(__Pyx_Generator_SendEx(gen, NULL));
440 441 442 443 444 445
            goto throw_here;
        }
        gen->is_running = 1;
        if (__Pyx_Generator_CheckExact(yf)) {
            ret = __Pyx_Generator_Throw(yf, args);
        } else {
446
            PyObject *meth = __Pyx_PyObject_GetAttrStr(yf, PYIDENT("throw"));
447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465
            if (unlikely(!meth)) {
                Py_DECREF(yf);
                if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
                    gen->is_running = 0;
                    return NULL;
                }
                PyErr_Clear();
                __Pyx_Generator_Undelegate(gen);
                gen->is_running = 0;
                goto throw_here;
            }
            ret = PyObject_CallObject(meth, args);
            Py_DECREF(meth);
        }
        gen->is_running = 0;
        Py_DECREF(yf);
        if (!ret) {
            ret = __Pyx_Generator_FinishDelegation(gen);
        }
466
        return __Pyx_Generator_MethodReturn(ret);
467 468
    }
throw_here:
469
    __Pyx_Raise(typ, val, tb, NULL);
470
    return __Pyx_Generator_MethodReturn(__Pyx_Generator_SendEx(gen, NULL));
471 472
}

473
static int __Pyx_Generator_traverse(PyObject *self, visitproc visit, void *arg) {
474 475 476 477
    __pyx_GeneratorObject *gen = (__pyx_GeneratorObject *) self;

    Py_VISIT(gen->closure);
    Py_VISIT(gen->classobj);
478
    Py_VISIT(gen->yieldfrom);
479 480 481 482 483 484
    Py_VISIT(gen->exc_type);
    Py_VISIT(gen->exc_value);
    Py_VISIT(gen->exc_traceback);
    return 0;
}

485 486 487 488 489 490 491 492 493
static int __Pyx_Generator_clear(PyObject *self) {
    __pyx_GeneratorObject *gen = (__pyx_GeneratorObject *) self;

    Py_CLEAR(gen->closure);
    Py_CLEAR(gen->classobj);
    Py_CLEAR(gen->yieldfrom);
    Py_CLEAR(gen->exc_type);
    Py_CLEAR(gen->exc_value);
    Py_CLEAR(gen->exc_traceback);
494 495
    Py_CLEAR(gen->gi_name);
    Py_CLEAR(gen->gi_qualname);
496 497 498
    return 0;
}

499
static void __Pyx_Generator_dealloc(PyObject *self) {
500 501
    __pyx_GeneratorObject *gen = (__pyx_GeneratorObject *) self;

502 503 504 505 506
    PyObject_GC_UnTrack(gen);
    if (gen->gi_weakreflist != NULL)
        PyObject_ClearWeakRefs(self);

    if (gen->resume_label > 0) {
507
        // Generator is paused, so we need to close
508 509 510 511
        PyObject_GC_Track(self);
#if PY_VERSION_HEX >= 0x030400a1
        if (PyObject_CallFinalizerFromDealloc(self))
#else
512 513
        Py_TYPE(gen)->tp_del(self);
        if (self->ob_refcnt > 0)
514
#endif
515 516 517 518
        {
            // resurrected.  :(
            return;
        }
519
        PyObject_GC_UnTrack(self);
520 521
    }

522
    __Pyx_Generator_clear(self);
523 524 525
    PyObject_GC_Del(gen);
}

526
static void __Pyx_Generator_del(PyObject *self) {
527 528 529 530 531 532 533
    PyObject *res;
    PyObject *error_type, *error_value, *error_traceback;
    __pyx_GeneratorObject *gen = (__pyx_GeneratorObject *) self;

    if (gen->resume_label <= 0)
        return ;

534
#if PY_VERSION_HEX < 0x030400a1
535
    // Temporarily resurrect the object.
536 537
    assert(self->ob_refcnt == 0);
    self->ob_refcnt = 1;
538
#endif
539

540
    // Save the current exception, if any.
541 542 543 544 545 546 547 548 549
    __Pyx_ErrFetch(&error_type, &error_value, &error_traceback);

    res = __Pyx_Generator_Close(self);

    if (res == NULL)
        PyErr_WriteUnraisable(self);
    else
        Py_DECREF(res);

550
    // Restore the saved exception.
551 552
    __Pyx_ErrRestore(error_type, error_value, error_traceback);

553
#if PY_VERSION_HEX < 0x030400a1
554 555
    // Undo the temporary resurrection; can't use DECREF here, it would
    // cause a recursive call.
556
    assert(self->ob_refcnt > 0);
557 558 559 560
    if (--self->ob_refcnt == 0) {
        // this is the normal path out
        return;
    }
561

562 563
    // close() resurrected it!  Make it look like the original Py_DECREF
    // never happened.
564 565 566 567 568
    {
        Py_ssize_t refcnt = self->ob_refcnt;
        _Py_NewReference(self);
        self->ob_refcnt = refcnt;
    }
569
#if CYTHON_COMPILING_IN_CPYTHON
570 571 572
    assert(PyType_IS_GC(self->ob_type) &&
           _Py_AS_GC(self)->gc.gc_refs != _PyGC_REFS_UNTRACKED);

573 574
    // If Py_REF_DEBUG, _Py_NewReference bumped _Py_RefTotal, so
    // we need to undo that.
575
    _Py_DEC_REFTOTAL;
576
#endif
577 578 579 580 581
    // 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.
582
#ifdef COUNT_ALLOCS
583 584
    --Py_TYPE(self)->tp_frees;
    --Py_TYPE(self)->tp_allocs;
585
#endif
586
#endif
587
}
588

589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645
static PyObject *
__Pyx_Generator_get_name(__pyx_GeneratorObject *self)
{
    Py_INCREF(self->gi_name);
    return self->gi_name;
}

static int
__Pyx_Generator_set_name(__pyx_GeneratorObject *self, PyObject *value)
{
    PyObject *tmp;

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

static PyObject *
__Pyx_Generator_get_qualname(__pyx_GeneratorObject *self)
{
    Py_INCREF(self->gi_qualname);
    return self->gi_qualname;
}

static int
__Pyx_Generator_set_qualname(__pyx_GeneratorObject *self, PyObject *value)
{
    PyObject *tmp;

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

static PyGetSetDef __pyx_Generator_getsets[] = {
646
    {(char *) "__name__", (getter)__Pyx_Generator_get_name, (setter)__Pyx_Generator_set_name,
Stefan Behnel's avatar
Stefan Behnel committed
647
     (char*) PyDoc_STR("name of the generator"), 0},
648
    {(char *) "__qualname__", (getter)__Pyx_Generator_get_qualname, (setter)__Pyx_Generator_set_qualname,
Stefan Behnel's avatar
Stefan Behnel committed
649
     (char*) PyDoc_STR("qualified name of the generator"), 0},
650 651 652
    {0, 0, 0, 0, 0}
};

653
static PyMemberDef __pyx_Generator_memberlist[] = {
654
    {(char *) "gi_running", T_BOOL, offsetof(__pyx_GeneratorObject, is_running), READONLY, NULL},
655
    {0, 0, 0, 0, 0}
656 657
};

658
static PyMethodDef __pyx_Generator_methods[] = {
659 660 661
    {"send", (PyCFunction) __Pyx_Generator_Send, METH_O, 0},
    {"throw", (PyCFunction) __Pyx_Generator_Throw, METH_VARARGS, 0},
    {"close", (PyCFunction) __Pyx_Generator_Close, METH_NOARGS, 0},
662 663 664
    {0, 0, 0, 0}
};

665
static PyTypeObject __pyx_GeneratorType_type = {
666
    PyVarObject_HEAD_INIT(0, 0)
667
    "generator",                        /*tp_name*/
668 669 670 671 672 673 674 675 676 677 678
    sizeof(__pyx_GeneratorObject),      /*tp_basicsize*/
    0,                                  /*tp_itemsize*/
    (destructor) __Pyx_Generator_dealloc,/*tp_dealloc*/
    0,                                  /*tp_print*/
    0,                                  /*tp_getattr*/
    0,                                  /*tp_setattr*/
#if PY_MAJOR_VERSION < 3
    0,                                  /*tp_compare*/
#else
    0,                                  /*reserved*/
#endif
679
    0,                                  /*tp_repr*/
680 681 682 683 684 685
    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
686
    0,                                  /*tp_getattro*/
687 688
    0,                                  /*tp_setattro*/
    0,                                  /*tp_as_buffer*/
689
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
690 691
    0,                                  /*tp_doc*/
    (traverseproc) __Pyx_Generator_traverse,   /*tp_traverse*/
692
    0,                                  /*tp_clear*/
693
    0,                                  /*tp_richcompare*/
694
    offsetof(__pyx_GeneratorObject, gi_weakreflist), /*tp_weaklistoffset*/
Stefan Behnel's avatar
Stefan Behnel committed
695
    0,                                  /*tp_iter*/
696 697
    (iternextfunc) __Pyx_Generator_Next, /*tp_iternext*/
    __pyx_Generator_methods,            /*tp_methods*/
698
    __pyx_Generator_memberlist,         /*tp_members*/
699
    __pyx_Generator_getsets,            /*tp_getset*/
700 701 702 703 704 705 706 707 708 709 710 711 712 713 714
    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*/
715 716 717
#if PY_VERSION_HEX >= 0x030400a1
    0,                                  /*tp_del*/
#else
718
    __Pyx_Generator_del,                /*tp_del*/
719
#endif
720
    0,                                  /*tp_version_tag*/
721
#if PY_VERSION_HEX >= 0x030400a1
722
    __Pyx_Generator_del,                /*tp_finalize*/
723
#endif
724 725
};

726
static __pyx_GeneratorObject *__Pyx_Generator_New(__pyx_generator_body_t body,
727
                                                  PyObject *closure, PyObject *name, PyObject *qualname) {
728
    __pyx_GeneratorObject *gen =
729
        PyObject_GC_New(__pyx_GeneratorObject, __pyx_GeneratorType);
730 731 732 733 734 735 736 737 738 739

    if (gen == NULL)
        return NULL;

    gen->body = body;
    gen->closure = closure;
    Py_XINCREF(closure);
    gen->is_running = 0;
    gen->resume_label = 0;
    gen->classobj = NULL;
740
    gen->yieldfrom = NULL;
741 742 743 744
    gen->exc_type = NULL;
    gen->exc_value = NULL;
    gen->exc_traceback = NULL;
    gen->gi_weakreflist = NULL;
745
    Py_XINCREF(qualname);
746
    gen->gi_qualname = qualname;
747
    Py_XINCREF(name);
748
    gen->gi_name = name;
749 750 751 752 753

    PyObject_GC_Track(gen);
    return gen;
}

754
static int __pyx_Generator_init(void) {
755
    // on Windows, C-API functions can't be used in slots statically
Stefan Behnel's avatar
Stefan Behnel committed
756 757
    __pyx_GeneratorType_type.tp_getattro = PyObject_GenericGetAttr;
    __pyx_GeneratorType_type.tp_iter = PyObject_SelfIter;
758 759 760

    __pyx_GeneratorType = __Pyx_FetchCommonType(&__pyx_GeneratorType_type);
    if (__pyx_GeneratorType == NULL) {
761 762 763
        return -1;
    }
    return 0;
764
}
765 766


767 768 769 770
/////////////// ReturnWithStopIteration.proto ///////////////

#if CYTHON_COMPILING_IN_CPYTHON
// CPython 3.3+ crashes in yield-from when the StopIteration is not instantiated
771 772
#define __Pyx_ReturnWithStopIteration(value)  \
    if (value == Py_None) PyErr_SetNone(PyExc_StopIteration); else __Pyx__ReturnWithStopIteration(value)
773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795
static void __Pyx__ReturnWithStopIteration(PyObject* value); /*proto*/
#else
#define __Pyx_ReturnWithStopIteration(value)  PyErr_SetObject(PyExc_StopIteration, value)
#endif

/////////////// ReturnWithStopIteration ///////////////

#if CYTHON_COMPILING_IN_CPYTHON
static void __Pyx__ReturnWithStopIteration(PyObject* value) {
    PyObject *exc, *args;
    args = PyTuple_New(1);
    if (!args) return;
    Py_INCREF(value);
    PyTuple_SET_ITEM(args, 0, value);
    exc = PyObject_Call(PyExc_StopIteration, args, NULL);
    Py_DECREF(args);
    if (!exc) return;
    Py_INCREF(PyExc_StopIteration);
    PyErr_Restore(PyExc_StopIteration, exc, NULL);
}
#endif


796 797 798 799 800 801 802 803
//////////////////// PatchModuleWithGenerator.proto ////////////////////

static PyObject* __Pyx_Generator_patch_module(PyObject* module, const char* py_code); /*proto*/

//////////////////// PatchModuleWithGenerator ////////////////////
//@substitute: naming

static PyObject* __Pyx_Generator_patch_module(PyObject* module, const char* py_code) {
804
#ifdef __Pyx_Generator_USED
805 806 807 808
    PyObject *globals, *result_obj;
    globals = PyDict_New();  if (unlikely(!globals)) goto ignore;
    if (unlikely(PyDict_SetItemString(globals, "_cython_generator_type", (PyObject*)__pyx_GeneratorType) < 0)) goto ignore;
    if (unlikely(PyDict_SetItemString(globals, "_module", module) < 0)) goto ignore;
809
    if (unlikely(PyDict_SetItemString(globals, "__builtins__", $builtins_cname) < 0)) goto ignore;
810 811 812 813 814 815 816 817
    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);
818
    PyErr_WriteUnraisable(module);
819 820 821 822
    if (unlikely(PyErr_WarnEx(PyExc_RuntimeWarning, "Cython module failed to patch module with custom type", 1) < 0)) {
        Py_DECREF(module);
        module = NULL;
    }
823 824 825 826
#else
    // avoid "unused" warning
    py_code++;
#endif
827 828
    return module;
}
829

830

831 832 833 834 835 836 837 838 839 840 841 842 843 844
//////////////////// PatchGeneratorABC.proto ////////////////////

// patch 'collections.abc' if it lacks generator support
// see https://bugs.python.org/issue24018
static int __Pyx_patch_abc(void); /*proto*/

//////////////////// PatchGeneratorABC ////////////////////
//@requires: PatchModuleWithGenerator

static int __Pyx_patch_abc(void) {
#if defined(__Pyx_Generator_USED) && (!defined(CYTHON_PATCH_ABC) || CYTHON_PATCH_ABC)
    static int abc_patched = 0;
    if (!abc_patched) {
        PyObject *module;
845
        module = PyImport_ImportModule((PY_VERSION_HEX >= 0x03030000) ? "collections.abc" : "collections");
846
        if (!module) {
847
            PyErr_WriteUnraisable(NULL);
848 849 850 851
            if (unlikely(PyErr_WarnEx(PyExc_RuntimeWarning,
                    ((PY_VERSION_HEX >= 0x03030000) ?
                        "Cython module failed to patch collections.abc.Generator" :
                        "Cython module failed to patch collections.Generator"), 1) < 0)) {
852 853 854
                return -1;
            }
        } else {
855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936
            PyObject *abc = PyObject_GetAttrString(module, "Generator");
            if (abc) {
                abc_patched = 1;
                Py_DECREF(abc);
            } else {
                PyErr_Clear();
                module = __Pyx_Generator_patch_module(
                    module, CSTRING("""\
def mk_gen():
    from abc import abstractmethod

    required_methods = (
        '__iter__', '__next__' if hasattr(iter(()), '__next__') else 'next',
         'send', 'throw', 'close')

    class Generator(_module.Iterator):
        __slots__ = ()

        if '__next__' in required_methods:
            def __next__(self):
                return self.send(None)
        else:
            def next(self):
                return self.send(None)

        @abstractmethod
        def send(self, value):
            raise StopIteration

        def throw(self, typ, val=None, tb=None):
            if val is None:
                if tb is None:
                    raise typ
                val = typ()
            if tb is not None:
                val = val.with_traceback(tb)
            raise val

        def close(self):
            try:
                self.throw(GeneratorExit)
            except (GeneratorExit, StopIteration):
                pass
            else:
                raise RuntimeError('generator ignored GeneratorExit')

        @classmethod
        def __subclasshook__(cls, C):
            if cls is Generator:
                mro = C.__mro__
                for method in required_methods:
                    for base in mro:
                        if method in base.__dict__:
                            break
                    else:
                        return NotImplemented
                return True
            return NotImplemented

    generator = type((lambda: (yield))())
    Generator.register(generator)
    Generator.register(_cython_generator_type)
    return Generator

_module.Generator = mk_gen()
""")
                );
                abc_patched = 1;
                if (unlikely(!module))
                    return -1;
            }
            Py_DECREF(module);
        }
    }
#else
    // avoid "unused" warning for __Pyx_Generator_patch_module()
    if (0) __Pyx_Generator_patch_module(NULL, NULL);
#endif
    return 0;
}


937 938 939 940 941 942 943 944 945 946
//////////////////// PatchAsyncIO.proto ////////////////////

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

//////////////////// PatchAsyncIO ////////////////////
//@requires: PatchModuleWithGenerator
//@requires: PatchInspect

static PyObject* __Pyx_patch_asyncio(PyObject* module) {
947
#if defined(__Pyx_Generator_USED) && (!defined(CYTHON_PATCH_ASYNCIO) || CYTHON_PATCH_ASYNCIO)
948 949 950 951 952 953 954
    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) {
            patch_module = __Pyx_Generator_patch_module(
955 956 957 958 959
                PyObject_GetAttrString(package, "coroutines"), CSTRING("""\
old_types = getattr(_module, '_COROUTINE_TYPES', None)
if old_types is not None and _cython_generator_type not in old_types:
    _module._COROUTINE_TYPES = type(old_types) (tuple(old_types) + (_cython_generator_type,))
""")
960 961 962 963 964 965 966 967
            );
        #if PY_VERSION_HEX < 0x03050000
        } else {
            // Py3.4 used to have asyncio.tasks instead of asyncio.coroutines
            PyErr_Clear();
            package = __Pyx_Import(PYIDENT("asyncio.tasks"), NULL, 0);
            if (unlikely(!package)) goto asyncio_done;
            patch_module = __Pyx_Generator_patch_module(
968 969 970 971 972 973 974 975 976
                PyObject_GetAttrString(package, "tasks"), CSTRING("""\
if (hasattr(_module, 'iscoroutine') and
        getattr(_module.iscoroutine, '_cython_generator_type', None) is not _cython_generator_type):
    def cy_wrap(orig_func, cython_generator_type=_cython_generator_type, type=type):
        def cy_iscoroutine(obj): return type(obj) is cython_generator_type or orig_func(obj)
        cy_iscoroutine._cython_generator_type = cython_generator_type
        return cy_iscoroutine
    _module.iscoroutine = cy_wrap(_module.iscoroutine)
""")
977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011
            );
        #endif
        }
        Py_DECREF(package);
        if (unlikely(!patch_module)) goto ignore;
#if PY_VERSION_HEX < 0x03050000
asyncio_done:
        PyErr_Clear();
#endif
        asyncio_patched = 1;
        // now patch inspect.isgenerator() by looking up the imported module in the patched asyncio module
        {
            PyObject *inspect_module;
            if (patch_module) {
                inspect_module = PyObject_GetAttrString(patch_module, "inspect");
                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;
            }
            Py_DECREF(inspect_module);
        }
    }
    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;
    }
1012 1013 1014 1015
#else
    // avoid "unused" warning for __Pyx_Generator_patch_module()
    if (0) return __Pyx_Generator_patch_module(module, NULL);
#endif
1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028
    return module;
}


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

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

//////////////////// PatchInspect ////////////////////
//@requires: PatchModuleWithGenerator

static PyObject* __Pyx_patch_inspect(PyObject* module) {
1029
#if defined(__Pyx_Generator_USED) && (!defined(CYTHON_PATCH_INSPECT) || CYTHON_PATCH_INSPECT)
1030 1031 1032
    static int inspect_patched = 0;
    if (unlikely((!inspect_patched) && module)) {
        module = __Pyx_Generator_patch_module(
1033 1034 1035 1036 1037 1038 1039 1040
            module, CSTRING("""\
if getattr(_module.isgenerator, '_cython_generator_type', None) is not _cython_generator_type:
    def cy_wrap(orig_func, cython_generator_type=_cython_generator_type, type=type):
        def cy_isgenerator(obj): return type(obj) is cython_generator_type or orig_func(obj)
        cy_isgenerator._cython_generator_type = cython_generator_type
        return cy_isgenerator
    _module.isgenerator = cy_wrap(_module.isgenerator)
""")
1041 1042 1043
        );
        inspect_patched = 1;
    }
1044 1045 1046 1047
#else
    // avoid "unused" warning for __Pyx_Generator_patch_module()
    if (0) return __Pyx_Generator_patch_module(module, NULL);
#endif
1048 1049
    return module;
}