diff --git a/Modules/clinic/itertoolsmodule.c.h b/Modules/clinic/itertoolsmodule.c.h index 55db7e6bb1bc127..17581efa09d62e4 100644 --- a/Modules/clinic/itertoolsmodule.c.h +++ b/Modules/clinic/itertoolsmodule.c.h @@ -347,8 +347,8 @@ itertools_cycle(PyTypeObject *type, PyObject *args, PyObject *kwargs) PyObject *return_value = NULL; PyObject *iterable; - if ((type == &cycle_type || - type->tp_init == cycle_type.tp_init) && + if ((type == clinic_state()->cycle_type || + type->tp_init == clinic_state()->cycle_type->tp_init) && !_PyArg_NoKeywords("cycle", kwargs)) { goto exit; } @@ -913,4 +913,4 @@ itertools_count(PyTypeObject *type, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=22eb8d1eeaaa805f input=a9049054013a1b77]*/ +/*[clinic end generated code: output=1dcd0a1d663ade43 input=a9049054013a1b77]*/ diff --git a/Modules/itertoolsmodule.c b/Modules/itertoolsmodule.c index d16591538e76dd0..3a249c38aa8f009 100644 --- a/Modules/itertoolsmodule.c +++ b/Modules/itertoolsmodule.c @@ -11,6 +11,7 @@ */ typedef struct { + PyTypeObject *cycle_type; PyTypeObject *groupby_type; PyTypeObject *_grouper_type; } itertools_state; @@ -40,7 +41,7 @@ class itertools._grouper "_grouperobject *" "clinic_state()->_grouper_type" class itertools.teedataobject "teedataobject *" "&teedataobject_type" class itertools._tee "teeobject *" "&tee_type" class itertools.batched "batchedobject *" "&batched_type" -class itertools.cycle "cycleobject *" "&cycle_type" +class itertools.cycle "cycleobject *" "clinic_state()->cycle_type" class itertools.dropwhile "dropwhileobject *" "&dropwhile_type" class itertools.takewhile "takewhileobject *" "&takewhile_type" class itertools.starmap "starmapobject *" "&starmap_type" @@ -54,12 +55,11 @@ class itertools.filterfalse "filterfalseobject *" "&filterfalse_type" class itertools.count "countobject *" "&count_type" class itertools.pairwise "pairwiseobject *" "&pairwise_type" [clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=424108522584b55b]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=b73cdca8e1fddfb5]*/ static PyTypeObject teedataobject_type; static PyTypeObject tee_type; static PyTypeObject batched_type; -static PyTypeObject cycle_type; static PyTypeObject dropwhile_type; static PyTypeObject takewhile_type; static PyTypeObject starmap_type; @@ -1273,15 +1273,18 @@ itertools_cycle_impl(PyTypeObject *type, PyObject *iterable) static void cycle_dealloc(cycleobject *lz) { + PyTypeObject *tp = Py_TYPE(lz); PyObject_GC_UnTrack(lz); Py_XDECREF(lz->it); Py_XDECREF(lz->saved); - Py_TYPE(lz)->tp_free(lz); + tp->tp_free(lz); + Py_DECREF(tp); } static int cycle_traverse(cycleobject *lz, visitproc visit, void *arg) { + Py_VISIT(Py_TYPE(lz)); Py_VISIT(lz->it); Py_VISIT(lz->saved); return 0; @@ -1368,48 +1371,25 @@ static PyMethodDef cycle_methods[] = { {NULL, NULL} /* sentinel */ }; -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_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 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 | - Py_TPFLAGS_BASETYPE, /* tp_flags */ - itertools_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 */ - itertools_cycle, /* tp_new */ - PyObject_GC_Del, /* tp_free */ +static PyType_Slot cycle_slots[] = { + {Py_tp_dealloc, cycle_dealloc}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_doc, (void *)itertools_cycle__doc__}, + {Py_tp_traverse, cycle_traverse}, + {Py_tp_iter, PyObject_SelfIter}, + {Py_tp_iternext, cycle_next}, + {Py_tp_methods, cycle_methods}, + {Py_tp_new, itertools_cycle}, + {Py_tp_free, PyObject_GC_Del}, + {0, NULL}, +}; + +static PyType_Spec cycle_spec = { + .name = "itertools.cycle", + .basicsize = sizeof(cycleobject), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = cycle_slots, }; @@ -4962,6 +4942,7 @@ static int itertoolsmodule_traverse(PyObject *mod, visitproc visit, void *arg) { itertools_state *state = get_module_state(mod); + Py_VISIT(state->cycle_type); Py_VISIT(state->groupby_type); Py_VISIT(state->_grouper_type); return 0; @@ -4971,6 +4952,7 @@ static int itertoolsmodule_clear(PyObject *mod) { itertools_state *state = get_module_state(mod); + Py_CLEAR(state->cycle_type); Py_CLEAR(state->groupby_type); Py_CLEAR(state->_grouper_type); return 0; @@ -4997,6 +4979,7 @@ static int itertoolsmodule_exec(PyObject *mod) { itertools_state *state = get_module_state(mod); + ADD_TYPE(mod, state->cycle_type, &cycle_spec); ADD_TYPE(mod, state->groupby_type, &groupby_spec); ADD_TYPE(mod, state->_grouper_type, &_grouper_spec); @@ -5005,7 +4988,6 @@ itertoolsmodule_exec(PyObject *mod) &batched_type, &combinations_type, &cwr_type, - &cycle_type, &dropwhile_type, &takewhile_type, &islice_type,