gh-101277: Port more itertools static types to heap types (#101304)

Add accumulate, compress, count, filterfalse, pairwise, product,
and zip_longest types to module state.
This commit is contained in:
Erlend E. Aasland 2023-02-08 21:25:42 +01:00 committed by GitHub
parent 616aec1ff1
commit de3669ebcb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 200 additions and 327 deletions

View File

@ -102,7 +102,7 @@ static PyObject *
pairwise_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) pairwise_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
{ {
PyObject *return_value = NULL; PyObject *return_value = NULL;
PyTypeObject *base_tp = &pairwise_type; PyTypeObject *base_tp = clinic_state()->pairwise_type;
PyObject *iterable; PyObject *iterable;
if ((type == base_tp || type->tp_init == base_tp->tp_init) && if ((type == base_tp || type->tp_init == base_tp->tp_init) &&
@ -821,7 +821,7 @@ static PyObject *
itertools_filterfalse(PyTypeObject *type, PyObject *args, PyObject *kwargs) itertools_filterfalse(PyTypeObject *type, PyObject *args, PyObject *kwargs)
{ {
PyObject *return_value = NULL; PyObject *return_value = NULL;
PyTypeObject *base_tp = &filterfalse_type; PyTypeObject *base_tp = clinic_state()->filterfalse_type;
PyObject *func; PyObject *func;
PyObject *seq; PyObject *seq;
@ -913,4 +913,4 @@ skip_optional_pos:
exit: exit:
return return_value; return return_value;
} }
/*[clinic end generated code: output=b86fcd99bd32145e input=a9049054013a1b77]*/ /*[clinic end generated code: output=a08b58d7dac825da input=a9049054013a1b77]*/

View File

@ -12,15 +12,22 @@
*/ */
typedef struct { typedef struct {
PyTypeObject *accumulate_type;
PyTypeObject *combinations_type; PyTypeObject *combinations_type;
PyTypeObject *compress_type;
PyTypeObject *count_type;
PyTypeObject *cwr_type; PyTypeObject *cwr_type;
PyTypeObject *cycle_type; PyTypeObject *cycle_type;
PyTypeObject *dropwhile_type; PyTypeObject *dropwhile_type;
PyTypeObject *filterfalse_type;
PyTypeObject *groupby_type; PyTypeObject *groupby_type;
PyTypeObject *_grouper_type; PyTypeObject *_grouper_type;
PyTypeObject *pairwise_type;
PyTypeObject *permutations_type; PyTypeObject *permutations_type;
PyTypeObject *product_type;
PyTypeObject *starmap_type; PyTypeObject *starmap_type;
PyTypeObject *takewhile_type; PyTypeObject *takewhile_type;
PyTypeObject *ziplongest_type;
} itertools_state; } itertools_state;
static inline itertools_state * static inline itertools_state *
@ -48,7 +55,6 @@ find_state_by_type(PyTypeObject *tp)
assert(mod != NULL); assert(mod != NULL);
return get_module_state(mod); return get_module_state(mod);
} }
#define clinic_state() (find_state_by_type(type))
/*[clinic input] /*[clinic input]
module itertools module itertools
@ -65,23 +71,19 @@ class itertools.chain "chainobject *" "&chain_type"
class itertools.combinations "combinationsobject *" "clinic_state()->combinations_type" class itertools.combinations "combinationsobject *" "clinic_state()->combinations_type"
class itertools.combinations_with_replacement "cwr_object *" "clinic_state()->cwr_type" class itertools.combinations_with_replacement "cwr_object *" "clinic_state()->cwr_type"
class itertools.permutations "permutationsobject *" "clinic_state()->permutations_type" class itertools.permutations "permutationsobject *" "clinic_state()->permutations_type"
class itertools.accumulate "accumulateobject *" "&accumulate_type" class itertools.accumulate "accumulateobject *" "clinic_state()->accumulate_type"
class itertools.compress "compressobject *" "&compress_type" class itertools.compress "compressobject *" "clinic_state()->compress_type"
class itertools.filterfalse "filterfalseobject *" "&filterfalse_type" class itertools.filterfalse "filterfalseobject *" "clinic_state()->filterfalse_type"
class itertools.count "countobject *" "&count_type" class itertools.count "countobject *" "clinic_state()->count_type"
class itertools.pairwise "pairwiseobject *" "&pairwise_type" class itertools.pairwise "pairwiseobject *" "clinic_state()->pairwise_type"
[clinic start generated code]*/ [clinic start generated code]*/
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=1790ac655869a651]*/ /*[clinic end generated code: output=da39a3ee5e6b4b0d input=28ffff5c0c93eed7]*/
static PyTypeObject teedataobject_type; static PyTypeObject teedataobject_type;
static PyTypeObject tee_type; static PyTypeObject tee_type;
static PyTypeObject batched_type; static PyTypeObject batched_type;
static PyTypeObject accumulate_type;
static PyTypeObject compress_type;
static PyTypeObject filterfalse_type;
static PyTypeObject count_type;
static PyTypeObject pairwise_type;
#define clinic_state() (find_state_by_type(type))
#define clinic_state_by_cls() (get_module_state_by_cls(base_tp)) #define clinic_state_by_cls() (get_module_state_by_cls(base_tp))
#include "clinic/itertoolsmodule.c.h" #include "clinic/itertoolsmodule.c.h"
#undef clinic_state_by_cls #undef clinic_state_by_cls
@ -308,15 +310,18 @@ pairwise_new_impl(PyTypeObject *type, PyObject *iterable)
static void static void
pairwise_dealloc(pairwiseobject *po) pairwise_dealloc(pairwiseobject *po)
{ {
PyTypeObject *tp = Py_TYPE(po);
PyObject_GC_UnTrack(po); PyObject_GC_UnTrack(po);
Py_XDECREF(po->it); Py_XDECREF(po->it);
Py_XDECREF(po->old); Py_XDECREF(po->old);
Py_TYPE(po)->tp_free(po); tp->tp_free(po);
Py_DECREF(tp);
} }
static int static int
pairwise_traverse(pairwiseobject *po, visitproc visit, void *arg) pairwise_traverse(pairwiseobject *po, visitproc visit, void *arg)
{ {
Py_VISIT(Py_TYPE(po));
Py_VISIT(po->it); Py_VISIT(po->it);
Py_VISIT(po->old); Py_VISIT(po->old);
return 0; return 0;
@ -351,48 +356,25 @@ pairwise_next(pairwiseobject *po)
return result; return result;
} }
static PyTypeObject pairwise_type = { static PyType_Slot pairwise_slots[] = {
PyVarObject_HEAD_INIT(&PyType_Type, 0) {Py_tp_dealloc, pairwise_dealloc},
"itertools.pairwise", /* tp_name */ {Py_tp_getattro, PyObject_GenericGetAttr},
sizeof(pairwiseobject), /* tp_basicsize */ {Py_tp_doc, (void *)pairwise_new__doc__},
0, /* tp_itemsize */ {Py_tp_traverse, pairwise_traverse},
/* methods */ {Py_tp_iter, PyObject_SelfIter},
(destructor)pairwise_dealloc, /* tp_dealloc */ {Py_tp_iternext, pairwise_next},
0, /* tp_vectorcall_offset */ {Py_tp_alloc, PyType_GenericAlloc},
0, /* tp_getattr */ {Py_tp_new, pairwise_new},
0, /* tp_setattr */ {Py_tp_free, PyObject_GC_Del},
0, /* tp_as_async */ {0, NULL},
0, /* tp_repr */ };
0, /* tp_as_number */
0, /* tp_as_sequence */ static PyType_Spec pairwise_spec = {
0, /* tp_as_mapping */ .name = "itertools.pairwise",
0, /* tp_hash */ .basicsize = sizeof(pairwiseobject),
0, /* tp_call */ .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE |
0, /* tp_str */ Py_TPFLAGS_IMMUTABLETYPE),
PyObject_GenericGetAttr, /* tp_getattro */ .slots = pairwise_slots,
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
Py_TPFLAGS_BASETYPE, /* tp_flags */
pairwise_new__doc__, /* tp_doc */
(traverseproc)pairwise_traverse, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
PyObject_SelfIter, /* tp_iter */
(iternextfunc)pairwise_next, /* tp_iternext */
0, /* 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 */
PyType_GenericAlloc, /* tp_alloc */
pairwise_new, /* tp_new */
PyObject_GC_Del, /* tp_free */
}; };
@ -2300,8 +2282,6 @@ typedef struct {
int stopped; /* set to 1 when the iterator is exhausted */ int stopped; /* set to 1 when the iterator is exhausted */
} productobject; } productobject;
static PyTypeObject product_type;
static PyObject * static PyObject *
product_new(PyTypeObject *type, PyObject *args, PyObject *kwds) product_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{ {
@ -2388,12 +2368,14 @@ product_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
static void static void
product_dealloc(productobject *lz) product_dealloc(productobject *lz)
{ {
PyTypeObject *tp = Py_TYPE(lz);
PyObject_GC_UnTrack(lz); PyObject_GC_UnTrack(lz);
Py_XDECREF(lz->pools); Py_XDECREF(lz->pools);
Py_XDECREF(lz->result); Py_XDECREF(lz->result);
if (lz->indices != NULL) if (lz->indices != NULL)
PyMem_Free(lz->indices); PyMem_Free(lz->indices);
Py_TYPE(lz)->tp_free(lz); tp->tp_free(lz);
Py_DECREF(tp);
} }
static PyObject * static PyObject *
@ -2409,6 +2391,7 @@ PyDoc_STRVAR(sizeof_doc, "Returns size in memory, in bytes.");
static int static int
product_traverse(productobject *lz, visitproc visit, void *arg) product_traverse(productobject *lz, visitproc visit, void *arg)
{ {
Py_VISIT(Py_TYPE(lz));
Py_VISIT(lz->pools); Py_VISIT(lz->pools);
Py_VISIT(lz->result); Py_VISIT(lz->result);
return 0; return 0;
@ -2600,48 +2583,25 @@ product(A, repeat=4) means the same as product(A, A, A, A).\n\n\
product('ab', range(3)) --> ('a',0) ('a',1) ('a',2) ('b',0) ('b',1) ('b',2)\n\ 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) ..."); 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 = { static PyType_Slot product_slots[] = {
PyVarObject_HEAD_INIT(NULL, 0) {Py_tp_dealloc, product_dealloc},
"itertools.product", /* tp_name */ {Py_tp_getattro, PyObject_GenericGetAttr},
sizeof(productobject), /* tp_basicsize */ {Py_tp_doc, (void *)product_doc},
0, /* tp_itemsize */ {Py_tp_traverse, product_traverse},
/* methods */ {Py_tp_iter, PyObject_SelfIter},
(destructor)product_dealloc, /* tp_dealloc */ {Py_tp_iternext, product_next},
0, /* tp_vectorcall_offset */ {Py_tp_methods, product_methods},
0, /* tp_getattr */ {Py_tp_new, product_new},
0, /* tp_setattr */ {Py_tp_free, PyObject_GC_Del},
0, /* tp_as_async */ {0, NULL},
0, /* tp_repr */ };
0, /* tp_as_number */
0, /* tp_as_sequence */ static PyType_Spec product_spec = {
0, /* tp_as_mapping */ .name = "itertools.product",
0, /* tp_hash */ .basicsize = sizeof(productobject),
0, /* tp_call */ .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE |
0, /* tp_str */ Py_TPFLAGS_IMMUTABLETYPE),
PyObject_GenericGetAttr, /* tp_getattro */ .slots = product_slots,
0, /* tp_setattro */
0, /* tp_as_buffer */
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 */
}; };
@ -3658,17 +3618,20 @@ itertools_accumulate_impl(PyTypeObject *type, PyObject *iterable,
static void static void
accumulate_dealloc(accumulateobject *lz) accumulate_dealloc(accumulateobject *lz)
{ {
PyTypeObject *tp = Py_TYPE(lz);
PyObject_GC_UnTrack(lz); PyObject_GC_UnTrack(lz);
Py_XDECREF(lz->binop); Py_XDECREF(lz->binop);
Py_XDECREF(lz->total); Py_XDECREF(lz->total);
Py_XDECREF(lz->it); Py_XDECREF(lz->it);
Py_XDECREF(lz->initial); Py_XDECREF(lz->initial);
Py_TYPE(lz)->tp_free(lz); tp->tp_free(lz);
Py_DECREF(tp);
} }
static int static int
accumulate_traverse(accumulateobject *lz, visitproc visit, void *arg) accumulate_traverse(accumulateobject *lz, visitproc visit, void *arg)
{ {
Py_VISIT(Py_TYPE(lz));
Py_VISIT(lz->binop); Py_VISIT(lz->binop);
Py_VISIT(lz->it); Py_VISIT(lz->it);
Py_VISIT(lz->total); Py_VISIT(lz->total);
@ -3762,48 +3725,25 @@ static PyMethodDef accumulate_methods[] = {
{NULL, NULL} /* sentinel */ {NULL, NULL} /* sentinel */
}; };
static PyTypeObject accumulate_type = { static PyType_Slot accumulate_slots[] = {
PyVarObject_HEAD_INIT(NULL, 0) {Py_tp_dealloc, accumulate_dealloc},
"itertools.accumulate", /* tp_name */ {Py_tp_getattro, PyObject_GenericGetAttr},
sizeof(accumulateobject), /* tp_basicsize */ {Py_tp_doc, (void *)itertools_accumulate__doc__},
0, /* tp_itemsize */ {Py_tp_traverse, accumulate_traverse},
/* methods */ {Py_tp_iter, PyObject_SelfIter},
(destructor)accumulate_dealloc, /* tp_dealloc */ {Py_tp_iternext, accumulate_next},
0, /* tp_vectorcall_offset */ {Py_tp_methods, accumulate_methods},
0, /* tp_getattr */ {Py_tp_new, itertools_accumulate},
0, /* tp_setattr */ {Py_tp_free, PyObject_GC_Del},
0, /* tp_as_async */ {0, NULL},
0, /* tp_repr */ };
0, /* tp_as_number */
0, /* tp_as_sequence */ static PyType_Spec accumulate_spec = {
0, /* tp_as_mapping */ .name = "itertools.accumulate",
0, /* tp_hash */ .basicsize = sizeof(accumulateobject),
0, /* tp_call */ .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE |
0, /* tp_str */ Py_TPFLAGS_IMMUTABLETYPE),
PyObject_GenericGetAttr, /* tp_getattro */ .slots = accumulate_slots,
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
Py_TPFLAGS_BASETYPE, /* tp_flags */
itertools_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 */
itertools_accumulate, /* tp_new */
PyObject_GC_Del, /* tp_free */
}; };
@ -3864,15 +3804,18 @@ itertools_compress_impl(PyTypeObject *type, PyObject *seq1, PyObject *seq2)
static void static void
compress_dealloc(compressobject *lz) compress_dealloc(compressobject *lz)
{ {
PyTypeObject *tp = Py_TYPE(lz);
PyObject_GC_UnTrack(lz); PyObject_GC_UnTrack(lz);
Py_XDECREF(lz->data); Py_XDECREF(lz->data);
Py_XDECREF(lz->selectors); Py_XDECREF(lz->selectors);
Py_TYPE(lz)->tp_free(lz); tp->tp_free(lz);
Py_DECREF(tp);
} }
static int static int
compress_traverse(compressobject *lz, visitproc visit, void *arg) compress_traverse(compressobject *lz, visitproc visit, void *arg)
{ {
Py_VISIT(Py_TYPE(lz));
Py_VISIT(lz->data); Py_VISIT(lz->data);
Py_VISIT(lz->selectors); Py_VISIT(lz->selectors);
return 0; return 0;
@ -3927,48 +3870,25 @@ static PyMethodDef compress_methods[] = {
{NULL, NULL} /* sentinel */ {NULL, NULL} /* sentinel */
}; };
static PyTypeObject compress_type = { static PyType_Slot compress_slots[] = {
PyVarObject_HEAD_INIT(NULL, 0) {Py_tp_dealloc, compress_dealloc},
"itertools.compress", /* tp_name */ {Py_tp_getattro, PyObject_GenericGetAttr},
sizeof(compressobject), /* tp_basicsize */ {Py_tp_doc, (void *)itertools_compress__doc__},
0, /* tp_itemsize */ {Py_tp_traverse, compress_traverse},
/* methods */ {Py_tp_iter, PyObject_SelfIter},
(destructor)compress_dealloc, /* tp_dealloc */ {Py_tp_iternext, compress_next},
0, /* tp_vectorcall_offset */ {Py_tp_methods, compress_methods},
0, /* tp_getattr */ {Py_tp_new, itertools_compress},
0, /* tp_setattr */ {Py_tp_free, PyObject_GC_Del},
0, /* tp_as_async */ {0, NULL},
0, /* tp_repr */ };
0, /* tp_as_number */
0, /* tp_as_sequence */ static PyType_Spec compress_spec = {
0, /* tp_as_mapping */ .name = "itertools.compress",
0, /* tp_hash */ .basicsize = sizeof(compressobject),
0, /* tp_call */ .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE |
0, /* tp_str */ Py_TPFLAGS_IMMUTABLETYPE),
PyObject_GenericGetAttr, /* tp_getattro */ .slots = compress_slots,
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
Py_TPFLAGS_BASETYPE, /* tp_flags */
itertools_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 */
itertools_compress, /* tp_new */
PyObject_GC_Del, /* tp_free */
}; };
@ -4018,15 +3938,18 @@ itertools_filterfalse_impl(PyTypeObject *type, PyObject *func, PyObject *seq)
static void static void
filterfalse_dealloc(filterfalseobject *lz) filterfalse_dealloc(filterfalseobject *lz)
{ {
PyTypeObject *tp = Py_TYPE(lz);
PyObject_GC_UnTrack(lz); PyObject_GC_UnTrack(lz);
Py_XDECREF(lz->func); Py_XDECREF(lz->func);
Py_XDECREF(lz->it); Py_XDECREF(lz->it);
Py_TYPE(lz)->tp_free(lz); tp->tp_free(lz);
Py_DECREF(tp);
} }
static int static int
filterfalse_traverse(filterfalseobject *lz, visitproc visit, void *arg) filterfalse_traverse(filterfalseobject *lz, visitproc visit, void *arg)
{ {
Py_VISIT(Py_TYPE(lz));
Py_VISIT(lz->it); Py_VISIT(lz->it);
Py_VISIT(lz->func); Py_VISIT(lz->func);
return 0; return 0;
@ -4078,48 +4001,25 @@ static PyMethodDef filterfalse_methods[] = {
{NULL, NULL} /* sentinel */ {NULL, NULL} /* sentinel */
}; };
static PyTypeObject filterfalse_type = { static PyType_Slot filterfalse_slots[] = {
PyVarObject_HEAD_INIT(NULL, 0) {Py_tp_dealloc, filterfalse_dealloc},
"itertools.filterfalse", /* tp_name */ {Py_tp_getattro, PyObject_GenericGetAttr},
sizeof(filterfalseobject), /* tp_basicsize */ {Py_tp_doc, (void *)itertools_filterfalse__doc__},
0, /* tp_itemsize */ {Py_tp_traverse, filterfalse_traverse},
/* methods */ {Py_tp_iter, PyObject_SelfIter},
(destructor)filterfalse_dealloc, /* tp_dealloc */ {Py_tp_iternext, filterfalse_next},
0, /* tp_vectorcall_offset */ {Py_tp_methods, filterfalse_methods},
0, /* tp_getattr */ {Py_tp_new, itertools_filterfalse},
0, /* tp_setattr */ {Py_tp_free, PyObject_GC_Del},
0, /* tp_as_async */ {0, NULL},
0, /* tp_repr */ };
0, /* tp_as_number */
0, /* tp_as_sequence */ static PyType_Spec filterfalse_spec = {
0, /* tp_as_mapping */ .name = "itertools.filterfalse",
0, /* tp_hash */ .basicsize = sizeof(filterfalseobject),
0, /* tp_call */ .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE |
0, /* tp_str */ Py_TPFLAGS_IMMUTABLETYPE),
PyObject_GenericGetAttr, /* tp_getattro */ .slots = filterfalse_slots,
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
Py_TPFLAGS_BASETYPE, /* tp_flags */
itertools_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 */
itertools_filterfalse, /* tp_new */
PyObject_GC_Del, /* tp_free */
}; };
@ -4245,15 +4145,18 @@ itertools_count_impl(PyTypeObject *type, PyObject *long_cnt,
static void static void
count_dealloc(countobject *lz) count_dealloc(countobject *lz)
{ {
PyTypeObject *tp = Py_TYPE(lz);
PyObject_GC_UnTrack(lz); PyObject_GC_UnTrack(lz);
Py_XDECREF(lz->long_cnt); Py_XDECREF(lz->long_cnt);
Py_XDECREF(lz->long_step); Py_XDECREF(lz->long_step);
Py_TYPE(lz)->tp_free(lz); tp->tp_free(lz);
Py_DECREF(tp);
} }
static int static int
count_traverse(countobject *lz, visitproc visit, void *arg) count_traverse(countobject *lz, visitproc visit, void *arg)
{ {
Py_VISIT(Py_TYPE(lz));
Py_VISIT(lz->long_cnt); Py_VISIT(lz->long_cnt);
Py_VISIT(lz->long_step); Py_VISIT(lz->long_step);
return 0; return 0;
@ -4327,48 +4230,26 @@ static PyMethodDef count_methods[] = {
{NULL, NULL} /* sentinel */ {NULL, NULL} /* sentinel */
}; };
static PyTypeObject count_type = { static PyType_Slot count_slots[] = {
PyVarObject_HEAD_INIT(NULL, 0) {Py_tp_dealloc, count_dealloc},
"itertools.count", /* tp_name */ {Py_tp_repr, count_repr},
sizeof(countobject), /* tp_basicsize */ {Py_tp_getattro, PyObject_GenericGetAttr},
0, /* tp_itemsize */ {Py_tp_doc, (void *)itertools_count__doc__},
/* methods */ {Py_tp_traverse, count_traverse},
(destructor)count_dealloc, /* tp_dealloc */ {Py_tp_iter, PyObject_SelfIter},
0, /* tp_vectorcall_offset */ {Py_tp_iternext, count_next},
0, /* tp_getattr */ {Py_tp_methods, count_methods},
0, /* tp_setattr */ {Py_tp_new, itertools_count},
0, /* tp_as_async */ {Py_tp_free, PyObject_GC_Del},
(reprfunc)count_repr, /* tp_repr */ {0, NULL},
0, /* tp_as_number */ };
0, /* tp_as_sequence */
0, /* tp_as_mapping */ static PyType_Spec count_spec = {
0, /* tp_hash */ .name = "itertools.count",
0, /* tp_call */ .basicsize = sizeof(countobject),
0, /* tp_str */ .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE |
PyObject_GenericGetAttr, /* tp_getattro */ Py_TPFLAGS_IMMUTABLETYPE),
0, /* tp_setattro */ .slots = count_slots,
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
Py_TPFLAGS_BASETYPE, /* tp_flags */
itertools_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 */
itertools_count, /* tp_new */
PyObject_GC_Del, /* tp_free */
}; };
@ -4536,8 +4417,6 @@ typedef struct {
PyObject *fillvalue; PyObject *fillvalue;
} ziplongestobject; } ziplongestobject;
static PyTypeObject ziplongest_type;
static PyObject * static PyObject *
zip_longest_new(PyTypeObject *type, PyObject *args, PyObject *kwds) zip_longest_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{ {
@ -4609,16 +4488,19 @@ zip_longest_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
static void static void
zip_longest_dealloc(ziplongestobject *lz) zip_longest_dealloc(ziplongestobject *lz)
{ {
PyTypeObject *tp = Py_TYPE(lz);
PyObject_GC_UnTrack(lz); PyObject_GC_UnTrack(lz);
Py_XDECREF(lz->ittuple); Py_XDECREF(lz->ittuple);
Py_XDECREF(lz->result); Py_XDECREF(lz->result);
Py_XDECREF(lz->fillvalue); Py_XDECREF(lz->fillvalue);
Py_TYPE(lz)->tp_free(lz); tp->tp_free(lz);
Py_DECREF(tp);
} }
static int static int
zip_longest_traverse(ziplongestobject *lz, visitproc visit, void *arg) zip_longest_traverse(ziplongestobject *lz, visitproc visit, void *arg)
{ {
Py_VISIT(Py_TYPE(lz));
Py_VISIT(lz->ittuple); Py_VISIT(lz->ittuple);
Py_VISIT(lz->result); Py_VISIT(lz->result);
Py_VISIT(lz->fillvalue); Py_VISIT(lz->fillvalue);
@ -4752,48 +4634,25 @@ are exhausted, the fillvalue is substituted in their place. The fillvalue\n\
defaults to None or can be specified by a keyword argument.\n\ defaults to None or can be specified by a keyword argument.\n\
"); ");
static PyTypeObject ziplongest_type = { static PyType_Slot ziplongest_slots[] = {
PyVarObject_HEAD_INIT(NULL, 0) {Py_tp_dealloc, zip_longest_dealloc},
"itertools.zip_longest", /* tp_name */ {Py_tp_getattro, PyObject_GenericGetAttr},
sizeof(ziplongestobject), /* tp_basicsize */ {Py_tp_doc, (void *)zip_longest_doc},
0, /* tp_itemsize */ {Py_tp_traverse, zip_longest_traverse},
/* methods */ {Py_tp_iter, PyObject_SelfIter},
(destructor)zip_longest_dealloc, /* tp_dealloc */ {Py_tp_iternext, zip_longest_next},
0, /* tp_vectorcall_offset */ {Py_tp_methods, zip_longest_methods},
0, /* tp_getattr */ {Py_tp_new, zip_longest_new},
0, /* tp_setattr */ {Py_tp_free, PyObject_GC_Del},
0, /* tp_as_async */ {0, NULL},
0, /* tp_repr */ };
0, /* tp_as_number */
0, /* tp_as_sequence */ static PyType_Spec ziplongest_spec = {
0, /* tp_as_mapping */ .name = "itertools.zip_longest",
0, /* tp_hash */ .basicsize = sizeof(ziplongestobject),
0, /* tp_call */ .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE |
0, /* tp_str */ Py_TPFLAGS_IMMUTABLETYPE),
PyObject_GenericGetAttr, /* tp_getattro */ .slots = ziplongest_slots,
0, /* tp_setattro */
0, /* tp_as_buffer */
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 */
}; };
@ -4835,15 +4694,22 @@ static int
itertoolsmodule_traverse(PyObject *mod, visitproc visit, void *arg) itertoolsmodule_traverse(PyObject *mod, visitproc visit, void *arg)
{ {
itertools_state *state = get_module_state(mod); itertools_state *state = get_module_state(mod);
Py_VISIT(state->accumulate_type);
Py_VISIT(state->combinations_type); Py_VISIT(state->combinations_type);
Py_VISIT(state->compress_type);
Py_VISIT(state->count_type);
Py_VISIT(state->cwr_type); Py_VISIT(state->cwr_type);
Py_VISIT(state->cycle_type); Py_VISIT(state->cycle_type);
Py_VISIT(state->dropwhile_type); Py_VISIT(state->dropwhile_type);
Py_VISIT(state->filterfalse_type);
Py_VISIT(state->groupby_type); Py_VISIT(state->groupby_type);
Py_VISIT(state->_grouper_type); Py_VISIT(state->_grouper_type);
Py_VISIT(state->pairwise_type);
Py_VISIT(state->permutations_type); Py_VISIT(state->permutations_type);
Py_VISIT(state->product_type);
Py_VISIT(state->starmap_type); Py_VISIT(state->starmap_type);
Py_VISIT(state->takewhile_type); Py_VISIT(state->takewhile_type);
Py_VISIT(state->ziplongest_type);
return 0; return 0;
} }
@ -4851,15 +4717,22 @@ static int
itertoolsmodule_clear(PyObject *mod) itertoolsmodule_clear(PyObject *mod)
{ {
itertools_state *state = get_module_state(mod); itertools_state *state = get_module_state(mod);
Py_CLEAR(state->accumulate_type);
Py_CLEAR(state->combinations_type); Py_CLEAR(state->combinations_type);
Py_CLEAR(state->compress_type);
Py_CLEAR(state->count_type);
Py_CLEAR(state->cwr_type); Py_CLEAR(state->cwr_type);
Py_CLEAR(state->cycle_type); Py_CLEAR(state->cycle_type);
Py_CLEAR(state->dropwhile_type); Py_CLEAR(state->dropwhile_type);
Py_CLEAR(state->filterfalse_type);
Py_CLEAR(state->groupby_type); Py_CLEAR(state->groupby_type);
Py_CLEAR(state->_grouper_type); Py_CLEAR(state->_grouper_type);
Py_CLEAR(state->pairwise_type);
Py_CLEAR(state->permutations_type); Py_CLEAR(state->permutations_type);
Py_CLEAR(state->product_type);
Py_CLEAR(state->starmap_type); Py_CLEAR(state->starmap_type);
Py_CLEAR(state->takewhile_type); Py_CLEAR(state->takewhile_type);
Py_CLEAR(state->ziplongest_type);
return 0; return 0;
} }
@ -4884,27 +4757,27 @@ static int
itertoolsmodule_exec(PyObject *mod) itertoolsmodule_exec(PyObject *mod)
{ {
itertools_state *state = get_module_state(mod); itertools_state *state = get_module_state(mod);
ADD_TYPE(mod, state->accumulate_type, &accumulate_spec);
ADD_TYPE(mod, state->combinations_type, &combinations_spec); ADD_TYPE(mod, state->combinations_type, &combinations_spec);
ADD_TYPE(mod, state->compress_type, &compress_spec);
ADD_TYPE(mod, state->count_type, &count_spec);
ADD_TYPE(mod, state->cwr_type, &cwr_spec); ADD_TYPE(mod, state->cwr_type, &cwr_spec);
ADD_TYPE(mod, state->cycle_type, &cycle_spec); ADD_TYPE(mod, state->cycle_type, &cycle_spec);
ADD_TYPE(mod, state->dropwhile_type, &dropwhile_spec); ADD_TYPE(mod, state->dropwhile_type, &dropwhile_spec);
ADD_TYPE(mod, state->filterfalse_type, &filterfalse_spec);
ADD_TYPE(mod, state->groupby_type, &groupby_spec); ADD_TYPE(mod, state->groupby_type, &groupby_spec);
ADD_TYPE(mod, state->_grouper_type, &_grouper_spec); ADD_TYPE(mod, state->_grouper_type, &_grouper_spec);
ADD_TYPE(mod, state->pairwise_type, &pairwise_spec);
ADD_TYPE(mod, state->permutations_type, &permutations_spec); ADD_TYPE(mod, state->permutations_type, &permutations_spec);
ADD_TYPE(mod, state->product_type, &product_spec);
ADD_TYPE(mod, state->starmap_type, &starmap_spec); ADD_TYPE(mod, state->starmap_type, &starmap_spec);
ADD_TYPE(mod, state->takewhile_type, &takewhile_spec); ADD_TYPE(mod, state->takewhile_type, &takewhile_spec);
ADD_TYPE(mod, state->ziplongest_type, &ziplongest_spec);
PyTypeObject *typelist[] = { PyTypeObject *typelist[] = {
&accumulate_type,
&batched_type, &batched_type,
&islice_type, &islice_type,
&chain_type, &chain_type,
&compress_type,
&filterfalse_type,
&count_type,
&ziplongest_type,
&pairwise_type,
&product_type,
&repeat_type, &repeat_type,
&tee_type, &tee_type,
&teedataobject_type &teedataobject_type