diff -r 67d0c0bdecd0 Modules/itertoolsmodule.c --- a/Modules/itertoolsmodule.c Thu Aug 16 10:35:24 2012 +0200 +++ b/Modules/itertoolsmodule.c Thu Aug 16 10:49:25 2012 +0200 @@ -20,7 +20,96 @@ PyObject *currvalue; } groupbyobject; -static PyTypeObject groupby_type; +typedef struct { + PyObject *groupby_type; + PyObject *_grouper_type; + PyObject *teedataobject_type; + PyObject *tee_type; + PyObject *cycle_type; + PyObject *dropwhile_type; + PyObject *takewhile_type; + PyObject *islice_type; + PyObject *starmap_type; + PyObject *chain_type; + PyObject *product_type; + PyObject *combinations_type; + PyObject *cwr_type; + PyObject *permutations_type; + PyObject *accumulate_type; + PyObject *compress_type; + PyObject *filterfalse_type; + PyObject *count_type; + PyObject *repeat_type; + PyObject *ziplongest_type; +} itertoolsstate; + + +#define itertools_state(o) ((itertoolsstate *)PyModule_GetState(o)) + +static int +itertools_clear(PyObject *m) +{ + itertoolsstate *state = itertools_state(m); + Py_CLEAR(state->groupby_type); + Py_CLEAR(state->_grouper_type); + Py_CLEAR(state->teedataobject_type); + Py_CLEAR(state->tee_type); + Py_CLEAR(state->cycle_type); + Py_CLEAR(state->dropwhile_type); + Py_CLEAR(state->takewhile_type); + Py_CLEAR(state->islice_type); + Py_CLEAR(state->starmap_type); + Py_CLEAR(state->chain_type); + Py_CLEAR(state->product_type); + Py_CLEAR(state->combinations_type); + Py_CLEAR(state->cwr_type); + Py_CLEAR(state->permutations_type); + Py_CLEAR(state->accumulate_type); + Py_CLEAR(state->compress_type); + Py_CLEAR(state->filterfalse_type); + Py_CLEAR(state->count_type); + Py_CLEAR(state->repeat_type); + Py_CLEAR(state->ziplongest_type); + return 0; +} + +static int +itertools_traverse(PyObject *m, visitproc visit, void *arg) +{ + itertoolsstate *state = itertools_state(m); + Py_VISIT(state->groupby_type); + Py_VISIT(state->_grouper_type); + Py_VISIT(state->teedataobject_type); + Py_VISIT(state->tee_type); + Py_VISIT(state->cycle_type); + Py_VISIT(state->dropwhile_type); + Py_VISIT(state->takewhile_type); + Py_VISIT(state->islice_type); + Py_VISIT(state->starmap_type); + Py_VISIT(state->chain_type); + Py_VISIT(state->product_type); + Py_VISIT(state->combinations_type); + Py_VISIT(state->cwr_type); + Py_VISIT(state->permutations_type); + Py_VISIT(state->accumulate_type); + Py_VISIT(state->compress_type); + Py_VISIT(state->filterfalse_type); + Py_VISIT(state->count_type); + Py_VISIT(state->repeat_type); + Py_VISIT(state->ziplongest_type); + return 0; +} + +static void +itertools_free(void *m) +{ + itertools_clear((PyObject *)m); +} + +static PyModuleDef itertoolsmodule; + +#define itertoolsstate_global ((itertoolsstate *)PyModule_GetState(PyState_FindModule(&itertoolsmodule))) + static PyObject *_grouper_create(groupbyobject *, PyObject *); static PyObject * @@ -47,19 +136,24 @@ Py_DECREF(gbo); return NULL; } + Py_INCREF(type); return (PyObject *)gbo; } static void groupby_dealloc(groupbyobject *gbo) { + PyTypeObject *type = Py_TYPE(gbo); PyObject_GC_UnTrack(gbo); Py_XDECREF(gbo->it); Py_XDECREF(gbo->keyfunc); Py_XDECREF(gbo->tgtkey); Py_XDECREF(gbo->currkey); Py_XDECREF(gbo->currvalue); - Py_TYPE(gbo)->tp_free(gbo); + type->tp_free(gbo); + if((void *)type->tp_dealloc == (void *)groupby_dealloc) { + Py_DECREF(type); + } } static int @@ -148,6 +242,7 @@ value = Py_BuildValue("O(OO)", Py_TYPE(lz), lz->it, lz->keyfunc); + Py_INCREF(Py_TYPE(lz)); return value; } @@ -185,51 +280,31 @@ "groupby(iterable[, keyfunc]) -> create an iterator which returns\n\ (key, sub-iterator) grouped by each value of key(value).\n"); -static PyTypeObject groupby_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "itertools.groupby", /* tp_name */ - sizeof(groupbyobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)groupby_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_reserved */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ + +static PyType_Slot groupby_type_slots[] = { + {Py_tp_dealloc, (destructor)groupby_dealloc}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_doc, groupby_doc}, + {Py_tp_traverse, (traverseproc)groupby_traverse}, + {Py_tp_iter, PyObject_SelfIter}, + {Py_tp_iternext, (iternextfunc)groupby_next}, + {Py_tp_methods, groupby_methods}, + {Py_tp_new, groupby_new}, + {Py_tp_free, PyObject_GC_Del}, + {0, 0} +}; + +static PyType_Spec groupby_type_spec = { + "itertools.groupby", + sizeof(groupbyobject), + 0, Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_BASETYPE, /* tp_flags */ - groupby_doc, /* tp_doc */ - (traverseproc)groupby_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)groupby_next, /* tp_iternext */ - groupby_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 */ - groupby_new, /* tp_new */ - PyObject_GC_Del, /* tp_free */ + Py_TPFLAGS_BASETYPE, + groupby_type_slots, }; + /* _grouper object (internal) ************************************************/ typedef struct { @@ -238,14 +313,12 @@ PyObject *tgtkey; } _grouperobject; -static PyTypeObject _grouper_type; - static PyObject * _grouper_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { PyObject *parent, *tgtkey; - if (!PyArg_ParseTuple(args, "O!O", &groupby_type, &parent, &tgtkey)) + if (!PyArg_ParseTuple(args, "O!O", itertoolsstate_global->groupby_type, &parent, &tgtkey)) return NULL; return _grouper_create((groupbyobject*) parent, tgtkey); @@ -256,9 +329,11 @@ { _grouperobject *igo; - igo = PyObject_GC_New(_grouperobject, &_grouper_type); + igo = PyObject_GC_New(_grouperobject, + (PyTypeObject *)itertoolsstate_global->_grouper_type); if (igo == NULL) return NULL; + Py_INCREF(itertoolsstate_global->_grouper_type); igo->parent = (PyObject *)parent; Py_INCREF(parent); igo->tgtkey = tgtkey; @@ -271,10 +346,14 @@ static void _grouper_dealloc(_grouperobject *igo) { + PyTypeObject *type = Py_TYPE(igo); PyObject_GC_UnTrack(igo); Py_DECREF(igo->parent); Py_DECREF(igo->tgtkey); PyObject_GC_Del(igo); + if((void *)type->tp_dealloc == (void *)_grouper_dealloc) { + Py_DECREF(type); + } } static int @@ -330,6 +409,7 @@ static PyObject * _grouper_reduce(_grouperobject *lz) { + Py_INCREF(Py_TYPE(lz)); return Py_BuildValue("O(OO)", Py_TYPE(lz), lz->parent, lz->tgtkey); } @@ -340,51 +420,25 @@ {NULL, NULL} /* sentinel */ }; - -static PyTypeObject _grouper_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "itertools._grouper", /* tp_name */ - sizeof(_grouperobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)_grouper_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_reserved */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ - 0, /* tp_doc */ - (traverseproc)_grouper_traverse,/* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)_grouper_next, /* tp_iternext */ - _grouper_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 */ - _grouper_new, /* tp_new */ - PyObject_GC_Del, /* tp_free */ +static PyType_Slot _grouper_type_slots[] = { + {Py_tp_dealloc, (destructor)_grouper_dealloc}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_traverse, (traverseproc)_grouper_traverse}, + {Py_tp_iter, PyObject_SelfIter}, + {Py_tp_iternext, (iternextfunc)_grouper_next}, + {Py_tp_methods, _grouper_methods}, + {Py_tp_new, _grouper_new}, + {Py_tp_free, PyObject_GC_Del}, + {0, 0} }; - +static PyType_Spec _grouper_type_spec = { + "itertools._grouper", + sizeof(_grouperobject), + 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, + _grouper_type_slots, +}; /* tee object and with supporting function and objects ***************/ @@ -413,17 +467,17 @@ PyObject *weakreflist; } teeobject; -static PyTypeObject teedataobject_type; - static PyObject * teedataobject_newinternal(PyObject *it) { teedataobject *tdo; - tdo = PyObject_GC_New(teedataobject, &teedataobject_type); + tdo = PyObject_GC_New(teedataobject, + (PyTypeObject *)itertoolsstate_global->teedataobject_type); if (tdo == NULL) return NULL; + Py_INCREF(itertoolsstate_global->teedataobject_type); tdo->numread = 0; tdo->nextlink = NULL; Py_INCREF(it); @@ -487,8 +541,12 @@ static void teedataobject_dealloc(teedataobject *tdo) { + PyTypeObject *type = Py_TYPE(tdo); PyObject_GC_UnTrack(tdo); teedataobject_clear(tdo); + if((void *)type->tp_dealloc == (void *)teedataobject_dealloc) { + Py_DECREF(type); + } PyObject_GC_Del(tdo); } @@ -504,13 +562,12 @@ Py_INCREF(tdo->values[i]); PyList_SET_ITEM(values, i, tdo->values[i]); } + Py_INCREF(Py_TYPE(tdo)); return Py_BuildValue("O(ONO)", Py_TYPE(tdo), tdo->it, values, tdo->nextlink ? tdo->nextlink : Py_None); } -static PyTypeObject teedataobject_type; - static PyObject * teedataobject_new(PyTypeObject *type, PyObject *args, PyObject *kw) { @@ -518,7 +575,7 @@ PyObject *it, *values, *next; Py_ssize_t i, len; - assert(type == &teedataobject_type); + assert(type == (PyTypeObject *)itertoolsstate_global->teedataobject_type); if (!PyArg_ParseTuple(args, "OO!O", &it, &PyList_Type, &values, &next)) return NULL; @@ -538,7 +595,7 @@ if (len == LINKCELLS) { if (next != Py_None) { - if (Py_TYPE(next) != &teedataobject_type) + if (Py_TYPE(next) != (PyTypeObject *)itertoolsstate_global->teedataobject_type) goto err; assert(tdo->nextlink == NULL); Py_INCREF(next); @@ -564,51 +621,25 @@ PyDoc_STRVAR(teedataobject_doc, "Data container common to multiple tee objects."); -static PyTypeObject teedataobject_type = { - PyVarObject_HEAD_INIT(0, 0) /* Must fill in type value later */ - "itertools._tee_dataobject", /* tp_name */ - sizeof(teedataobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)teedataobject_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_reserved */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ - teedataobject_doc, /* tp_doc */ - (traverseproc)teedataobject_traverse, /* tp_traverse */ - (inquiry)teedataobject_clear, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - teedataobject_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 */ - teedataobject_new, /* tp_new */ - PyObject_GC_Del, /* tp_free */ +static PyType_Slot teedataobject_type_slots[] = { + {Py_tp_dealloc, (destructor)teedataobject_dealloc}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_doc, teedataobject_doc}, + {Py_tp_traverse, (traverseproc)teedataobject_traverse}, + {Py_tp_clear, (inquiry)teedataobject_clear}, + {Py_tp_methods, teedataobject_methods}, + {Py_tp_new, teedataobject_new}, + {Py_tp_free, PyObject_GC_Del}, + {0, 0} }; - -static PyTypeObject tee_type; +static PyType_Spec teedataobject_type_spec = { + "itertools._tee_dataobject", + sizeof(teedataobject), + 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, + teedataobject_type_slots, +}; static PyObject * tee_next(teeobject *to) @@ -640,9 +671,11 @@ { teeobject *newto; - newto = PyObject_GC_New(teeobject, &tee_type); + newto = PyObject_GC_New(teeobject, + (PyTypeObject *)itertoolsstate_global->tee_type); if (newto == NULL) return NULL; + Py_INCREF(itertoolsstate_global->tee_type); Py_INCREF(to->dataobj); newto->dataobj = to->dataobj; newto->index = to->index; @@ -662,14 +695,16 @@ it = PyObject_GetIter(iterable); if (it == NULL) return NULL; - if (PyObject_TypeCheck(it, &tee_type)) { + if (PyObject_TypeCheck(it, (PyTypeObject *)itertoolsstate_global->tee_type)) { to = (teeobject *)tee_copy((teeobject *)it); goto done; } - to = PyObject_GC_New(teeobject, &tee_type); + to = PyObject_GC_New(teeobject, + (PyTypeObject *)itertoolsstate_global->tee_type); if (to == NULL) goto done; + Py_INCREF(itertoolsstate_global->tee_type); to->dataobj = (teedataobject *)teedataobject_newinternal(it); if (!to->dataobj) { PyObject_GC_Del(to); @@ -692,6 +727,7 @@ if (!PyArg_UnpackTuple(args, "_tee", 1, 1, &iterable)) return NULL; + Py_INCREF(type); return tee_fromiterable(iterable); } @@ -707,14 +743,19 @@ static void tee_dealloc(teeobject *to) { + PyTypeObject *type = Py_TYPE(to); PyObject_GC_UnTrack(to); tee_clear(to); + if((void *)type->tp_dealloc == (void *)tee_dealloc) { + Py_DECREF(type); + } PyObject_GC_Del(to); } static PyObject * tee_reduce(teeobject *to) { + Py_INCREF(Py_TYPE(to)); return Py_BuildValue("O(())(Oi)", Py_TYPE(to), to->dataobj, to->index); } @@ -723,7 +764,7 @@ { teedataobject *tdo; int index; - if (!PyArg_ParseTuple(state, "O!i", &teedataobject_type, &tdo, &index)) + if (!PyArg_ParseTuple(state, "O!i", itertoolsstate_global->teedataobject_type, &tdo, &index)) return NULL; if (index < 0 || index > LINKCELLS) { PyErr_SetString(PyExc_ValueError, "Index out of range"); @@ -746,49 +787,28 @@ {NULL, NULL} /* sentinel */ }; -static PyTypeObject tee_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "itertools._tee", /* tp_name */ - sizeof(teeobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)tee_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_reserved */ - 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 */ - teeobject_doc, /* tp_doc */ - (traverseproc)tee_traverse, /* tp_traverse */ - (inquiry)tee_clear, /* tp_clear */ - 0, /* tp_richcompare */ - offsetof(teeobject, weakreflist), /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)tee_next, /* tp_iternext */ - tee_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 */ - tee_new, /* tp_new */ - PyObject_GC_Del, /* tp_free */ +static PyType_Slot tee_type_slots[] = { + {Py_tp_dealloc, (destructor)tee_dealloc}, + {Py_tp_doc, teeobject_doc}, + {Py_tp_traverse, (traverseproc)tee_traverse}, + {Py_tp_clear, (inquiry)tee_clear}, + {Py_tp_iter, PyObject_SelfIter}, + {Py_tp_iternext, (iternextfunc)tee_next}, + {Py_tp_methods, tee_methods}, + {Py_tp_new, tee_new}, + {Py_tp_free, PyObject_GC_Del}, + {0, 0} }; +static PyType_Spec tee_type_spec = { + "itertools._tee", + sizeof(teeobject), + 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, + tee_type_slots, +}; + + static PyObject * tee(PyObject *self, PyObject *args) { @@ -847,8 +867,6 @@ int firstpass; } cycleobject; -static PyTypeObject cycle_type; - static PyObject * cycle_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { @@ -857,7 +875,7 @@ PyObject *saved; cycleobject *lz; - if (type == &cycle_type && !_PyArg_NoKeywords("cycle()", kwds)) + if (type == (PyTypeObject *)itertoolsstate_global->cycle_type && !_PyArg_NoKeywords("cycle()", kwds)) return NULL; if (!PyArg_UnpackTuple(args, "cycle", 1, 1, &iterable)) @@ -881,6 +899,7 @@ Py_DECREF(saved); return NULL; } + Py_INCREF(type); lz->it = it; lz->saved = saved; lz->firstpass = 0; @@ -891,10 +910,14 @@ static void cycle_dealloc(cycleobject *lz) { + PyTypeObject *type = Py_TYPE(lz); PyObject_GC_UnTrack(lz); Py_XDECREF(lz->saved); Py_XDECREF(lz->it); - Py_TYPE(lz)->tp_free(lz); + type->tp_free(lz); + if((void *)type->tp_dealloc == (void *)cycle_dealloc) { + Py_DECREF(type); + } } static int @@ -945,6 +968,7 @@ /* Create a new cycle with the iterator tuple, then set * the saved state on it. */ + Py_INCREF(Py_TYPE(lz)); return Py_BuildValue("O(O)(Oi)", Py_TYPE(lz), lz->it, lz->saved, lz->firstpass); } @@ -977,51 +1001,33 @@ Return elements from the iterable until it is exhausted.\n\ Then repeat the sequence indefinitely."); -static PyTypeObject cycle_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "itertools.cycle", /* tp_name */ - sizeof(cycleobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)cycle_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_reserved */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ + + + +static PyType_Slot cycle_type_slots[] = { + {Py_tp_dealloc, (destructor)cycle_dealloc}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_doc, cycle_doc}, + {Py_tp_traverse, (traverseproc)cycle_traverse}, + {Py_tp_iter, PyObject_SelfIter}, + {Py_tp_iternext, (iternextfunc)cycle_next}, + {Py_tp_methods, cycle_methods}, + {Py_tp_new, cycle_new}, + {Py_tp_free, PyObject_GC_Del}, + {0, 0} +}; + +static PyType_Spec cycle_type_spec = { + "itertools.cycle", + sizeof(cycleobject), + 0, Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_BASETYPE, /* tp_flags */ - cycle_doc, /* tp_doc */ - (traverseproc)cycle_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)cycle_next, /* tp_iternext */ - cycle_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 */ - cycle_new, /* tp_new */ - PyObject_GC_Del, /* tp_free */ + Py_TPFLAGS_BASETYPE, + cycle_type_slots, }; + /* dropwhile object **********************************************************/ typedef struct { @@ -1031,8 +1037,6 @@ long start; } dropwhileobject; -static PyTypeObject dropwhile_type; - static PyObject * dropwhile_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { @@ -1040,7 +1044,7 @@ PyObject *it; dropwhileobject *lz; - if (type == &dropwhile_type && !_PyArg_NoKeywords("dropwhile()", kwds)) + if (type == (PyTypeObject *)itertoolsstate_global->dropwhile_type && !_PyArg_NoKeywords("dropwhile()", kwds)) return NULL; if (!PyArg_UnpackTuple(args, "dropwhile", 2, 2, &func, &seq)) @@ -1057,6 +1061,7 @@ Py_DECREF(it); return NULL; } + Py_INCREF(type); Py_INCREF(func); lz->func = func; lz->it = it; @@ -1068,10 +1073,14 @@ static void dropwhile_dealloc(dropwhileobject *lz) { + PyTypeObject *type = Py_TYPE(lz); PyObject_GC_UnTrack(lz); Py_XDECREF(lz->func); Py_XDECREF(lz->it); - Py_TYPE(lz)->tp_free(lz); + type->tp_free(lz); + if((void *)type->tp_dealloc == (void *)dropwhile_dealloc) { + Py_DECREF(type); + } } static int @@ -1116,6 +1125,7 @@ static PyObject * dropwhile_reduce(dropwhileobject *lz) { + Py_INCREF(Py_TYPE(lz)); return Py_BuildValue("O(OO)l", Py_TYPE(lz), lz->func, lz->it, lz->start); } @@ -1144,51 +1154,31 @@ Drop items from the iterable while predicate(item) is true.\n\ Afterwards, return every element until the iterable is exhausted."); -static PyTypeObject dropwhile_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "itertools.dropwhile", /* tp_name */ - sizeof(dropwhileobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)dropwhile_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_reserved */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ + +static PyType_Slot dropwhile_type_slots[] = { + {Py_tp_dealloc, (destructor)dropwhile_dealloc}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_doc, dropwhile_doc}, + {Py_tp_traverse, (traverseproc)dropwhile_traverse}, + {Py_tp_iter, PyObject_SelfIter}, + {Py_tp_iternext, (iternextfunc)dropwhile_next}, + {Py_tp_methods, dropwhile_methods}, + {Py_tp_new, dropwhile_new}, + {Py_tp_free, PyObject_GC_Del}, + {0, 0} +}; + +static PyType_Spec dropwhile_type_spec = { + "itertools.dropwhile", + sizeof(dropwhileobject), + 0, Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_BASETYPE, /* tp_flags */ - dropwhile_doc, /* tp_doc */ - (traverseproc)dropwhile_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)dropwhile_next, /* tp_iternext */ - dropwhile_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 */ - dropwhile_new, /* tp_new */ - PyObject_GC_Del, /* tp_free */ + Py_TPFLAGS_BASETYPE, + dropwhile_type_slots, }; + /* takewhile object **********************************************************/ typedef struct { @@ -1198,8 +1188,6 @@ long stop; } takewhileobject; -static PyTypeObject takewhile_type; - static PyObject * takewhile_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { @@ -1207,7 +1195,7 @@ PyObject *it; takewhileobject *lz; - if (type == &takewhile_type && !_PyArg_NoKeywords("takewhile()", kwds)) + if (type == (PyTypeObject *)itertoolsstate_global->takewhile_type && !_PyArg_NoKeywords("takewhile()", kwds)) return NULL; if (!PyArg_UnpackTuple(args, "takewhile", 2, 2, &func, &seq)) @@ -1224,6 +1212,7 @@ Py_DECREF(it); return NULL; } + Py_INCREF(type); Py_INCREF(func); lz->func = func; lz->it = it; @@ -1235,10 +1224,14 @@ static void takewhile_dealloc(takewhileobject *lz) { + PyTypeObject *type = Py_TYPE(lz); PyObject_GC_UnTrack(lz); Py_XDECREF(lz->func); Py_XDECREF(lz->it); - Py_TYPE(lz)->tp_free(lz); + type->tp_free(lz); + if((void *)type->tp_dealloc == (void *)takewhile_dealloc) { + Py_DECREF(type); + } } static int @@ -1280,6 +1273,7 @@ static PyObject * takewhile_reduce(takewhileobject *lz) { + Py_INCREF(Py_TYPE(lz)); return Py_BuildValue("O(OO)l", Py_TYPE(lz), lz->func, lz->it, lz->stop); } @@ -1307,51 +1301,33 @@ Return successive entries from an iterable as long as the \n\ predicate evaluates to true for each entry."); -static PyTypeObject takewhile_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "itertools.takewhile", /* tp_name */ - sizeof(takewhileobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)takewhile_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_reserved */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ + + + +static PyType_Slot takewhile_type_slots[] = { + {Py_tp_dealloc, (destructor)takewhile_dealloc}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_doc, takewhile_doc}, + {Py_tp_traverse, (traverseproc)takewhile_traverse}, + {Py_tp_iter, PyObject_SelfIter}, + {Py_tp_iternext, (iternextfunc)takewhile_next}, + {Py_tp_methods, takewhile_reduce_methods}, + {Py_tp_new, takewhile_new}, + {Py_tp_free, PyObject_GC_Del}, + {0, 0} +}; + +static PyType_Spec takewhile_type_spec = { + "itertools.takewhile", + sizeof(takewhileobject), + 0, Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_BASETYPE, /* tp_flags */ - takewhile_doc, /* tp_doc */ - (traverseproc)takewhile_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)takewhile_next, /* tp_iternext */ - takewhile_reduce_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 */ - takewhile_new, /* tp_new */ - PyObject_GC_Del, /* tp_free */ + Py_TPFLAGS_BASETYPE, + takewhile_type_slots, }; + /* islice object ************************************************************/ typedef struct { @@ -1363,8 +1339,6 @@ Py_ssize_t cnt; } isliceobject; -static PyTypeObject islice_type; - static PyObject * islice_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { @@ -1374,7 +1348,7 @@ Py_ssize_t numargs; isliceobject *lz; - if (type == &islice_type && !_PyArg_NoKeywords("islice()", kwds)) + if (type == (PyTypeObject *)itertoolsstate_global->islice_type && !_PyArg_NoKeywords("islice()", kwds)) return NULL; if (!PyArg_UnpackTuple(args, "islice", 2, 4, &seq, &a1, &a2, &a3)) @@ -1437,6 +1411,7 @@ Py_DECREF(it); return NULL; } + Py_INCREF(type); lz->it = it; lz->next = start; lz->stop = stop; @@ -1449,9 +1424,13 @@ static void islice_dealloc(isliceobject *lz) { + PyTypeObject *type = Py_TYPE(lz); PyObject_GC_UnTrack(lz); Py_XDECREF(lz->it); - Py_TYPE(lz)->tp_free(lz); + type->tp_free(lz); + if((void *)type->tp_dealloc == (void *)islice_dealloc) { + Py_DECREF(type); + } } static int @@ -1508,6 +1487,7 @@ if (stop == NULL) return NULL; } + Py_INCREF(Py_TYPE(lz)); return Py_BuildValue("O(OnNn)n", Py_TYPE(lz), lz->it, lz->next, stop, lz->step, lz->cnt); @@ -1541,51 +1521,33 @@ skipped between successive calls. Works like a slice() on a list\n\ but returns an iterator."); -static PyTypeObject islice_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "itertools.islice", /* tp_name */ - sizeof(isliceobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)islice_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_reserved */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ + + + +static PyType_Slot islice_type_slots[] = { + {Py_tp_dealloc, (destructor)islice_dealloc}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_doc, islice_doc}, + {Py_tp_traverse, (traverseproc)islice_traverse}, + {Py_tp_iter, PyObject_SelfIter}, + {Py_tp_iternext, (iternextfunc)islice_next}, + {Py_tp_methods, islice_methods}, + {Py_tp_new, islice_new}, + {Py_tp_free, PyObject_GC_Del}, + {0, 0} +}; + +static PyType_Spec islice_type_spec = { + "itertools.islice", + sizeof(isliceobject), + 0, Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_BASETYPE, /* tp_flags */ - islice_doc, /* tp_doc */ - (traverseproc)islice_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)islice_next, /* tp_iternext */ - islice_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 */ - islice_new, /* tp_new */ - PyObject_GC_Del, /* tp_free */ + Py_TPFLAGS_BASETYPE, + islice_type_slots, }; + /* starmap object ************************************************************/ typedef struct { @@ -1594,8 +1556,6 @@ PyObject *it; } starmapobject; -static PyTypeObject starmap_type; - static PyObject * starmap_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { @@ -1603,7 +1563,7 @@ PyObject *it; starmapobject *lz; - if (type == &starmap_type && !_PyArg_NoKeywords("starmap()", kwds)) + if (type == (PyTypeObject *)itertoolsstate_global->starmap_type && !_PyArg_NoKeywords("starmap()", kwds)) return NULL; if (!PyArg_UnpackTuple(args, "starmap", 2, 2, &func, &seq)) @@ -1620,6 +1580,7 @@ Py_DECREF(it); return NULL; } + Py_INCREF(type); Py_INCREF(func); lz->func = func; lz->it = it; @@ -1630,10 +1591,14 @@ static void starmap_dealloc(starmapobject *lz) { + PyTypeObject *type = Py_TYPE(lz); PyObject_GC_UnTrack(lz); Py_XDECREF(lz->func); Py_XDECREF(lz->it); - Py_TYPE(lz)->tp_free(lz); + type->tp_free(lz); + if((void *)type->tp_dealloc == (void *)starmap_dealloc) { + Py_DECREF(type); + } } static int @@ -1670,6 +1635,7 @@ starmap_reduce(starmapobject *lz) { /* Just pickle the iterator */ + Py_INCREF(Py_TYPE(lz)); return Py_BuildValue("O(OO)", Py_TYPE(lz), lz->func, lz->it); } @@ -1685,51 +1651,33 @@ Return an iterator whose values are returned from the function evaluated\n\ with a argument tuple taken from the given sequence."); -static PyTypeObject starmap_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "itertools.starmap", /* tp_name */ - sizeof(starmapobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)starmap_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_reserved */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ + + + +static PyType_Slot starmap_type_slots[] = { + {Py_tp_dealloc, (destructor)starmap_dealloc}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_doc, starmap_doc}, + {Py_tp_traverse, (traverseproc)starmap_traverse}, + {Py_tp_iter, PyObject_SelfIter}, + {Py_tp_iternext, (iternextfunc)starmap_next}, + {Py_tp_methods, starmap_methods}, + {Py_tp_new, starmap_new}, + {Py_tp_free, PyObject_GC_Del}, + {0, 0} +}; + +static PyType_Spec starmap_type_spec = { + "itertools.starmap", + sizeof(starmapobject), + 0, Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_BASETYPE, /* tp_flags */ - starmap_doc, /* tp_doc */ - (traverseproc)starmap_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)starmap_next, /* tp_iternext */ - starmap_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 */ - starmap_new, /* tp_new */ - PyObject_GC_Del, /* tp_free */ + Py_TPFLAGS_BASETYPE, + starmap_type_slots, }; + /* chain object ************************************************************/ typedef struct { @@ -1738,8 +1686,6 @@ PyObject *active; /* Currently running input iterator */ } chainobject; -static PyTypeObject chain_type; - static PyObject * chain_new_internal(PyTypeObject *type, PyObject *source) { @@ -1750,6 +1696,7 @@ Py_DECREF(source); return NULL; } + Py_INCREF(type); lz->source = source; lz->active = NULL; @@ -1761,7 +1708,7 @@ { PyObject *source; - if (type == &chain_type && !_PyArg_NoKeywords("chain()", kwds)) + if (type == (PyTypeObject *)itertoolsstate_global->chain_type && !_PyArg_NoKeywords("chain()", kwds)) return NULL; source = PyObject_GetIter(args); @@ -1786,10 +1733,14 @@ static void chain_dealloc(chainobject *lz) { + PyTypeObject *type = Py_TYPE(lz); PyObject_GC_UnTrack(lz); Py_XDECREF(lz->active); Py_XDECREF(lz->source); - Py_TYPE(lz)->tp_free(lz); + type->tp_free(lz); + if((void *)type->tp_dealloc == (void *)chain_dealloc) { + Py_DECREF(type); + } } static int @@ -1837,6 +1788,7 @@ static PyObject * chain_reduce(chainobject *lz) { + Py_INCREF(Py_TYPE(lz)); if (lz->source) { /* we can't pickle function objects (itertools.from_iterable) so * we must use setstate to replace the iterable. One day we @@ -1850,6 +1802,7 @@ } else { return Py_BuildValue("O()", Py_TYPE(lz)); /* exhausted */ } + Py_DECREF(Py_TYPE(lz)); return NULL; } @@ -1892,51 +1845,33 @@ {NULL, NULL} /* sentinel */ }; -static PyTypeObject chain_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "itertools.chain", /* tp_name */ - sizeof(chainobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)chain_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_reserved */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ + + + +static PyType_Slot chain_type_slots[] = { + {Py_tp_dealloc, (destructor)chain_dealloc}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_doc, chain_doc}, + {Py_tp_traverse, (traverseproc)chain_traverse}, + {Py_tp_iter, PyObject_SelfIter}, + {Py_tp_iternext, (iternextfunc)chain_next}, + {Py_tp_methods, chain_methods}, + {Py_tp_new, chain_new}, + {Py_tp_free, PyObject_GC_Del}, + {0, 0} +}; + +static PyType_Spec chain_type_spec = { + "itertools.chain", + sizeof(chainobject), + 0, Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_BASETYPE, /* tp_flags */ - chain_doc, /* tp_doc */ - (traverseproc)chain_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)chain_next, /* tp_iternext */ - chain_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 */ - chain_new, /* tp_new */ - PyObject_GC_Del, /* tp_free */ + Py_TPFLAGS_BASETYPE, + chain_type_slots, }; + /* product object ************************************************************/ typedef struct { @@ -1947,8 +1882,6 @@ int stopped; /* set to 1 when the product iterator is exhausted */ } productobject; -static PyTypeObject product_type; - static PyObject * product_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { @@ -2008,6 +1941,7 @@ lz = (productobject *)type->tp_alloc(type, 0); if (lz == NULL) goto error; + Py_INCREF(type); lz->pools = pools; lz->indices = indices; @@ -2026,12 +1960,16 @@ static void product_dealloc(productobject *lz) { + PyTypeObject *type = Py_TYPE(lz); PyObject_GC_UnTrack(lz); Py_XDECREF(lz->pools); Py_XDECREF(lz->result); if (lz->indices != NULL) PyMem_Free(lz->indices); - Py_TYPE(lz)->tp_free(lz); + type->tp_free(lz); + if((void *)type->tp_dealloc == (void *)product_dealloc) { + Py_DECREF(type); + } } static int @@ -2133,8 +2071,10 @@ product_reduce(productobject *lz) { if (lz->stopped) { + Py_INCREF(Py_TYPE(lz)); return Py_BuildValue("O(())", Py_TYPE(lz)); } else if (lz->result == NULL) { + Py_INCREF(Py_TYPE(lz)); return Py_BuildValue("OO", Py_TYPE(lz), lz->pools); } else { PyObject *indices; @@ -2155,6 +2095,7 @@ } PyTuple_SET_ITEM(indices, i, index); } + Py_INCREF(Py_TYPE(lz)); return Py_BuildValue("OON", Py_TYPE(lz), lz->pools, indices); } } @@ -2220,51 +2161,33 @@ product('ab', range(3)) --> ('a',0) ('a',1) ('a',2) ('b',0) ('b',1) ('b',2)\n\ product((0,1), (0,1), (0,1)) --> (0,0,0) (0,0,1) (0,1,0) (0,1,1) (1,0,0) ..."); -static PyTypeObject product_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "itertools.product", /* tp_name */ - sizeof(productobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)product_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_reserved */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ + + + +static PyType_Slot product_type_slots[] = { + {Py_tp_dealloc, (destructor)product_dealloc}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_doc, product_doc}, + {Py_tp_traverse, (traverseproc)product_traverse}, + {Py_tp_iter, PyObject_SelfIter}, + {Py_tp_iternext, (iternextfunc)product_next}, + {Py_tp_methods, product_methods}, + {Py_tp_new, product_new}, + {Py_tp_free, PyObject_GC_Del}, + {0, 0} +}; + +static PyType_Spec product_type_spec = { + "itertools.product", + sizeof(productobject), + 0, Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_BASETYPE, /* tp_flags */ - product_doc, /* tp_doc */ - (traverseproc)product_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)product_next, /* tp_iternext */ - product_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 */ - product_new, /* tp_new */ - PyObject_GC_Del, /* tp_free */ + Py_TPFLAGS_BASETYPE, + product_type_slots, }; + /* combinations object ************************************************************/ typedef struct { @@ -2276,8 +2199,6 @@ int stopped; /* set to 1 when the combinations iterator is exhausted */ } combinationsobject; -static PyTypeObject combinations_type; - static PyObject * combinations_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { @@ -2316,6 +2237,7 @@ co = (combinationsobject *)type->tp_alloc(type, 0); if (co == NULL) goto error; + Py_INCREF(type); co->pool = pool; co->indices = indices; @@ -2335,12 +2257,16 @@ static void combinations_dealloc(combinationsobject *co) { + PyTypeObject *type = Py_TYPE(co); PyObject_GC_UnTrack(co); Py_XDECREF(co->pool); Py_XDECREF(co->result); if (co->indices != NULL) PyMem_Free(co->indices); - Py_TYPE(co)->tp_free(co); + type->tp_free(co); + if((void *)type->tp_dealloc == (void *)combinations_dealloc) { + Py_DECREF(type); + } } static int @@ -2441,8 +2367,10 @@ combinations_reduce(combinationsobject *lz) { if (lz->result == NULL) { + Py_INCREF(Py_TYPE(lz)); return Py_BuildValue("O(On)", Py_TYPE(lz), lz->pool, lz->r); } else if (lz->stopped) { + Py_INCREF(Py_TYPE(lz)); return Py_BuildValue("O(()n)", Py_TYPE(lz), lz->r); } else { PyObject *indices; @@ -2461,7 +2389,7 @@ } PyTuple_SET_ITEM(indices, i, index); } - + Py_INCREF(Py_TYPE(lz)); return Py_BuildValue("O(On)N", Py_TYPE(lz), lz->pool, lz->r, indices); } } @@ -2523,51 +2451,33 @@ Return successive r-length combinations of elements in the iterable.\n\n\ combinations(range(4), 3) --> (0,1,2), (0,1,3), (0,2,3), (1,2,3)"); -static PyTypeObject combinations_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "itertools.combinations", /* tp_name */ - sizeof(combinationsobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)combinations_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_reserved */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ + + + +static PyType_Slot combinations_type_slots[] = { + {Py_tp_dealloc, (destructor)combinations_dealloc}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_doc, combinations_doc}, + {Py_tp_traverse, (traverseproc)combinations_traverse}, + {Py_tp_iter, PyObject_SelfIter}, + {Py_tp_iternext, (iternextfunc)combinations_next}, + {Py_tp_methods, combinations_methods}, + {Py_tp_new, combinations_new}, + {Py_tp_free, PyObject_GC_Del}, + {0, 0} +}; + +static PyType_Spec combinations_type_spec = { + "itertools.combinations", + sizeof(combinationsobject), + 0, Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_BASETYPE, /* tp_flags */ - combinations_doc, /* tp_doc */ - (traverseproc)combinations_traverse,/* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)combinations_next, /* tp_iternext */ - combinations_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 */ - combinations_new, /* tp_new */ - PyObject_GC_Del, /* tp_free */ + Py_TPFLAGS_BASETYPE, + combinations_type_slots, }; + /* combinations with replacement object *******************************************/ /* Equivalent to: @@ -2605,8 +2515,6 @@ int stopped; /* set to 1 when the cwr iterator is exhausted */ } cwrobject; -static PyTypeObject cwr_type; - static PyObject * cwr_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { @@ -2645,6 +2553,7 @@ co = (cwrobject *)type->tp_alloc(type, 0); if (co == NULL) goto error; + Py_INCREF(type); co->pool = pool; co->indices = indices; @@ -2664,12 +2573,16 @@ static void cwr_dealloc(cwrobject *co) { + PyTypeObject *type = Py_TYPE(co); PyObject_GC_UnTrack(co); Py_XDECREF(co->pool); Py_XDECREF(co->result); if (co->indices != NULL) PyMem_Free(co->indices); - Py_TYPE(co)->tp_free(co); + type->tp_free(co); + if((void *)type->tp_dealloc == (void *)cwr_dealloc) { + Py_DECREF(type); + } } static int @@ -2766,8 +2679,10 @@ cwr_reduce(cwrobject *lz) { if (lz->result == NULL) { + Py_INCREF(Py_TYPE(lz)); return Py_BuildValue("O(On)", Py_TYPE(lz), lz->pool, lz->r); } else if (lz->stopped) { + Py_INCREF(Py_TYPE(lz)); return Py_BuildValue("O(()n)", Py_TYPE(lz), lz->r); } else { PyObject *indices; @@ -2786,7 +2701,7 @@ } PyTuple_SET_ITEM(indices, i, index); } - + Py_INCREF(Py_TYPE(lz)); return Py_BuildValue("O(On)N", Py_TYPE(lz), lz->pool, lz->r, indices); } } @@ -2845,51 +2760,33 @@ allowing individual elements to have successive repeats.\n\ combinations_with_replacement('ABC', 2) --> AA AB AC BB BC CC"); -static PyTypeObject cwr_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "itertools.combinations_with_replacement", /* tp_name */ - sizeof(cwrobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)cwr_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_reserved */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ + + + +static PyType_Slot cwr_type_slots[] = { + {Py_tp_dealloc, (destructor)cwr_dealloc}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_doc, cwr_doc}, + {Py_tp_traverse, (traverseproc)cwr_traverse}, + {Py_tp_iter, PyObject_SelfIter}, + {Py_tp_iternext, (iternextfunc)cwr_next}, + {Py_tp_methods, cwr_methods}, + {Py_tp_new, cwr_new}, + {Py_tp_free, PyObject_GC_Del}, + {0, 0} +}; + +static PyType_Spec cwr_type_spec = { + "itertools.combinations_with_replacement", + sizeof(cwrobject), + 0, Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_BASETYPE, /* tp_flags */ - cwr_doc, /* tp_doc */ - (traverseproc)cwr_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)cwr_next, /* tp_iternext */ - cwr_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 */ - cwr_new, /* tp_new */ - PyObject_GC_Del, /* tp_free */ + Py_TPFLAGS_BASETYPE, + cwr_type_slots, }; + /* permutations object ************************************************************ def permutations(iterable, r=None): @@ -2925,8 +2822,6 @@ int stopped; /* set to 1 when the permutations iterator is exhausted */ } permutationsobject; -static PyTypeObject permutations_type; - static PyObject * permutations_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { @@ -2981,6 +2876,7 @@ po = (permutationsobject *)type->tp_alloc(type, 0); if (po == NULL) goto error; + Py_INCREF(type); po->pool = pool; po->indices = indices; @@ -3003,12 +2899,16 @@ static void permutations_dealloc(permutationsobject *po) { + PyTypeObject *type = Py_TYPE(po); PyObject_GC_UnTrack(po); Py_XDECREF(po->pool); Py_XDECREF(po->result); PyMem_Free(po->indices); PyMem_Free(po->cycles); - Py_TYPE(po)->tp_free(po); + type->tp_free(po); + if((void *)type->tp_dealloc == (void *)permutations_dealloc) { + Py_DECREF(type); + } } static int @@ -3114,8 +3014,10 @@ permutations_reduce(permutationsobject *po) { if (po->result == NULL) { + Py_INCREF(Py_TYPE(po)); return Py_BuildValue("O(On)", Py_TYPE(po), po->pool, po->r); } else if (po->stopped) { + Py_INCREF(Py_TYPE(po)); return Py_BuildValue("O(()n)", Py_TYPE(po), po->r); } else { PyObject *indices=NULL, *cycles=NULL; @@ -3143,6 +3045,7 @@ goto err; PyTuple_SET_ITEM(cycles, i, index); } + Py_INCREF(Py_TYPE(po)); return Py_BuildValue("O(On)(NN)", Py_TYPE(po), po->pool, po->r, indices, cycles); @@ -3225,50 +3128,32 @@ Return successive r-length permutations of elements in the iterable.\n\n\ permutations(range(3), 2) --> (0,1), (0,2), (1,0), (1,2), (2,0), (2,1)"); -static PyTypeObject permutations_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "itertools.permutations", /* tp_name */ - sizeof(permutationsobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)permutations_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_reserved */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ + + + +static PyType_Slot permutations_type_slots[] = { + {Py_tp_dealloc, (destructor)permutations_dealloc}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_doc, permutations_doc}, + {Py_tp_traverse, (traverseproc)permutations_traverse}, + {Py_tp_iter, PyObject_SelfIter}, + {Py_tp_iternext, (iternextfunc)permutations_next}, + {Py_tp_methods, permuations_methods}, + {Py_tp_new, permutations_new}, + {Py_tp_free, PyObject_GC_Del}, + {0, 0} +}; + +static PyType_Spec permutations_type_spec = { + "itertools.permutations", + sizeof(permutationsobject), + 0, Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_BASETYPE, /* tp_flags */ - permutations_doc, /* tp_doc */ - (traverseproc)permutations_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)permutations_next, /* tp_iternext */ - permuations_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 */ - permutations_new, /* tp_new */ - PyObject_GC_Del, /* tp_free */ + Py_TPFLAGS_BASETYPE, + permutations_type_slots, }; + /* accumulate object ************************************************************/ typedef struct { @@ -3278,8 +3163,6 @@ PyObject *binop; } accumulateobject; -static PyTypeObject accumulate_type; - static PyObject * accumulate_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { @@ -3304,6 +3187,7 @@ Py_DECREF(it); return NULL; } + Py_INCREF(type); if (binop != Py_None) { Py_XINCREF(binop); @@ -3317,11 +3201,15 @@ static void accumulate_dealloc(accumulateobject *lz) { + PyTypeObject *type = Py_TYPE(lz); PyObject_GC_UnTrack(lz); Py_XDECREF(lz->binop); Py_XDECREF(lz->total); Py_XDECREF(lz->it); - Py_TYPE(lz)->tp_free(lz); + type->tp_free(lz); + if((void *)type->tp_dealloc == (void *)accumulate_dealloc) { + Py_DECREF(type); + } } static int @@ -3367,6 +3255,7 @@ static PyObject * accumulate_reduce(accumulateobject *lz) { + Py_INCREF(Py_TYPE(lz)); return Py_BuildValue("O(OO)O", Py_TYPE(lz), lz->it, lz->binop?lz->binop:Py_None, lz->total?lz->total:Py_None); @@ -3394,51 +3283,33 @@ \n\ Return series of accumulated sums (or other binary function results)."); -static PyTypeObject accumulate_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "itertools.accumulate", /* tp_name */ - sizeof(accumulateobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)accumulate_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_reserved */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ + + + +static PyType_Slot accumulate_type_slots[] = { + {Py_tp_dealloc, (destructor)accumulate_dealloc}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_doc, accumulate_doc}, + {Py_tp_traverse, (traverseproc)accumulate_traverse}, + {Py_tp_iter, PyObject_SelfIter}, + {Py_tp_iternext, (iternextfunc)accumulate_next}, + {Py_tp_methods, accumulate_methods}, + {Py_tp_new, accumulate_new}, + {Py_tp_free, PyObject_GC_Del}, + {0, 0} +}; + +static PyType_Spec accumulate_type_spec = { + "itertools.accumulate", + sizeof(accumulateobject), + 0, Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_BASETYPE, /* tp_flags */ - accumulate_doc, /* tp_doc */ - (traverseproc)accumulate_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)accumulate_next, /* tp_iternext */ - accumulate_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 */ - accumulate_new, /* tp_new */ - PyObject_GC_Del, /* tp_free */ + Py_TPFLAGS_BASETYPE, + accumulate_type_slots, }; + /* compress object ************************************************************/ /* Equivalent to: @@ -3454,8 +3325,6 @@ PyObject *selectors; } compressobject; -static PyTypeObject compress_type; - static PyObject * compress_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { @@ -3478,6 +3347,7 @@ lz = (compressobject *)type->tp_alloc(type, 0); if (lz == NULL) goto fail; + Py_INCREF(type); lz->data = data; lz->selectors = selectors; return (PyObject *)lz; @@ -3491,10 +3361,14 @@ static void compress_dealloc(compressobject *lz) { + PyTypeObject *type = Py_TYPE(lz); PyObject_GC_UnTrack(lz); Py_XDECREF(lz->data); Py_XDECREF(lz->selectors); - Py_TYPE(lz)->tp_free(lz); + type->tp_free(lz); + if((void *)type->tp_dealloc == (void *)compress_dealloc) { + Py_DECREF(type); + } } static int @@ -3544,9 +3418,10 @@ static PyObject * compress_reduce(compressobject *lz) { + Py_INCREF(Py_TYPE(lz)); return Py_BuildValue("O(OO)", Py_TYPE(lz), lz->data, lz->selectors); - } +} static PyMethodDef compress_methods[] = { {"__reduce__", (PyCFunction)compress_reduce, METH_NOARGS, @@ -3561,51 +3436,33 @@ Forms a shorter iterator from selected data elements using the\n\ selectors to choose the data elements."); -static PyTypeObject compress_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "itertools.compress", /* tp_name */ - sizeof(compressobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)compress_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_reserved */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ + + + +static PyType_Slot compress_type_slots[] = { + {Py_tp_dealloc, (destructor)compress_dealloc}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_doc, compress_doc}, + {Py_tp_traverse, (traverseproc)compress_traverse}, + {Py_tp_iter, PyObject_SelfIter}, + {Py_tp_iternext, (iternextfunc)compress_next}, + {Py_tp_methods, compress_methods}, + {Py_tp_new, compress_new}, + {Py_tp_free, PyObject_GC_Del}, + {0, 0} +}; + +static PyType_Spec compress_type_spec = { + "itertools.compress", + sizeof(compressobject), + 0, Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_BASETYPE, /* tp_flags */ - compress_doc, /* tp_doc */ - (traverseproc)compress_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)compress_next, /* tp_iternext */ - compress_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 */ - compress_new, /* tp_new */ - PyObject_GC_Del, /* tp_free */ + Py_TPFLAGS_BASETYPE, + compress_type_slots, }; + /* filterfalse object ************************************************************/ typedef struct { @@ -3614,8 +3471,6 @@ PyObject *it; } filterfalseobject; -static PyTypeObject filterfalse_type; - static PyObject * filterfalse_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { @@ -3623,7 +3478,7 @@ PyObject *it; filterfalseobject *lz; - if (type == &filterfalse_type && + if (type == (PyTypeObject *)itertoolsstate_global->filterfalse_type && !_PyArg_NoKeywords("filterfalse()", kwds)) return NULL; @@ -3641,6 +3496,7 @@ Py_DECREF(it); return NULL; } + Py_INCREF(type); Py_INCREF(func); lz->func = func; lz->it = it; @@ -3651,10 +3507,14 @@ static void filterfalse_dealloc(filterfalseobject *lz) { + PyTypeObject *type = Py_TYPE(lz); PyObject_GC_UnTrack(lz); Py_XDECREF(lz->func); Py_XDECREF(lz->it); - Py_TYPE(lz)->tp_free(lz); + type->tp_free(lz); + if((void *)type->tp_dealloc == (void *)filterfalse_dealloc) { + Py_DECREF(type); + } } static int @@ -3701,9 +3561,10 @@ static PyObject * filterfalse_reduce(filterfalseobject *lz) { + Py_INCREF(Py_TYPE(lz)); return Py_BuildValue("O(OO)", Py_TYPE(lz), lz->func, lz->it); - } +} static PyMethodDef filterfalse_methods[] = { {"__reduce__", (PyCFunction)filterfalse_reduce, METH_NOARGS, @@ -3717,51 +3578,33 @@ Return those items of sequence for which function(item) is false.\n\ If function is None, return the items that are false."); -static PyTypeObject filterfalse_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "itertools.filterfalse", /* tp_name */ - sizeof(filterfalseobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)filterfalse_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_reserved */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ + + + +static PyType_Slot filterfalse_type_slots[] = { + {Py_tp_dealloc, (destructor)filterfalse_dealloc}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_doc, filterfalse_doc}, + {Py_tp_traverse, (traverseproc)filterfalse_traverse}, + {Py_tp_iter, PyObject_SelfIter}, + {Py_tp_iternext, (iternextfunc)filterfalse_next}, + {Py_tp_methods, filterfalse_methods}, + {Py_tp_new, filterfalse_new}, + {Py_tp_free, PyObject_GC_Del}, + {0, 0} +}; + +static PyType_Spec filterfalse_type_spec = { + "itertools.filterfalse", + sizeof(filterfalseobject), + 0, Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_BASETYPE, /* tp_flags */ - filterfalse_doc, /* tp_doc */ - (traverseproc)filterfalse_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)filterfalse_next, /* tp_iternext */ - filterfalse_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 */ - filterfalse_new, /* tp_new */ - PyObject_GC_Del, /* tp_free */ + Py_TPFLAGS_BASETYPE, + filterfalse_type_slots, }; + /* count object ************************************************************/ typedef struct { @@ -3788,8 +3631,6 @@ Either long_cnt or long_step may be a float, Fraction, or Decimal. */ -static PyTypeObject count_type; - static PyObject * count_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { @@ -3859,6 +3700,7 @@ Py_XDECREF(long_cnt); return NULL; } + Py_INCREF(type); lz->cnt = cnt; lz->long_cnt = long_cnt; lz->long_step = long_step; @@ -3869,10 +3711,14 @@ static void count_dealloc(countobject *lz) { + PyTypeObject *type = Py_TYPE(lz); PyObject_GC_UnTrack(lz); Py_XDECREF(lz->long_cnt); Py_XDECREF(lz->long_step); - Py_TYPE(lz)->tp_free(lz); + type->tp_free(lz); + if((void *)type->tp_dealloc == (void *)count_dealloc) { + Py_DECREF(type); + } } static int @@ -3936,6 +3782,7 @@ static PyObject * count_reduce(countobject *lz) { + Py_INCREF(Py_TYPE(lz)); if (lz->cnt == PY_SSIZE_T_MAX) return Py_BuildValue("O(OO)", Py_TYPE(lz), lz->long_cnt, lz->long_step); return Py_BuildValue("O(n)", Py_TYPE(lz), lz->cnt); @@ -3958,51 +3805,34 @@ yield x\n\ x += step\n"); -static PyTypeObject count_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "itertools.count", /* tp_name */ - sizeof(countobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)count_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_reserved */ - (reprfunc)count_repr, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ + + + +static PyType_Slot count_type_slots[] = { + {Py_tp_dealloc, (destructor)count_dealloc}, + {Py_tp_repr, (reprfunc)count_repr}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_doc, count_doc}, + {Py_tp_traverse, (traverseproc)count_traverse}, + {Py_tp_iter, PyObject_SelfIter}, + {Py_tp_iternext, (iternextfunc)count_next}, + {Py_tp_methods, count_methods}, + {Py_tp_new, count_new}, + {Py_tp_free, PyObject_GC_Del}, + {0, 0} +}; + +static PyType_Spec count_type_spec = { + "itertools.count", + sizeof(countobject), + 0, Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_BASETYPE, /* tp_flags */ - count_doc, /* tp_doc */ - (traverseproc)count_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)count_next, /* tp_iternext */ - count_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 */ - count_new, /* tp_new */ - PyObject_GC_Del, /* tp_free */ + Py_TPFLAGS_BASETYPE, + count_type_slots, }; + /* repeat object ************************************************************/ typedef struct { @@ -4011,8 +3841,6 @@ Py_ssize_t cnt; } repeatobject; -static PyTypeObject repeat_type; - static PyObject * repeat_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { @@ -4031,6 +3859,7 @@ ro = (repeatobject *)type->tp_alloc(type, 0); if (ro == NULL) return NULL; + Py_INCREF(type); Py_INCREF(element); ro->element = element; ro->cnt = cnt; @@ -4040,9 +3869,13 @@ static void repeat_dealloc(repeatobject *ro) { + PyTypeObject *type = Py_TYPE(ro); PyObject_GC_UnTrack(ro); Py_XDECREF(ro->element); - Py_TYPE(ro)->tp_free(ro); + type->tp_free(ro); + if((void *)type->tp_dealloc == (void *)repeat_dealloc) { + Py_DECREF(type); + } } static int @@ -4090,6 +3923,7 @@ /* unpickle this so that a new repeat iterator is constructed with an * object, then call __setstate__ on it to set cnt */ + Py_INCREF(Py_TYPE(ro)); if (ro->cnt >= 0) return Py_BuildValue("O(On)", Py_TYPE(ro), ro->element, ro->cnt); else @@ -4107,50 +3941,33 @@ for the specified number of times. If not specified, returns the object\n\ endlessly."); -static PyTypeObject repeat_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "itertools.repeat", /* tp_name */ - sizeof(repeatobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)repeat_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_reserved */ - (reprfunc)repeat_repr, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ + + + +static PyType_Slot repeat_type_slots[] = { + {Py_tp_dealloc, (destructor)repeat_dealloc}, + {Py_tp_repr, (reprfunc)repeat_repr}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_doc, repeat_doc}, + {Py_tp_traverse, (traverseproc)repeat_traverse}, + {Py_tp_iter, PyObject_SelfIter}, + {Py_tp_iternext, (iternextfunc)repeat_next}, + {Py_tp_methods, repeat_methods}, + {Py_tp_new, repeat_new}, + {Py_tp_free, PyObject_GC_Del}, + {0, 0} +}; + +static PyType_Spec repeat_type_spec = { + "itertools.repeat", + sizeof(repeatobject), + 0, Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_BASETYPE, /* tp_flags */ - repeat_doc, /* tp_doc */ - (traverseproc)repeat_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)repeat_next, /* tp_iternext */ - repeat_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 */ - repeat_new, /* tp_new */ - PyObject_GC_Del, /* tp_free */ + Py_TPFLAGS_BASETYPE, + repeat_type_slots, }; + /* ziplongest object ************************************************************/ #include "Python.h" @@ -4164,8 +3981,6 @@ PyObject *fillvalue; } ziplongestobject; -static PyTypeObject ziplongest_type; - static PyObject * zip_longest_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { @@ -4224,6 +4039,7 @@ Py_DECREF(result); return NULL; } + Py_INCREF(type); lz->ittuple = ittuple; lz->tuplesize = tuplesize; lz->numactive = tuplesize; @@ -4236,11 +4052,15 @@ static void zip_longest_dealloc(ziplongestobject *lz) { + PyTypeObject *type = Py_TYPE(lz); PyObject_GC_UnTrack(lz); Py_XDECREF(lz->ittuple); Py_XDECREF(lz->result); Py_XDECREF(lz->fillvalue); - Py_TYPE(lz)->tp_free(lz); + type->tp_free(lz); + if((void *)type->tp_dealloc == (void *)zip_longest_dealloc) { + Py_DECREF(type); + } } static int @@ -4347,6 +4167,7 @@ Py_INCREF(elem); PyTuple_SET_ITEM(args, i, elem); } + Py_INCREF(Py_TYPE(lz)); return Py_BuildValue("ONO", Py_TYPE(lz), args, lz->fillvalue); } @@ -4378,50 +4199,32 @@ defaults to None or can be specified by a keyword argument.\n\ "); -static PyTypeObject ziplongest_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "itertools.zip_longest", /* tp_name */ - sizeof(ziplongestobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)zip_longest_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_reserved */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ + + + +static PyType_Slot ziplongest_type_slots[] = { + {Py_tp_dealloc, (destructor)zip_longest_dealloc}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_doc, zip_longest_doc}, + {Py_tp_traverse, (traverseproc)zip_longest_traverse}, + {Py_tp_iter, PyObject_SelfIter}, + {Py_tp_iternext, (iternextfunc)zip_longest_next}, + {Py_tp_methods, zip_longest_methods}, + {Py_tp_new, zip_longest_new}, + {Py_tp_free, PyObject_GC_Del}, + {0, 0} +}; + +static PyType_Spec ziplongest_type_spec = { + "itertools.zip_longest", + sizeof(ziplongestobject), + 0, Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_BASETYPE, /* tp_flags */ - zip_longest_doc, /* tp_doc */ - (traverseproc)zip_longest_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)zip_longest_next, /* tp_iternext */ - zip_longest_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 */ - zip_longest_new, /* tp_new */ - PyObject_GC_Del, /* tp_free */ + Py_TPFLAGS_BASETYPE, + ziplongest_type_slots, }; + /* module level code ********************************************************/ PyDoc_STRVAR(module_doc, @@ -4464,12 +4267,12 @@ PyModuleDef_HEAD_INIT, "itertools", module_doc, - -1, + sizeof(itertoolsstate), module_methods, NULL, - NULL, - NULL, - NULL + itertools_traverse, + itertools_clear, + itertools_free }; PyMODINIT_FUNC @@ -4478,37 +4281,43 @@ int i; PyObject *m; char *name; - PyTypeObject *typelist[] = { - &accumulate_type, - &combinations_type, - &cwr_type, - &cycle_type, - &dropwhile_type, - &takewhile_type, - &islice_type, - &starmap_type, - &chain_type, - &compress_type, - &filterfalse_type, - &count_type, - &ziplongest_type, - &permutations_type, - &product_type, - &repeat_type, - &groupby_type, - &_grouper_type, - &tee_type, - &teedataobject_type, - NULL - }; - - Py_TYPE(&teedataobject_type) = &PyType_Type; + PyTypeObject **typelist; + itertoolsstate *state; + PyType_Spec *speclist[] = { + &groupby_type_spec, + &_grouper_type_spec, + &teedataobject_type_spec, + &tee_type_spec, + &cycle_type_spec, + &dropwhile_type_spec, + &takewhile_type_spec, + &islice_type_spec, + &starmap_type_spec, + &chain_type_spec, + &product_type_spec, + &combinations_type_spec, + &cwr_type_spec, + &permutations_type_spec, + &accumulate_type_spec, + &compress_type_spec, + &filterfalse_type_spec, + &count_type_spec, + &repeat_type_spec, + &ziplongest_type_spec, + NULL + }; + m = PyModule_Create(&itertoolsmodule); if (m == NULL) return NULL; - for (i=0 ; typelist[i] != NULL ; i++) { - if (PyType_Ready(typelist[i]) < 0) + state = itertools_state(m); + + typelist = (PyTypeObject **)state; + + for (i=0 ; speclist[i] != NULL ; i++) { + typelist[i] = (PyTypeObject *)PyType_FromSpec(speclist[i]); + if (typelist[i] == NULL) return NULL; name = strchr(typelist[i]->tp_name, '.'); assert (name != NULL); @@ -4516,5 +4325,8 @@ PyModule_AddObject(m, name+1, (PyObject *)typelist[i]); } + ((PyTypeObject *)state->tee_type)->tp_weaklistoffset = + offsetof(teeobject, weakreflist); + return m; }