1//////////////////// YieldFrom.proto ////////////////////
2
3static CYTHON_INLINE PyObject* __Pyx_Generator_Yield_From(__pyx_GeneratorObject *gen, PyObject *source);
4
5//////////////////// YieldFrom ////////////////////
6//@requires: Generator
7
8static CYTHON_INLINE PyObject* __Pyx_Generator_Yield_From(__pyx_GeneratorObject *gen, PyObject *source) {
9    PyObject *source_gen, *retval;
10    source_gen = PyObject_GetIter(source);
11    if (unlikely(!source_gen))
12        return NULL;
13    /* source_gen is now the iterator, make the first next() call */
14    retval = Py_TYPE(source_gen)->tp_iternext(source_gen);
15    if (likely(retval)) {
16        gen->yieldfrom = source_gen;
17        return retval;
18    }
19    Py_DECREF(source_gen);
20    return NULL;
21}
22
23//////////////////// Generator.proto ////////////////////
24#define __Pyx_Generator_USED
25#include <structmember.h>
26#include <frameobject.h>
27
28typedef PyObject *(*__pyx_generator_body_t)(PyObject *, PyObject *);
29
30typedef struct {
31    PyObject_HEAD
32    __pyx_generator_body_t body;
33    PyObject *closure;
34    PyObject *exc_type;
35    PyObject *exc_value;
36    PyObject *exc_traceback;
37    PyObject *gi_weakreflist;
38    PyObject *classobj;
39    PyObject *yieldfrom;
40    int resume_label;
41    // using T_BOOL for property below requires char value
42    char is_running;
43} __pyx_GeneratorObject;
44
45static __pyx_GeneratorObject *__Pyx_Generator_New(__pyx_generator_body_t body,
46                                                  PyObject *closure);
47static int __pyx_Generator_init(void);
48static int __Pyx_Generator_clear(PyObject* self);
49
50#if 1 || PY_VERSION_HEX < 0x030300B0
51static int __Pyx_PyGen_FetchStopIterationValue(PyObject **pvalue);
52#else
53#define __Pyx_PyGen_FetchStopIterationValue(pvalue) PyGen_FetchStopIterationValue(pvalue)
54#endif
55
56//////////////////// Generator ////////////////////
57//@requires: Exceptions.c::PyErrFetchRestore
58//@requires: Exceptions.c::SwapException
59//@requires: Exceptions.c::RaiseException
60//@requires: ObjectHandling.c::PyObjectCallMethod
61//@requires: CommonTypes.c::FetchCommonType
62
63static PyObject *__Pyx_Generator_Next(PyObject *self);
64static PyObject *__Pyx_Generator_Send(PyObject *self, PyObject *value);
65static PyObject *__Pyx_Generator_Close(PyObject *self);
66static PyObject *__Pyx_Generator_Throw(PyObject *gen, PyObject *args);
67
68static PyTypeObject *__pyx_GeneratorType = 0;
69
70#define __Pyx_Generator_CheckExact(obj) (Py_TYPE(obj) == __pyx_GeneratorType)
71#define __Pyx_Generator_Undelegate(gen) Py_CLEAR((gen)->yieldfrom)
72
73//   If StopIteration exception is set, fetches its 'value'
74//   attribute if any, otherwise sets pvalue to None.
75//
76//   Returns 0 if no exception or StopIteration is set.
77//   If any other exception is set, returns -1 and leaves
78//   pvalue unchanged.
79#if 1 || PY_VERSION_HEX < 0x030300B0
80static int __Pyx_PyGen_FetchStopIterationValue(PyObject **pvalue) {
81    PyObject *et, *ev, *tb;
82    PyObject *value = NULL;
83
84    __Pyx_ErrFetch(&et, &ev, &tb);
85
86    if (!et) {
87        Py_XDECREF(tb);
88        Py_XDECREF(ev);
89        Py_INCREF(Py_None);
90        *pvalue = Py_None;
91        return 0;
92    }
93
94    if (unlikely(et != PyExc_StopIteration) &&
95            unlikely(!PyErr_GivenExceptionMatches(et, PyExc_StopIteration))) {
96        __Pyx_ErrRestore(et, ev, tb);
97        return -1;
98    }
99
100    // most common case: plain StopIteration without or with separate argument
101    if (likely(et == PyExc_StopIteration)) {
102        if (likely(!ev) || !PyObject_IsInstance(ev, PyExc_StopIteration)) {
103            // PyErr_SetObject() and friends put the value directly into ev
104            if (!ev) {
105                Py_INCREF(Py_None);
106                ev = Py_None;
107            }
108            Py_XDECREF(tb);
109            Py_DECREF(et);
110            *pvalue = ev;
111            return 0;
112        }
113    }
114    // otherwise: normalise and check what that gives us
115    PyErr_NormalizeException(&et, &ev, &tb);
116    if (unlikely(!PyObject_IsInstance(ev, PyExc_StopIteration))) {
117        // looks like normalisation failed - raise the new exception
118        __Pyx_ErrRestore(et, ev, tb);
119        return -1;
120    }
121    Py_XDECREF(tb);
122    Py_DECREF(et);
123#if PY_VERSION_HEX >= 0x030300A0
124    value = ((PyStopIterationObject *)ev)->value;
125    Py_INCREF(value);
126    Py_DECREF(ev);
127#else
128    {
129        PyObject* args = PyObject_GetAttr(ev, PYIDENT("args"));
130        Py_DECREF(ev);
131        if (likely(args)) {
132            value = PyObject_GetItem(args, 0);
133            Py_DECREF(args);
134        }
135        if (unlikely(!value)) {
136            __Pyx_ErrRestore(NULL, NULL, NULL);
137            Py_INCREF(Py_None);
138            value = Py_None;
139        }
140    }
141#endif
142    *pvalue = value;
143    return 0;
144}
145#endif
146
147static CYTHON_INLINE
148void __Pyx_Generator_ExceptionClear(__pyx_GeneratorObject *self) {
149    PyObject *exc_type = self->exc_type;
150    PyObject *exc_value = self->exc_value;
151    PyObject *exc_traceback = self->exc_traceback;
152
153    self->exc_type = NULL;
154    self->exc_value = NULL;
155    self->exc_traceback = NULL;
156
157    Py_XDECREF(exc_type);
158    Py_XDECREF(exc_value);
159    Py_XDECREF(exc_traceback);
160}
161
162static CYTHON_INLINE
163int __Pyx_Generator_CheckRunning(__pyx_GeneratorObject *gen) {
164    if (unlikely(gen->is_running)) {
165        PyErr_SetString(PyExc_ValueError,
166                        "generator already executing");
167        return 1;
168    }
169    return 0;
170}
171
172static CYTHON_INLINE
173PyObject *__Pyx_Generator_SendEx(__pyx_GeneratorObject *self, PyObject *value) {
174    PyObject *retval;
175
176    assert(!self->is_running);
177
178    if (unlikely(self->resume_label == 0)) {
179        if (unlikely(value && value != Py_None)) {
180            PyErr_SetString(PyExc_TypeError,
181                            "can't send non-None value to a "
182                            "just-started generator");
183            return NULL;
184        }
185    }
186
187    if (unlikely(self->resume_label == -1)) {
188        PyErr_SetNone(PyExc_StopIteration);
189        return NULL;
190    }
191
192
193    if (value) {
194#if CYTHON_COMPILING_IN_PYPY
195        // FIXME: what to do in PyPy?
196#else
197        /* Generators always return to their most recent caller, not
198         * necessarily their creator. */
199        if (self->exc_traceback) {
200            PyThreadState *tstate = PyThreadState_GET();
201            PyTracebackObject *tb = (PyTracebackObject *) self->exc_traceback;
202            PyFrameObject *f = tb->tb_frame;
203
204            Py_XINCREF(tstate->frame);
205            assert(f->f_back == NULL);
206            f->f_back = tstate->frame;
207        }
208#endif
209        __Pyx_ExceptionSwap(&self->exc_type, &self->exc_value,
210                            &self->exc_traceback);
211    } else {
212        __Pyx_Generator_ExceptionClear(self);
213    }
214
215    self->is_running = 1;
216    retval = self->body((PyObject *) self, value);
217    self->is_running = 0;
218
219    if (retval) {
220        __Pyx_ExceptionSwap(&self->exc_type, &self->exc_value,
221                            &self->exc_traceback);
222#if CYTHON_COMPILING_IN_PYPY
223        // FIXME: what to do in PyPy?
224#else
225        /* Don't keep the reference to f_back any longer than necessary.  It
226         * may keep a chain of frames alive or it could create a reference
227         * cycle. */
228        if (self->exc_traceback) {
229            PyTracebackObject *tb = (PyTracebackObject *) self->exc_traceback;
230            PyFrameObject *f = tb->tb_frame;
231            Py_CLEAR(f->f_back);
232        }
233#endif
234    } else {
235        __Pyx_Generator_ExceptionClear(self);
236    }
237
238    return retval;
239}
240
241static CYTHON_INLINE
242PyObject *__Pyx_Generator_FinishDelegation(__pyx_GeneratorObject *gen) {
243    PyObject *ret;
244    PyObject *val = NULL;
245    __Pyx_Generator_Undelegate(gen);
246    __Pyx_PyGen_FetchStopIterationValue(&val);
247    // val == NULL on failure => pass on exception
248    ret = __Pyx_Generator_SendEx(gen, val);
249    Py_XDECREF(val);
250    return ret;
251}
252
253static PyObject *__Pyx_Generator_Next(PyObject *self) {
254    __pyx_GeneratorObject *gen = (__pyx_GeneratorObject*) self;
255    PyObject *yf = gen->yieldfrom;
256    if (unlikely(__Pyx_Generator_CheckRunning(gen)))
257        return NULL;
258    if (yf) {
259        PyObject *ret;
260        // FIXME: does this really need an INCREF() ?
261        //Py_INCREF(yf);
262        /* YieldFrom code ensures that yf is an iterator */
263        gen->is_running = 1;
264        ret = Py_TYPE(yf)->tp_iternext(yf);
265        gen->is_running = 0;
266        //Py_DECREF(yf);
267        if (likely(ret)) {
268            return ret;
269        }
270        return __Pyx_Generator_FinishDelegation(gen);
271    }
272    return __Pyx_Generator_SendEx(gen, Py_None);
273}
274
275static PyObject *__Pyx_Generator_Send(PyObject *self, PyObject *value) {
276    __pyx_GeneratorObject *gen = (__pyx_GeneratorObject*) self;
277    PyObject *yf = gen->yieldfrom;
278    if (unlikely(__Pyx_Generator_CheckRunning(gen)))
279        return NULL;
280    if (yf) {
281        PyObject *ret;
282        // FIXME: does this really need an INCREF() ?
283        //Py_INCREF(yf);
284        gen->is_running = 1;
285        if (__Pyx_Generator_CheckExact(yf)) {
286            ret = __Pyx_Generator_Send(yf, value);
287        } else {
288            if (value == Py_None)
289                ret = PyIter_Next(yf);
290            else
291                ret = __Pyx_PyObject_CallMethod1(yf, PYIDENT("send"), value);
292        }
293        gen->is_running = 0;
294        //Py_DECREF(yf);
295        if (likely(ret)) {
296            return ret;
297        }
298        return __Pyx_Generator_FinishDelegation(gen);
299    }
300    return __Pyx_Generator_SendEx(gen, value);
301}
302
303//   This helper function is used by gen_close and gen_throw to
304//   close a subiterator being delegated to by yield-from.
305static int __Pyx_Generator_CloseIter(__pyx_GeneratorObject *gen, PyObject *yf) {
306    PyObject *retval = NULL;
307    int err = 0;
308
309    if (__Pyx_Generator_CheckExact(yf)) {
310        retval = __Pyx_Generator_Close(yf);
311        if (!retval)
312            return -1;
313    } else {
314        PyObject *meth;
315        gen->is_running = 1;
316        meth = PyObject_GetAttr(yf, PYIDENT("close"));
317        if (unlikely(!meth)) {
318            if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
319                PyErr_WriteUnraisable(yf);
320            }
321            PyErr_Clear();
322        } else {
323            retval = PyObject_CallFunction(meth, NULL);
324            Py_DECREF(meth);
325            if (!retval)
326                err = -1;
327        }
328        gen->is_running = 0;
329    }
330    Py_XDECREF(retval);
331    return err;
332}
333
334static PyObject *__Pyx_Generator_Close(PyObject *self) {
335    __pyx_GeneratorObject *gen = (__pyx_GeneratorObject *) self;
336    PyObject *retval, *raised_exception;
337    PyObject *yf = gen->yieldfrom;
338    int err = 0;
339
340    if (unlikely(__Pyx_Generator_CheckRunning(gen)))
341        return NULL;
342
343    if (yf) {
344        Py_INCREF(yf);
345        err = __Pyx_Generator_CloseIter(gen, yf);
346        __Pyx_Generator_Undelegate(gen);
347        Py_DECREF(yf);
348    }
349    if (err == 0)
350#if PY_VERSION_HEX < 0x02050000
351        PyErr_SetNone(PyExc_StopIteration);
352#else
353        PyErr_SetNone(PyExc_GeneratorExit);
354#endif
355    retval = __Pyx_Generator_SendEx(gen, NULL);
356    if (retval) {
357        Py_DECREF(retval);
358        PyErr_SetString(PyExc_RuntimeError,
359                        "generator ignored GeneratorExit");
360        return NULL;
361    }
362    raised_exception = PyErr_Occurred();
363    if (!raised_exception
364        || raised_exception == PyExc_StopIteration
365#if PY_VERSION_HEX >= 0x02050000
366        || raised_exception == PyExc_GeneratorExit
367        || PyErr_GivenExceptionMatches(raised_exception, PyExc_GeneratorExit)
368#endif
369        || PyErr_GivenExceptionMatches(raised_exception, PyExc_StopIteration))
370    {
371        if (raised_exception) PyErr_Clear();      /* ignore these errors */
372        Py_INCREF(Py_None);
373        return Py_None;
374    }
375    return NULL;
376}
377
378static PyObject *__Pyx_Generator_Throw(PyObject *self, PyObject *args) {
379    __pyx_GeneratorObject *gen = (__pyx_GeneratorObject *) self;
380    PyObject *typ;
381    PyObject *tb = NULL;
382    PyObject *val = NULL;
383    PyObject *yf = gen->yieldfrom;
384
385    if (!PyArg_UnpackTuple(args, (char *)"throw", 1, 3, &typ, &val, &tb))
386        return NULL;
387
388    if (unlikely(__Pyx_Generator_CheckRunning(gen)))
389        return NULL;
390
391    if (yf) {
392        PyObject *ret;
393        Py_INCREF(yf);
394#if PY_VERSION_HEX >= 0x02050000
395        if (PyErr_GivenExceptionMatches(typ, PyExc_GeneratorExit)) {
396            int err = __Pyx_Generator_CloseIter(gen, yf);
397            Py_DECREF(yf);
398            __Pyx_Generator_Undelegate(gen);
399            if (err < 0)
400                return __Pyx_Generator_SendEx(gen, NULL);
401            goto throw_here;
402        }
403#endif
404        gen->is_running = 1;
405        if (__Pyx_Generator_CheckExact(yf)) {
406            ret = __Pyx_Generator_Throw(yf, args);
407        } else {
408            PyObject *meth = PyObject_GetAttr(yf, PYIDENT("throw"));
409            if (unlikely(!meth)) {
410                Py_DECREF(yf);
411                if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
412                    gen->is_running = 0;
413                    return NULL;
414                }
415                PyErr_Clear();
416                __Pyx_Generator_Undelegate(gen);
417                gen->is_running = 0;
418                goto throw_here;
419            }
420            ret = PyObject_CallObject(meth, args);
421            Py_DECREF(meth);
422        }
423        gen->is_running = 0;
424        Py_DECREF(yf);
425        if (!ret) {
426            ret = __Pyx_Generator_FinishDelegation(gen);
427        }
428        return ret;
429    }
430throw_here:
431    __Pyx_Raise(typ, val, tb, NULL);
432    return __Pyx_Generator_SendEx(gen, NULL);
433}
434
435static int __Pyx_Generator_traverse(PyObject *self, visitproc visit, void *arg) {
436    __pyx_GeneratorObject *gen = (__pyx_GeneratorObject *) self;
437
438    Py_VISIT(gen->closure);
439    Py_VISIT(gen->classobj);
440    Py_VISIT(gen->yieldfrom);
441    Py_VISIT(gen->exc_type);
442    Py_VISIT(gen->exc_value);
443    Py_VISIT(gen->exc_traceback);
444    return 0;
445}
446
447static int __Pyx_Generator_clear(PyObject *self) {
448    __pyx_GeneratorObject *gen = (__pyx_GeneratorObject *) self;
449
450    Py_CLEAR(gen->closure);
451    Py_CLEAR(gen->classobj);
452    Py_CLEAR(gen->yieldfrom);
453    Py_CLEAR(gen->exc_type);
454    Py_CLEAR(gen->exc_value);
455    Py_CLEAR(gen->exc_traceback);
456    return 0;
457}
458
459static void __Pyx_Generator_dealloc(PyObject *self) {
460    __pyx_GeneratorObject *gen = (__pyx_GeneratorObject *) self;
461
462    PyObject_GC_UnTrack(gen);
463    if (gen->gi_weakreflist != NULL)
464        PyObject_ClearWeakRefs(self);
465
466    if (gen->resume_label > 0) {
467        /* Generator is paused, so we need to close */
468        PyObject_GC_Track(self);
469#if PY_VERSION_HEX >= 0x030400a1
470        if (PyObject_CallFinalizerFromDealloc(self))
471#else
472        Py_TYPE(gen)->tp_del(self);
473        if (self->ob_refcnt > 0)
474#endif
475            return;                     /* resurrected.  :( */
476        PyObject_GC_UnTrack(self);
477    }
478
479    __Pyx_Generator_clear(self);
480    PyObject_GC_Del(gen);
481}
482
483static void __Pyx_Generator_del(PyObject *self) {
484    PyObject *res;
485    PyObject *error_type, *error_value, *error_traceback;
486    __pyx_GeneratorObject *gen = (__pyx_GeneratorObject *) self;
487
488    if (gen->resume_label <= 0)
489        return ;
490
491#if PY_VERSION_HEX < 0x030400a1
492    /* Temporarily resurrect the object. */
493    assert(self->ob_refcnt == 0);
494    self->ob_refcnt = 1;
495#endif
496
497    /* Save the current exception, if any. */
498    __Pyx_ErrFetch(&error_type, &error_value, &error_traceback);
499
500    res = __Pyx_Generator_Close(self);
501
502    if (res == NULL)
503        PyErr_WriteUnraisable(self);
504    else
505        Py_DECREF(res);
506
507    /* Restore the saved exception. */
508    __Pyx_ErrRestore(error_type, error_value, error_traceback);
509
510#if PY_VERSION_HEX < 0x030400a1
511    /* Undo the temporary resurrection; can't use DECREF here, it would
512     * cause a recursive call.
513     */
514    assert(self->ob_refcnt > 0);
515    if (--self->ob_refcnt == 0)
516        return; /* this is the normal path out */
517
518    /* close() resurrected it!  Make it look like the original Py_DECREF
519     * never happened.
520     */
521    {
522        Py_ssize_t refcnt = self->ob_refcnt;
523        _Py_NewReference(self);
524        self->ob_refcnt = refcnt;
525    }
526#if CYTHON_COMPILING_IN_CPYTHON
527    assert(PyType_IS_GC(self->ob_type) &&
528           _Py_AS_GC(self)->gc.gc_refs != _PyGC_REFS_UNTRACKED);
529
530    /* If Py_REF_DEBUG, _Py_NewReference bumped _Py_RefTotal, so
531     * we need to undo that. */
532    _Py_DEC_REFTOTAL;
533#endif
534    /* If Py_TRACE_REFS, _Py_NewReference re-added self to the object
535     * chain, so no more to do there.
536     * If COUNT_ALLOCS, the original decref bumped tp_frees, and
537     * _Py_NewReference bumped tp_allocs:  both of those need to be
538     * undone.
539     */
540#ifdef COUNT_ALLOCS
541    --Py_TYPE(self)->tp_frees;
542    --Py_TYPE(self)->tp_allocs;
543#endif
544#endif
545}
546
547static PyMemberDef __pyx_Generator_memberlist[] = {
548    {(char *) "gi_running",
549#if PY_VERSION_HEX >= 0x02060000
550     T_BOOL,
551#else
552     T_BYTE,
553#endif
554     offsetof(__pyx_GeneratorObject, is_running),
555     READONLY,
556     NULL},
557    {0, 0, 0, 0, 0}
558};
559
560static PyMethodDef __pyx_Generator_methods[] = {
561    {__Pyx_NAMESTR("send"), (PyCFunction) __Pyx_Generator_Send, METH_O, 0},
562    {__Pyx_NAMESTR("throw"), (PyCFunction) __Pyx_Generator_Throw, METH_VARARGS, 0},
563    {__Pyx_NAMESTR("close"), (PyCFunction) __Pyx_Generator_Close, METH_NOARGS, 0},
564    {0, 0, 0, 0}
565};
566
567static PyTypeObject __pyx_GeneratorType_type = {
568    PyVarObject_HEAD_INIT(0, 0)
569    __Pyx_NAMESTR("generator"),         /*tp_name*/
570    sizeof(__pyx_GeneratorObject),      /*tp_basicsize*/
571    0,                                  /*tp_itemsize*/
572    (destructor) __Pyx_Generator_dealloc,/*tp_dealloc*/
573    0,                                  /*tp_print*/
574    0,                                  /*tp_getattr*/
575    0,                                  /*tp_setattr*/
576#if PY_MAJOR_VERSION < 3
577    0,                                  /*tp_compare*/
578#else
579    0,                                  /*reserved*/
580#endif
581    0,                                   /*tp_repr*/
582    0,                                  /*tp_as_number*/
583    0,                                  /*tp_as_sequence*/
584    0,                                  /*tp_as_mapping*/
585    0,                                  /*tp_hash*/
586    0,                                  /*tp_call*/
587    0,                                  /*tp_str*/
588    0,                                  /*tp_getattro*/
589    0,                                  /*tp_setattro*/
590    0,                                  /*tp_as_buffer*/
591    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags*/
592    0,                                  /*tp_doc*/
593    (traverseproc) __Pyx_Generator_traverse,   /*tp_traverse*/
594    0,                                  /*tp_clear*/
595    0,                                  /*tp_richcompare*/
596    offsetof(__pyx_GeneratorObject, gi_weakreflist), /* tp_weaklistoffse */
597    0,                                  /*tp_iter*/
598    (iternextfunc) __Pyx_Generator_Next, /*tp_iternext*/
599    __pyx_Generator_methods,            /*tp_methods*/
600    __pyx_Generator_memberlist,         /*tp_members*/
601    0,                                  /*tp_getset*/
602    0,                                  /*tp_base*/
603    0,                                  /*tp_dict*/
604    0,                                  /*tp_descr_get*/
605    0,                                  /*tp_descr_set*/
606    0,                                  /*tp_dictoffset*/
607    0,                                  /*tp_init*/
608    0,                                  /*tp_alloc*/
609    0,                                  /*tp_new*/
610    0,                                  /*tp_free*/
611    0,                                  /*tp_is_gc*/
612    0,                                  /*tp_bases*/
613    0,                                  /*tp_mro*/
614    0,                                  /*tp_cache*/
615    0,                                  /*tp_subclasses*/
616    0,                                  /*tp_weaklist*/
617#if PY_VERSION_HEX >= 0x030400a1
618    0,                                  /*tp_del*/
619#else
620    __Pyx_Generator_del,                /*tp_del*/
621#endif
622#if PY_VERSION_HEX >= 0x02060000
623    0,                                  /*tp_version_tag*/
624#endif
625#if PY_VERSION_HEX >= 0x030400a1
626    __Pyx_Generator_del,                /*tp_finalize*/
627#endif
628};
629
630static __pyx_GeneratorObject *__Pyx_Generator_New(__pyx_generator_body_t body,
631                                                  PyObject *closure) {
632    __pyx_GeneratorObject *gen =
633        PyObject_GC_New(__pyx_GeneratorObject, &__pyx_GeneratorType_type);
634
635    if (gen == NULL)
636        return NULL;
637
638    gen->body = body;
639    gen->closure = closure;
640    Py_XINCREF(closure);
641    gen->is_running = 0;
642    gen->resume_label = 0;
643    gen->classobj = NULL;
644    gen->yieldfrom = NULL;
645    gen->exc_type = NULL;
646    gen->exc_value = NULL;
647    gen->exc_traceback = NULL;
648    gen->gi_weakreflist = NULL;
649
650    PyObject_GC_Track(gen);
651    return gen;
652}
653
654static int __pyx_Generator_init(void) {
655    /* on Windows, C-API functions can't be used in slots statically */
656    __pyx_GeneratorType_type.tp_getattro = PyObject_GenericGetAttr;
657    __pyx_GeneratorType_type.tp_iter = PyObject_SelfIter;
658
659    __pyx_GeneratorType = __Pyx_FetchCommonType(&__pyx_GeneratorType_type);
660    if (__pyx_GeneratorType == NULL) {
661        return -1;
662    }
663    return 0;
664}
665