summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorErlend E. Aasland <erlend.aasland@protonmail.com>2023-02-03 09:54:27 (GMT)
committerGitHub <noreply@github.com>2023-02-03 09:54:27 (GMT)
commita52cc9853fed39b5cc90b7ffb6a64249307a990b (patch)
tree11b86f1bae16dc3cd399f5332eb177f2caca1e30
parent45d014e03ba7ba4c9c912120ec36b2aca02061f4 (diff)
downloadcpython-a52cc9853fed39b5cc90b7ffb6a64249307a990b.zip
cpython-a52cc9853fed39b5cc90b7ffb6a64249307a990b.tar.gz
cpython-a52cc9853fed39b5cc90b7ffb6a64249307a990b.tar.bz2
gh-101277: Port more `itertools` static types to heap types (#101303)
Add dropwhile, takewhile, starmap, combinations*, and permutations types to module state.
-rw-r--r--Modules/clinic/itertoolsmodule.c.h10
-rw-r--r--Modules/itertoolsmodule.c520
2 files changed, 202 insertions, 328 deletions
diff --git a/Modules/clinic/itertoolsmodule.c.h b/Modules/clinic/itertoolsmodule.c.h
index c492c33..be44246 100644
--- a/Modules/clinic/itertoolsmodule.c.h
+++ b/Modules/clinic/itertoolsmodule.c.h
@@ -345,7 +345,7 @@ static PyObject *
itertools_cycle(PyTypeObject *type, PyObject *args, PyObject *kwargs)
{
PyObject *return_value = NULL;
- PyTypeObject *base_tp = &cycle_type;
+ PyTypeObject *base_tp = clinic_state()->cycle_type;
PyObject *iterable;
if ((type == base_tp || type->tp_init == base_tp->tp_init) &&
@@ -377,7 +377,7 @@ static PyObject *
itertools_dropwhile(PyTypeObject *type, PyObject *args, PyObject *kwargs)
{
PyObject *return_value = NULL;
- PyTypeObject *base_tp = &dropwhile_type;
+ PyTypeObject *base_tp = clinic_state()->dropwhile_type;
PyObject *func;
PyObject *seq;
@@ -409,7 +409,7 @@ static PyObject *
itertools_takewhile(PyTypeObject *type, PyObject *args, PyObject *kwargs)
{
PyObject *return_value = NULL;
- PyTypeObject *base_tp = &takewhile_type;
+ PyTypeObject *base_tp = clinic_state()->takewhile_type;
PyObject *func;
PyObject *seq;
@@ -441,7 +441,7 @@ static PyObject *
itertools_starmap(PyTypeObject *type, PyObject *args, PyObject *kwargs)
{
PyObject *return_value = NULL;
- PyTypeObject *base_tp = &starmap_type;
+ PyTypeObject *base_tp = clinic_state()->starmap_type;
PyObject *func;
PyObject *seq;
@@ -913,4 +913,4 @@ skip_optional_pos:
exit:
return return_value;
}
-/*[clinic end generated code: output=c3069caac417e165 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=b86fcd99bd32145e input=a9049054013a1b77]*/
diff --git a/Modules/itertoolsmodule.c b/Modules/itertoolsmodule.c
index a2ee482..c9baa47 100644
--- a/Modules/itertoolsmodule.c
+++ b/Modules/itertoolsmodule.c
@@ -12,8 +12,15 @@
*/
typedef struct {
+ PyTypeObject *combinations_type;
+ PyTypeObject *cwr_type;
+ PyTypeObject *cycle_type;
+ PyTypeObject *dropwhile_type;
PyTypeObject *groupby_type;
PyTypeObject *_grouper_type;
+ PyTypeObject *permutations_type;
+ PyTypeObject *starmap_type;
+ PyTypeObject *takewhile_type;
} itertools_state;
static inline itertools_state *
@@ -50,32 +57,25 @@ 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.dropwhile "dropwhileobject *" "&dropwhile_type"
-class itertools.takewhile "takewhileobject *" "&takewhile_type"
-class itertools.starmap "starmapobject *" "&starmap_type"
+class itertools.cycle "cycleobject *" "clinic_state()->cycle_type"
+class itertools.dropwhile "dropwhileobject *" "clinic_state()->dropwhile_type"
+class itertools.takewhile "takewhileobject *" "clinic_state()->takewhile_type"
+class itertools.starmap "starmapobject *" "clinic_state()->starmap_type"
class itertools.chain "chainobject *" "&chain_type"
-class itertools.combinations "combinationsobject *" "&combinations_type"
-class itertools.combinations_with_replacement "cwr_object *" "&cwr_type"
-class itertools.permutations "permutationsobject *" "&permutations_type"
+class itertools.combinations "combinationsobject *" "clinic_state()->combinations_type"
+class itertools.combinations_with_replacement "cwr_object *" "clinic_state()->cwr_type"
+class itertools.permutations "permutationsobject *" "clinic_state()->permutations_type"
class itertools.accumulate "accumulateobject *" "&accumulate_type"
class itertools.compress "compressobject *" "&compress_type"
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=1790ac655869a651]*/
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;
-static PyTypeObject combinations_type;
-static PyTypeObject cwr_type;
-static PyTypeObject permutations_type;
static PyTypeObject accumulate_type;
static PyTypeObject compress_type;
static PyTypeObject filterfalse_type;
@@ -1286,15 +1286,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;
@@ -1381,48 +1384,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,
};
@@ -1474,15 +1454,18 @@ itertools_dropwhile_impl(PyTypeObject *type, PyObject *func, PyObject *seq)
static void
dropwhile_dealloc(dropwhileobject *lz)
{
+ PyTypeObject *tp = Py_TYPE(lz);
PyObject_GC_UnTrack(lz);
Py_XDECREF(lz->func);
Py_XDECREF(lz->it);
- Py_TYPE(lz)->tp_free(lz);
+ tp->tp_free(lz);
+ Py_DECREF(tp);
}
static int
dropwhile_traverse(dropwhileobject *lz, visitproc visit, void *arg)
{
+ Py_VISIT(Py_TYPE(lz));
Py_VISIT(lz->it);
Py_VISIT(lz->func);
return 0;
@@ -1545,48 +1528,25 @@ static PyMethodDef dropwhile_methods[] = {
{NULL, NULL} /* sentinel */
};
-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_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_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 */
- itertools_dropwhile, /* tp_new */
- PyObject_GC_Del, /* tp_free */
+static PyType_Slot dropwhile_slots[] = {
+ {Py_tp_dealloc, dropwhile_dealloc},
+ {Py_tp_getattro, PyObject_GenericGetAttr},
+ {Py_tp_doc, (void *)itertools_dropwhile__doc__},
+ {Py_tp_traverse, dropwhile_traverse},
+ {Py_tp_iter, PyObject_SelfIter},
+ {Py_tp_iternext, dropwhile_next},
+ {Py_tp_methods, dropwhile_methods},
+ {Py_tp_new, itertools_dropwhile},
+ {Py_tp_free, PyObject_GC_Del},
+ {0, NULL},
+};
+
+static PyType_Spec dropwhile_spec = {
+ .name = "itertools.dropwhile",
+ .basicsize = sizeof(dropwhileobject),
+ .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE |
+ Py_TPFLAGS_IMMUTABLETYPE),
+ .slots = dropwhile_slots,
};
@@ -1636,15 +1596,18 @@ itertools_takewhile_impl(PyTypeObject *type, PyObject *func, PyObject *seq)
static void
takewhile_dealloc(takewhileobject *lz)
{
+ PyTypeObject *tp = Py_TYPE(lz);
PyObject_GC_UnTrack(lz);
Py_XDECREF(lz->func);
Py_XDECREF(lz->it);
- Py_TYPE(lz)->tp_free(lz);
+ tp->tp_free(lz);
+ Py_DECREF(tp);
}
static int
takewhile_traverse(takewhileobject *lz, visitproc visit, void *arg)
{
+ Py_VISIT(Py_TYPE(lz));
Py_VISIT(lz->it);
Py_VISIT(lz->func);
return 0;
@@ -1704,48 +1667,25 @@ static PyMethodDef takewhile_reduce_methods[] = {
{NULL, NULL} /* sentinel */
};
-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_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_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 */
- itertools_takewhile, /* tp_new */
- PyObject_GC_Del, /* tp_free */
+static PyType_Slot takewhile_slots[] = {
+ {Py_tp_dealloc, takewhile_dealloc},
+ {Py_tp_getattro, PyObject_GenericGetAttr},
+ {Py_tp_doc, (void *)itertools_takewhile__doc__},
+ {Py_tp_traverse, takewhile_traverse},
+ {Py_tp_iter, PyObject_SelfIter},
+ {Py_tp_iternext, takewhile_next},
+ {Py_tp_methods, takewhile_reduce_methods},
+ {Py_tp_new, itertools_takewhile},
+ {Py_tp_free, PyObject_GC_Del},
+ {0, NULL},
+};
+
+static PyType_Spec takewhile_spec = {
+ .name = "itertools.takewhile",
+ .basicsize = sizeof(takewhileobject),
+ .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE |
+ Py_TPFLAGS_IMMUTABLETYPE),
+ .slots = takewhile_slots,
};
@@ -2052,15 +1992,18 @@ itertools_starmap_impl(PyTypeObject *type, PyObject *func, PyObject *seq)
static void
starmap_dealloc(starmapobject *lz)
{
+ PyTypeObject *tp = Py_TYPE(lz);
PyObject_GC_UnTrack(lz);
Py_XDECREF(lz->func);
Py_XDECREF(lz->it);
- Py_TYPE(lz)->tp_free(lz);
+ tp->tp_free(lz);
+ Py_DECREF(tp);
}
static int
starmap_traverse(starmapobject *lz, visitproc visit, void *arg)
{
+ Py_VISIT(Py_TYPE(lz));
Py_VISIT(lz->it);
Py_VISIT(lz->func);
return 0;
@@ -2101,48 +2044,25 @@ static PyMethodDef starmap_methods[] = {
{NULL, NULL} /* sentinel */
};
-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_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_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 */
- itertools_starmap, /* tp_new */
- PyObject_GC_Del, /* tp_free */
+static PyType_Slot starmap_slots[] = {
+ {Py_tp_dealloc, starmap_dealloc},
+ {Py_tp_getattro, PyObject_GenericGetAttr},
+ {Py_tp_doc, (void *)itertools_starmap__doc__},
+ {Py_tp_traverse, starmap_traverse},
+ {Py_tp_iter, PyObject_SelfIter},
+ {Py_tp_iternext, starmap_next},
+ {Py_tp_methods, starmap_methods},
+ {Py_tp_new, itertools_starmap},
+ {Py_tp_free, PyObject_GC_Del},
+ {0, NULL},
+};
+
+static PyType_Spec starmap_spec = {
+ .name = "itertools.starmap",
+ .basicsize = sizeof(starmapobject),
+ .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE |
+ Py_TPFLAGS_IMMUTABLETYPE),
+ .slots = starmap_slots,
};
@@ -2799,12 +2719,14 @@ error:
static void
combinations_dealloc(combinationsobject *co)
{
+ PyTypeObject *tp = 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);
+ tp->tp_free(co);
+ Py_DECREF(tp);
}
static PyObject *
@@ -2818,6 +2740,7 @@ combinations_sizeof(combinationsobject *co, void *unused)
static int
combinations_traverse(combinationsobject *co, visitproc visit, void *arg)
{
+ Py_VISIT(Py_TYPE(co));
Py_VISIT(co->pool);
Py_VISIT(co->result);
return 0;
@@ -2988,48 +2911,25 @@ static PyMethodDef combinations_methods[] = {
{NULL, NULL} /* sentinel */
};
-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_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_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 */
- itertools_combinations, /* tp_new */
- PyObject_GC_Del, /* tp_free */
+static PyType_Slot combinations_slots[] = {
+ {Py_tp_dealloc, combinations_dealloc},
+ {Py_tp_getattro, PyObject_GenericGetAttr},
+ {Py_tp_doc, (void *)itertools_combinations__doc__},
+ {Py_tp_traverse, combinations_traverse},
+ {Py_tp_iter, PyObject_SelfIter},
+ {Py_tp_iternext, combinations_next},
+ {Py_tp_methods, combinations_methods},
+ {Py_tp_new, itertools_combinations},
+ {Py_tp_free, PyObject_GC_Del},
+ {0, NULL},
+};
+
+static PyType_Spec combinations_spec = {
+ .name = "itertools.combinations",
+ .basicsize = sizeof(combinationsobject),
+ .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE |
+ Py_TPFLAGS_IMMUTABLETYPE),
+ .slots = combinations_slots,
};
@@ -3133,12 +3033,14 @@ error:
static void
cwr_dealloc(cwrobject *co)
{
+ PyTypeObject *tp = 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);
+ tp->tp_free(co);
+ Py_DECREF(tp);
}
static PyObject *
@@ -3152,6 +3054,7 @@ cwr_sizeof(cwrobject *co, void *unused)
static int
cwr_traverse(cwrobject *co, visitproc visit, void *arg)
{
+ Py_VISIT(Py_TYPE(co));
Py_VISIT(co->pool);
Py_VISIT(co->result);
return 0;
@@ -3312,48 +3215,25 @@ static PyMethodDef cwr_methods[] = {
{NULL, NULL} /* sentinel */
};
-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_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_combinations_with_replacement__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 */
- itertools_combinations_with_replacement, /* tp_new */
- PyObject_GC_Del, /* tp_free */
+static PyType_Slot cwr_slots[] = {
+ {Py_tp_dealloc, cwr_dealloc},
+ {Py_tp_getattro, PyObject_GenericGetAttr},
+ {Py_tp_doc, (void *)itertools_combinations_with_replacement__doc__},
+ {Py_tp_traverse, cwr_traverse},
+ {Py_tp_iter, PyObject_SelfIter},
+ {Py_tp_iternext, cwr_next},
+ {Py_tp_methods, cwr_methods},
+ {Py_tp_new, itertools_combinations_with_replacement},
+ {Py_tp_free, PyObject_GC_Del},
+ {0, NULL},
+};
+
+static PyType_Spec cwr_spec = {
+ .name = "itertools.combinations_with_replacement",
+ .basicsize = sizeof(cwrobject),
+ .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE |
+ Py_TPFLAGS_IMMUTABLETYPE),
+ .slots = cwr_slots,
};
@@ -3476,12 +3356,14 @@ error:
static void
permutations_dealloc(permutationsobject *po)
{
+ PyTypeObject *tp = 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);
+ tp->tp_free(po);
+ Py_DECREF(tp);
}
static PyObject *
@@ -3496,6 +3378,7 @@ permutations_sizeof(permutationsobject *po, void *unused)
static int
permutations_traverse(permutationsobject *po, visitproc visit, void *arg)
{
+ Py_VISIT(Py_TYPE(po));
Py_VISIT(po->pool);
Py_VISIT(po->result);
return 0;
@@ -3701,48 +3584,25 @@ static PyMethodDef permuations_methods[] = {
{NULL, NULL} /* sentinel */
};
-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_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_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 */
- itertools_permutations, /* tp_new */
- PyObject_GC_Del, /* tp_free */
+static PyType_Slot permutations_slots[] = {
+ {Py_tp_dealloc, permutations_dealloc},
+ {Py_tp_getattro, PyObject_GenericGetAttr},
+ {Py_tp_doc, (void *)itertools_permutations__doc__},
+ {Py_tp_traverse, permutations_traverse},
+ {Py_tp_iter, PyObject_SelfIter},
+ {Py_tp_iternext, permutations_next},
+ {Py_tp_methods, permuations_methods},
+ {Py_tp_new, itertools_permutations},
+ {Py_tp_free, PyObject_GC_Del},
+ {0, NULL},
+};
+
+static PyType_Spec permutations_spec = {
+ .name = "itertools.permutations",
+ .basicsize = sizeof(permutationsobject),
+ .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE |
+ Py_TPFLAGS_IMMUTABLETYPE),
+ .slots = permutations_slots,
};
@@ -4975,8 +4835,15 @@ static int
itertoolsmodule_traverse(PyObject *mod, visitproc visit, void *arg)
{
itertools_state *state = get_module_state(mod);
+ Py_VISIT(state->combinations_type);
+ Py_VISIT(state->cwr_type);
+ Py_VISIT(state->cycle_type);
+ Py_VISIT(state->dropwhile_type);
Py_VISIT(state->groupby_type);
Py_VISIT(state->_grouper_type);
+ Py_VISIT(state->permutations_type);
+ Py_VISIT(state->starmap_type);
+ Py_VISIT(state->takewhile_type);
return 0;
}
@@ -4984,8 +4851,15 @@ static int
itertoolsmodule_clear(PyObject *mod)
{
itertools_state *state = get_module_state(mod);
+ Py_CLEAR(state->combinations_type);
+ Py_CLEAR(state->cwr_type);
+ Py_CLEAR(state->cycle_type);
+ Py_CLEAR(state->dropwhile_type);
Py_CLEAR(state->groupby_type);
Py_CLEAR(state->_grouper_type);
+ Py_CLEAR(state->permutations_type);
+ Py_CLEAR(state->starmap_type);
+ Py_CLEAR(state->takewhile_type);
return 0;
}
@@ -5010,26 +4884,26 @@ static int
itertoolsmodule_exec(PyObject *mod)
{
itertools_state *state = get_module_state(mod);
+ ADD_TYPE(mod, state->combinations_type, &combinations_spec);
+ ADD_TYPE(mod, state->cwr_type, &cwr_spec);
+ ADD_TYPE(mod, state->cycle_type, &cycle_spec);
+ ADD_TYPE(mod, state->dropwhile_type, &dropwhile_spec);
ADD_TYPE(mod, state->groupby_type, &groupby_spec);
ADD_TYPE(mod, state->_grouper_type, &_grouper_spec);
+ ADD_TYPE(mod, state->permutations_type, &permutations_spec);
+ ADD_TYPE(mod, state->starmap_type, &starmap_spec);
+ ADD_TYPE(mod, state->takewhile_type, &takewhile_spec);
PyTypeObject *typelist[] = {
&accumulate_type,
&batched_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,
&pairwise_type,
- &permutations_type,
&product_type,
&repeat_type,
&tee_type,