aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/tools/python3/src/Modules/itertoolsmodule.c
diff options
context:
space:
mode:
authorshadchin <shadchin@yandex-team.com>2024-02-12 07:53:52 +0300
committershadchin <shadchin@yandex-team.com>2024-02-12 08:07:36 +0300
commitce1b7ca3171f9158180640c6a02a74b4afffedea (patch)
treee47c1e8391b1b0128262c1e9b1e6ed4c8fff2348 /contrib/tools/python3/src/Modules/itertoolsmodule.c
parent57350d96f030db90f220ce50ee591d5c5d403df7 (diff)
downloadydb-ce1b7ca3171f9158180640c6a02a74b4afffedea.tar.gz
Update Python from 3.11.8 to 3.12.2
Diffstat (limited to 'contrib/tools/python3/src/Modules/itertoolsmodule.c')
-rw-r--r--contrib/tools/python3/src/Modules/itertoolsmodule.c2069
1 files changed, 964 insertions, 1105 deletions
diff --git a/contrib/tools/python3/src/Modules/itertoolsmodule.c b/contrib/tools/python3/src/Modules/itertoolsmodule.c
index 7a02a0d25b..24e77c485d 100644
--- a/contrib/tools/python3/src/Modules/itertoolsmodule.c
+++ b/contrib/tools/python3/src/Modules/itertoolsmodule.c
@@ -2,54 +2,262 @@
#include "Python.h"
#include "pycore_call.h" // _PyObject_CallNoArgs()
#include "pycore_long.h" // _PyLong_GetZero()
+#include "pycore_moduleobject.h" // _PyModule_GetState()
+#include "pycore_typeobject.h" // _PyType_GetModuleState()
#include "pycore_object.h" // _PyObject_GC_TRACK()
#include "pycore_tuple.h" // _PyTuple_ITEMS()
+#include "structmember.h" // PyMemberDef
#include <stddef.h> // offsetof()
/* Itertools module written and maintained
by Raymond D. Hettinger <python@rcn.com>
*/
+typedef struct {
+ PyTypeObject *accumulate_type;
+ PyTypeObject *batched_type;
+ PyTypeObject *chain_type;
+ PyTypeObject *combinations_type;
+ PyTypeObject *compress_type;
+ PyTypeObject *count_type;
+ PyTypeObject *cwr_type;
+ PyTypeObject *cycle_type;
+ PyTypeObject *dropwhile_type;
+ PyTypeObject *filterfalse_type;
+ PyTypeObject *groupby_type;
+ PyTypeObject *_grouper_type;
+ PyTypeObject *islice_type;
+ PyTypeObject *pairwise_type;
+ PyTypeObject *permutations_type;
+ PyTypeObject *product_type;
+ PyTypeObject *repeat_type;
+ PyTypeObject *starmap_type;
+ PyTypeObject *takewhile_type;
+ PyTypeObject *tee_type;
+ PyTypeObject *teedataobject_type;
+ PyTypeObject *ziplongest_type;
+} itertools_state;
+
+static inline itertools_state *
+get_module_state(PyObject *mod)
+{
+ void *state = _PyModule_GetState(mod);
+ assert(state != NULL);
+ return (itertools_state *)state;
+}
+
+static inline itertools_state *
+get_module_state_by_cls(PyTypeObject *cls)
+{
+ void *state = _PyType_GetModuleState(cls);
+ assert(state != NULL);
+ return (itertools_state *)state;
+}
+
+static struct PyModuleDef itertoolsmodule;
+
+static inline itertools_state *
+find_state_by_type(PyTypeObject *tp)
+{
+ PyObject *mod = PyType_GetModuleByDef(tp, &itertoolsmodule);
+ assert(mod != NULL);
+ return get_module_state(mod);
+}
+
/*[clinic input]
module itertools
-class itertools.groupby "groupbyobject *" "&groupby_type"
-class itertools._grouper "_grouperobject *" "&_grouper_type"
-class itertools.teedataobject "teedataobject *" "&teedataobject_type"
-class itertools._tee "teeobject *" "&tee_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.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.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"
+class itertools.groupby "groupbyobject *" "clinic_state()->groupby_type"
+class itertools._grouper "_grouperobject *" "clinic_state()->_grouper_type"
+class itertools.teedataobject "teedataobject *" "clinic_state()->teedataobject_type"
+class itertools._tee "teeobject *" "clinic_state()->tee_type"
+class itertools.batched "batchedobject *" "clinic_state()->batched_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 *" "clinic_state()->chain_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 *" "clinic_state()->accumulate_type"
+class itertools.compress "compressobject *" "clinic_state()->compress_type"
+class itertools.filterfalse "filterfalseobject *" "clinic_state()->filterfalse_type"
+class itertools.count "countobject *" "clinic_state()->count_type"
+class itertools.pairwise "pairwiseobject *" "clinic_state()->pairwise_type"
[clinic start generated code]*/
-/*[clinic end generated code: output=da39a3ee5e6b4b0d input=6498ed21fbe1bf94]*/
-
-static PyTypeObject groupby_type;
-static PyTypeObject _grouper_type;
-static PyTypeObject teedataobject_type;
-static PyTypeObject tee_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;
-static PyTypeObject count_type;
-static PyTypeObject pairwise_type;
+/*[clinic end generated code: output=da39a3ee5e6b4b0d input=aa48fe4de9d4080f]*/
+#define clinic_state() (find_state_by_type(type))
+#define clinic_state_by_cls() (get_module_state_by_cls(base_tp))
#include "clinic/itertoolsmodule.c.h"
+#undef clinic_state_by_cls
+#undef clinic_state
+
+/* Deprecation of pickle support: GH-101588 *********************************/
+
+#define ITERTOOL_PICKLE_DEPRECATION \
+ if (PyErr_WarnEx( \
+ PyExc_DeprecationWarning, \
+ "Pickle, copy, and deepcopy support will be " \
+ "removed from itertools in Python 3.14.", 1) < 0) { \
+ return NULL; \
+ }
+
+/* batched object ************************************************************/
+
+/* Note: The built-in zip() function includes a "strict" argument
+ that was needed because that function would silently truncate data,
+ and there was no easy way for a user to detect the data loss.
+ The same reasoning does not apply to batched() which never drops data.
+ Instead, batched() produces a shorter tuple which can be handled
+ as the user sees fit. If requested, it would be reasonable to add
+ "fillvalue" support which had demonstrated value in zip_longest().
+ For now, the API is kept simple and clean.
+ */
+
+typedef struct {
+ PyObject_HEAD
+ PyObject *it;
+ Py_ssize_t batch_size;
+} batchedobject;
+
+/*[clinic input]
+@classmethod
+itertools.batched.__new__ as batched_new
+ iterable: object
+ n: Py_ssize_t
+Batch data into tuples of length n. The last batch may be shorter than n.
+
+Loops over the input iterable and accumulates data into tuples
+up to size n. The input is consumed lazily, just enough to
+fill a batch. The result is yielded as soon as a batch is full
+or when the input iterable is exhausted.
+
+ >>> for batch in batched('ABCDEFG', 3):
+ ... print(batch)
+ ...
+ ('A', 'B', 'C')
+ ('D', 'E', 'F')
+ ('G',)
+
+[clinic start generated code]*/
+
+static PyObject *
+batched_new_impl(PyTypeObject *type, PyObject *iterable, Py_ssize_t n)
+/*[clinic end generated code: output=7ebc954d655371b6 input=ffd70726927c5129]*/
+{
+ PyObject *it;
+ batchedobject *bo;
+
+ if (n < 1) {
+ /* We could define the n==0 case to return an empty iterator
+ but that is at odds with the idea that batching should
+ never throw-away input data.
+ */
+ PyErr_SetString(PyExc_ValueError, "n must be at least one");
+ return NULL;
+ }
+ it = PyObject_GetIter(iterable);
+ if (it == NULL) {
+ return NULL;
+ }
+
+ /* create batchedobject structure */
+ bo = (batchedobject *)type->tp_alloc(type, 0);
+ if (bo == NULL) {
+ Py_DECREF(it);
+ return NULL;
+ }
+ bo->batch_size = n;
+ bo->it = it;
+ return (PyObject *)bo;
+}
+
+static void
+batched_dealloc(batchedobject *bo)
+{
+ PyTypeObject *tp = Py_TYPE(bo);
+ PyObject_GC_UnTrack(bo);
+ Py_XDECREF(bo->it);
+ tp->tp_free(bo);
+ Py_DECREF(tp);
+}
+
+static int
+batched_traverse(batchedobject *bo, visitproc visit, void *arg)
+{
+ Py_VISIT(Py_TYPE(bo));
+ Py_VISIT(bo->it);
+ return 0;
+}
+
+static PyObject *
+batched_next(batchedobject *bo)
+{
+ Py_ssize_t i;
+ Py_ssize_t n = bo->batch_size;
+ PyObject *it = bo->it;
+ PyObject *item;
+ PyObject *result;
+
+ if (it == NULL) {
+ return NULL;
+ }
+ result = PyTuple_New(n);
+ if (result == NULL) {
+ return NULL;
+ }
+ iternextfunc iternext = *Py_TYPE(it)->tp_iternext;
+ PyObject **items = _PyTuple_ITEMS(result);
+ for (i=0 ; i < n ; i++) {
+ item = iternext(it);
+ if (item == NULL) {
+ goto null_item;
+ }
+ items[i] = item;
+ }
+ return result;
+
+ null_item:
+ if (PyErr_Occurred()) {
+ if (!PyErr_ExceptionMatches(PyExc_StopIteration)) {
+ /* Input raised an exception other than StopIteration */
+ Py_CLEAR(bo->it);
+ Py_DECREF(result);
+ return NULL;
+ }
+ PyErr_Clear();
+ }
+ if (i == 0) {
+ Py_CLEAR(bo->it);
+ Py_DECREF(result);
+ return NULL;
+ }
+ _PyTuple_Resize(&result, i);
+ return result;
+}
+
+static PyType_Slot batched_slots[] = {
+ {Py_tp_dealloc, batched_dealloc},
+ {Py_tp_getattro, PyObject_GenericGetAttr},
+ {Py_tp_doc, (void *)batched_new__doc__},
+ {Py_tp_traverse, batched_traverse},
+ {Py_tp_iter, PyObject_SelfIter},
+ {Py_tp_iternext, batched_next},
+ {Py_tp_alloc, PyType_GenericAlloc},
+ {Py_tp_new, batched_new},
+ {Py_tp_free, PyObject_GC_Del},
+ {0, NULL},
+};
+
+static PyType_Spec batched_spec = {
+ .name = "itertools.batched",
+ .basicsize = sizeof(batchedobject),
+ .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE |
+ Py_TPFLAGS_IMMUTABLETYPE),
+ .slots = batched_slots,
+};
+
/* pairwise object ***********************************************************/
@@ -94,15 +302,18 @@ pairwise_new_impl(PyTypeObject *type, PyObject *iterable)
static void
pairwise_dealloc(pairwiseobject *po)
{
+ PyTypeObject *tp = Py_TYPE(po);
PyObject_GC_UnTrack(po);
Py_XDECREF(po->it);
Py_XDECREF(po->old);
- Py_TYPE(po)->tp_free(po);
+ tp->tp_free(po);
+ Py_DECREF(tp);
}
static int
pairwise_traverse(pairwiseobject *po, visitproc visit, void *arg)
{
+ Py_VISIT(Py_TYPE(po));
Py_VISIT(po->it);
Py_VISIT(po->old);
return 0;
@@ -146,48 +357,25 @@ pairwise_next(pairwiseobject *po)
return result;
}
-static PyTypeObject pairwise_type = {
- PyVarObject_HEAD_INIT(&PyType_Type, 0)
- "itertools.pairwise", /* tp_name */
- sizeof(pairwiseobject), /* tp_basicsize */
- 0, /* tp_itemsize */
- /* methods */
- (destructor)pairwise_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 */
- 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 */
+static PyType_Slot pairwise_slots[] = {
+ {Py_tp_dealloc, pairwise_dealloc},
+ {Py_tp_getattro, PyObject_GenericGetAttr},
+ {Py_tp_doc, (void *)pairwise_new__doc__},
+ {Py_tp_traverse, pairwise_traverse},
+ {Py_tp_iter, PyObject_SelfIter},
+ {Py_tp_iternext, pairwise_next},
+ {Py_tp_alloc, PyType_GenericAlloc},
+ {Py_tp_new, pairwise_new},
+ {Py_tp_free, PyObject_GC_Del},
+ {0, NULL},
+};
+
+static PyType_Spec pairwise_spec = {
+ .name = "itertools.pairwise",
+ .basicsize = sizeof(pairwiseobject),
+ .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE |
+ Py_TPFLAGS_IMMUTABLETYPE),
+ .slots = pairwise_slots,
};
@@ -201,6 +389,7 @@ typedef struct {
PyObject *currkey;
PyObject *currvalue;
const void *currgrouper; /* borrowed reference */
+ itertools_state *state;
} groupbyobject;
static PyObject *_grouper_create(groupbyobject *, PyObject *);
@@ -231,31 +420,34 @@ itertools_groupby_impl(PyTypeObject *type, PyObject *it, PyObject *keyfunc)
gbo->tgtkey = NULL;
gbo->currkey = NULL;
gbo->currvalue = NULL;
- gbo->keyfunc = keyfunc;
- Py_INCREF(keyfunc);
+ gbo->keyfunc = Py_NewRef(keyfunc);
gbo->it = PyObject_GetIter(it);
if (gbo->it == NULL) {
Py_DECREF(gbo);
return NULL;
}
+ gbo->state = find_state_by_type(type);
return (PyObject *)gbo;
}
static void
groupby_dealloc(groupbyobject *gbo)
{
+ PyTypeObject *tp = 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);
+ tp->tp_free(gbo);
+ Py_DECREF(tp);
}
static int
groupby_traverse(groupbyobject *gbo, visitproc visit, void *arg)
{
+ Py_VISIT(Py_TYPE(gbo));
Py_VISIT(gbo->it);
Py_VISIT(gbo->keyfunc);
Py_VISIT(gbo->tgtkey);
@@ -274,8 +466,7 @@ groupby_step(groupbyobject *gbo)
return -1;
if (gbo->keyfunc == Py_None) {
- newkey = newvalue;
- Py_INCREF(newvalue);
+ newkey = Py_NewRef(newvalue);
} else {
newkey = PyObject_CallOneArg(gbo->keyfunc, newvalue);
if (newkey == NULL) {
@@ -334,6 +525,7 @@ groupby_reduce(groupbyobject *lz, PyObject *Py_UNUSED(ignored))
/* reduce as a 'new' call with an optional 'setstate' if groupby
* has started
*/
+ ITERTOOL_PICKLE_DEPRECATION;
PyObject *value;
if (lz->tgtkey && lz->currkey && lz->currvalue)
value = Py_BuildValue("O(OO)(OOO)", Py_TYPE(lz),
@@ -350,6 +542,7 @@ PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
static PyObject *
groupby_setstate(groupbyobject *lz, PyObject *state)
{
+ ITERTOOL_PICKLE_DEPRECATION;
PyObject *currkey, *currvalue, *tgtkey;
if (!PyTuple_Check(state)) {
PyErr_SetString(PyExc_TypeError, "state is not a tuple");
@@ -377,50 +570,26 @@ static PyMethodDef groupby_methods[] = {
{NULL, NULL} /* sentinel */
};
-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_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_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 */
- itertools_groupby, /* tp_new */
- PyObject_GC_Del, /* tp_free */
+static PyType_Slot groupby_slots[] = {
+ {Py_tp_dealloc, groupby_dealloc},
+ {Py_tp_getattro, PyObject_GenericGetAttr},
+ {Py_tp_doc, (void *)itertools_groupby__doc__},
+ {Py_tp_traverse, groupby_traverse},
+ {Py_tp_iter, PyObject_SelfIter},
+ {Py_tp_iternext, groupby_next},
+ {Py_tp_methods, groupby_methods},
+ {Py_tp_new, itertools_groupby},
+ {Py_tp_free, PyObject_GC_Del},
+ {0, NULL},
};
+static PyType_Spec groupby_spec = {
+ .name = "itertools.groupby",
+ .basicsize= sizeof(groupbyobject),
+ .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE |
+ Py_TPFLAGS_IMMUTABLETYPE),
+ .slots = groupby_slots,
+};
/* _grouper object (internal) ************************************************/
@@ -434,7 +603,7 @@ typedef struct {
@classmethod
itertools._grouper.__new__
- parent: object(subclass_of='&groupby_type')
+ parent: object(subclass_of='clinic_state_by_cls()->groupby_type')
tgtkey: object
/
[clinic start generated code]*/
@@ -442,7 +611,7 @@ itertools._grouper.__new__
static PyObject *
itertools__grouper_impl(PyTypeObject *type, PyObject *parent,
PyObject *tgtkey)
-/*[clinic end generated code: output=462efb1cdebb5914 input=dc180d7771fc8c59]*/
+/*[clinic end generated code: output=462efb1cdebb5914 input=afe05eb477118f12]*/
{
return _grouper_create((groupbyobject*) parent, tgtkey);
}
@@ -450,15 +619,12 @@ itertools__grouper_impl(PyTypeObject *type, PyObject *parent,
static PyObject *
_grouper_create(groupbyobject *parent, PyObject *tgtkey)
{
- _grouperobject *igo;
-
- igo = PyObject_GC_New(_grouperobject, &_grouper_type);
+ itertools_state *state = parent->state;
+ _grouperobject *igo = PyObject_GC_New(_grouperobject, state->_grouper_type);
if (igo == NULL)
return NULL;
- igo->parent = (PyObject *)parent;
- Py_INCREF(parent);
- igo->tgtkey = tgtkey;
- Py_INCREF(tgtkey);
+ igo->parent = Py_NewRef(parent);
+ igo->tgtkey = Py_NewRef(tgtkey);
parent->currgrouper = igo; /* borrowed reference */
PyObject_GC_Track(igo);
@@ -468,15 +634,18 @@ _grouper_create(groupbyobject *parent, PyObject *tgtkey)
static void
_grouper_dealloc(_grouperobject *igo)
{
+ PyTypeObject *tp = Py_TYPE(igo);
PyObject_GC_UnTrack(igo);
Py_DECREF(igo->parent);
Py_DECREF(igo->tgtkey);
PyObject_GC_Del(igo);
+ Py_DECREF(tp);
}
static int
_grouper_traverse(_grouperobject *igo, visitproc visit, void *arg)
{
+ Py_VISIT(Py_TYPE(igo));
Py_VISIT(igo->parent);
Py_VISIT(igo->tgtkey);
return 0;
@@ -512,6 +681,7 @@ _grouper_next(_grouperobject *igo)
static PyObject *
_grouper_reduce(_grouperobject *lz, PyObject *Py_UNUSED(ignored))
{
+ ITERTOOL_PICKLE_DEPRECATION;
if (((groupbyobject *)lz->parent)->currgrouper != lz) {
return Py_BuildValue("N(())", _PyEval_GetBuiltin(&_Py_ID(iter)));
}
@@ -524,48 +694,24 @@ static PyMethodDef _grouper_methods[] = {
{NULL, NULL} /* sentinel */
};
+static PyType_Slot _grouper_slots[] = {
+ {Py_tp_dealloc, _grouper_dealloc},
+ {Py_tp_getattro, PyObject_GenericGetAttr},
+ {Py_tp_traverse, _grouper_traverse},
+ {Py_tp_iter, PyObject_SelfIter},
+ {Py_tp_iternext, _grouper_next},
+ {Py_tp_methods, _grouper_methods},
+ {Py_tp_new, itertools__grouper},
+ {Py_tp_free, PyObject_GC_Del},
+ {0, NULL},
+};
-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_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, /* 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 */
- itertools__grouper, /* tp_new */
- PyObject_GC_Del, /* tp_free */
+static PyType_Spec _grouper_spec = {
+ .name = "itertools._grouper",
+ .basicsize = sizeof(_grouperobject),
+ .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+ Py_TPFLAGS_IMMUTABLETYPE),
+ .slots = _grouper_slots,
};
@@ -595,33 +741,32 @@ typedef struct {
teedataobject *dataobj;
int index; /* 0 <= index <= LINKCELLS */
PyObject *weakreflist;
+ itertools_state *state;
} teeobject;
static PyObject *
-teedataobject_newinternal(PyObject *it)
+teedataobject_newinternal(itertools_state *state, PyObject *it)
{
teedataobject *tdo;
- tdo = PyObject_GC_New(teedataobject, &teedataobject_type);
+ tdo = PyObject_GC_New(teedataobject, state->teedataobject_type);
if (tdo == NULL)
return NULL;
tdo->running = 0;
tdo->numread = 0;
tdo->nextlink = NULL;
- Py_INCREF(it);
- tdo->it = it;
+ tdo->it = Py_NewRef(it);
PyObject_GC_Track(tdo);
return (PyObject *)tdo;
}
static PyObject *
-teedataobject_jumplink(teedataobject *tdo)
+teedataobject_jumplink(itertools_state *state, teedataobject *tdo)
{
if (tdo->nextlink == NULL)
- tdo->nextlink = teedataobject_newinternal(tdo->it);
- Py_XINCREF(tdo->nextlink);
- return tdo->nextlink;
+ tdo->nextlink = teedataobject_newinternal(state, tdo->it);
+ return Py_XNewRef(tdo->nextlink);
}
static PyObject *
@@ -648,8 +793,7 @@ teedataobject_getitem(teedataobject *tdo, int i)
tdo->numread++;
tdo->values[i] = value;
}
- Py_INCREF(value);
- return value;
+ return Py_NewRef(value);
}
static int
@@ -657,6 +801,7 @@ teedataobject_traverse(teedataobject *tdo, visitproc visit, void * arg)
{
int i;
+ Py_VISIT(Py_TYPE(tdo));
Py_VISIT(tdo->it);
for (i = 0; i < tdo->numread; i++)
Py_VISIT(tdo->values[i]);
@@ -665,14 +810,13 @@ teedataobject_traverse(teedataobject *tdo, visitproc visit, void * arg)
}
static void
-teedataobject_safe_decref(PyObject *obj)
+teedataobject_safe_decref(PyObject *obj, PyTypeObject *tdo_type)
{
- while (obj && Py_IS_TYPE(obj, &teedataobject_type) &&
+ while (obj && Py_IS_TYPE(obj, tdo_type) &&
Py_REFCNT(obj) == 1) {
PyObject *nextlink = ((teedataobject *)obj)->nextlink;
((teedataobject *)obj)->nextlink = NULL;
- Py_DECREF(obj);
- obj = nextlink;
+ Py_SETREF(obj, nextlink);
}
Py_XDECREF(obj);
}
@@ -688,21 +832,25 @@ teedataobject_clear(teedataobject *tdo)
Py_CLEAR(tdo->values[i]);
tmp = tdo->nextlink;
tdo->nextlink = NULL;
- teedataobject_safe_decref(tmp);
+ itertools_state *state = get_module_state_by_cls(Py_TYPE(tdo));
+ teedataobject_safe_decref(tmp, state->teedataobject_type);
return 0;
}
static void
teedataobject_dealloc(teedataobject *tdo)
{
+ PyTypeObject *tp = Py_TYPE(tdo);
PyObject_GC_UnTrack(tdo);
teedataobject_clear(tdo);
PyObject_GC_Del(tdo);
+ Py_DECREF(tp);
}
static PyObject *
teedataobject_reduce(teedataobject *tdo, PyObject *Py_UNUSED(ignored))
{
+ ITERTOOL_PICKLE_DEPRECATION;
int i;
/* create a temporary list of already iterated values */
PyObject *values = PyList_New(tdo->numread);
@@ -736,9 +884,10 @@ itertools_teedataobject_impl(PyTypeObject *type, PyObject *it,
teedataobject *tdo;
Py_ssize_t i, len;
- assert(type == &teedataobject_type);
+ itertools_state *state = get_module_state_by_cls(type);
+ assert(type == state->teedataobject_type);
- tdo = (teedataobject *)teedataobject_newinternal(it);
+ tdo = (teedataobject *)teedataobject_newinternal(state, it);
if (!tdo)
return NULL;
@@ -754,11 +903,10 @@ itertools_teedataobject_impl(PyTypeObject *type, PyObject *it,
if (len == LINKCELLS) {
if (next != Py_None) {
- if (!Py_IS_TYPE(next, &teedataobject_type))
+ if (!Py_IS_TYPE(next, state->teedataobject_type))
goto err;
assert(tdo->nextlink == NULL);
- Py_INCREF(next);
- tdo->nextlink = next;
+ tdo->nextlink = Py_NewRef(next);
}
} else {
if (next != Py_None)
@@ -778,47 +926,24 @@ static PyMethodDef teedataobject_methods[] = {
{NULL, NULL} /* sentinel */
};
-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_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, /* tp_flags */
- itertools_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 */
- itertools_teedataobject, /* tp_new */
- PyObject_GC_Del, /* tp_free */
+static PyType_Slot teedataobject_slots[] = {
+ {Py_tp_dealloc, teedataobject_dealloc},
+ {Py_tp_getattro, PyObject_GenericGetAttr},
+ {Py_tp_doc, (void *)itertools_teedataobject__doc__},
+ {Py_tp_traverse, teedataobject_traverse},
+ {Py_tp_clear, teedataobject_clear},
+ {Py_tp_methods, teedataobject_methods},
+ {Py_tp_new, itertools_teedataobject},
+ {Py_tp_free, PyObject_GC_Del},
+ {0, NULL},
+};
+
+static PyType_Spec teedataobject_spec = {
+ .name = "itertools._tee_dataobject",
+ .basicsize = sizeof(teedataobject),
+ .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+ Py_TPFLAGS_IMMUTABLETYPE),
+ .slots = teedataobject_slots,
};
@@ -828,7 +953,7 @@ tee_next(teeobject *to)
PyObject *value, *link;
if (to->index >= LINKCELLS) {
- link = teedataobject_jumplink(to->dataobj);
+ link = teedataobject_jumplink(to->state, to->dataobj);
if (link == NULL)
return NULL;
Py_SETREF(to->dataobj, (teedataobject *)link);
@@ -844,6 +969,7 @@ tee_next(teeobject *to)
static int
tee_traverse(teeobject *to, visitproc visit, void *arg)
{
+ Py_VISIT(Py_TYPE(to));
Py_VISIT((PyObject *)to->dataobj);
return 0;
}
@@ -853,13 +979,13 @@ tee_copy(teeobject *to, PyObject *Py_UNUSED(ignored))
{
teeobject *newto;
- newto = PyObject_GC_New(teeobject, &tee_type);
+ newto = PyObject_GC_New(teeobject, Py_TYPE(to));
if (newto == NULL)
return NULL;
- Py_INCREF(to->dataobj);
- newto->dataobj = to->dataobj;
+ newto->dataobj = (teedataobject*)Py_NewRef(to->dataobj);
newto->index = to->index;
newto->weakreflist = NULL;
+ newto->state = to->state;
PyObject_GC_Track(newto);
return (PyObject *)newto;
}
@@ -867,7 +993,7 @@ tee_copy(teeobject *to, PyObject *Py_UNUSED(ignored))
PyDoc_STRVAR(teecopy_doc, "Returns an independent iterator.");
static PyObject *
-tee_fromiterable(PyObject *iterable)
+tee_fromiterable(itertools_state *state, PyObject *iterable)
{
teeobject *to;
PyObject *it;
@@ -875,17 +1001,17 @@ tee_fromiterable(PyObject *iterable)
it = PyObject_GetIter(iterable);
if (it == NULL)
return NULL;
- if (PyObject_TypeCheck(it, &tee_type)) {
+ if (PyObject_TypeCheck(it, state->tee_type)) {
to = (teeobject *)tee_copy((teeobject *)it, NULL);
goto done;
}
- PyObject *dataobj = teedataobject_newinternal(it);
+ PyObject *dataobj = teedataobject_newinternal(state, it);
if (!dataobj) {
to = NULL;
goto done;
}
- to = PyObject_GC_New(teeobject, &tee_type);
+ to = PyObject_GC_New(teeobject, state->tee_type);
if (to == NULL) {
Py_DECREF(dataobj);
goto done;
@@ -893,6 +1019,7 @@ tee_fromiterable(PyObject *iterable)
to->dataobj = (teedataobject *)dataobj;
to->index = 0;
to->weakreflist = NULL;
+ to->state = state;
PyObject_GC_Track(to);
done:
Py_DECREF(it);
@@ -911,7 +1038,8 @@ static PyObject *
itertools__tee_impl(PyTypeObject *type, PyObject *iterable)
/*[clinic end generated code: output=b02d3fd26c810c3f input=adc0779d2afe37a2]*/
{
- return tee_fromiterable(iterable);
+ itertools_state *state = get_module_state_by_cls(type);
+ return tee_fromiterable(state, iterable);
}
static int
@@ -926,27 +1054,32 @@ tee_clear(teeobject *to)
static void
tee_dealloc(teeobject *to)
{
+ PyTypeObject *tp = Py_TYPE(to);
PyObject_GC_UnTrack(to);
tee_clear(to);
PyObject_GC_Del(to);
+ Py_DECREF(tp);
}
static PyObject *
tee_reduce(teeobject *to, PyObject *Py_UNUSED(ignored))
{
+ ITERTOOL_PICKLE_DEPRECATION;
return Py_BuildValue("O(())(Oi)", Py_TYPE(to), to->dataobj, to->index);
}
static PyObject *
tee_setstate(teeobject *to, PyObject *state)
{
+ ITERTOOL_PICKLE_DEPRECATION;
teedataobject *tdo;
int index;
if (!PyTuple_Check(state)) {
PyErr_SetString(PyExc_TypeError, "state is not a tuple");
return NULL;
}
- if (!PyArg_ParseTuple(state, "O!i", &teedataobject_type, &tdo, &index)) {
+ PyTypeObject *tdo_type = to->state->teedataobject_type;
+ if (!PyArg_ParseTuple(state, "O!i", tdo_type, &tdo, &index)) {
return NULL;
}
if (index < 0 || index > LINKCELLS) {
@@ -966,47 +1099,31 @@ static PyMethodDef tee_methods[] = {
{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_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 */
- 0, /* tp_getattro */
- 0, /* tp_setattro */
- 0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
- itertools__tee__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 */
- itertools__tee, /* tp_new */
- PyObject_GC_Del, /* tp_free */
+static PyMemberDef tee_members[] = {
+ {"__weaklistoffset__", T_PYSSIZET, offsetof(teeobject, weakreflist), READONLY},
+ {NULL},
+};
+
+static PyType_Slot tee_slots[] = {
+ {Py_tp_dealloc, tee_dealloc},
+ {Py_tp_doc, (void *)itertools__tee__doc__},
+ {Py_tp_traverse, tee_traverse},
+ {Py_tp_clear, tee_clear},
+ {Py_tp_iter, PyObject_SelfIter},
+ {Py_tp_iternext, tee_next},
+ {Py_tp_methods, tee_methods},
+ {Py_tp_members, tee_members},
+ {Py_tp_new, itertools__tee},
+ {Py_tp_free, PyObject_GC_Del},
+ {0, NULL},
+};
+
+static PyType_Spec tee_spec = {
+ .name = "itertools._tee",
+ .basicsize = sizeof(teeobject),
+ .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+ Py_TPFLAGS_IMMUTABLETYPE),
+ .slots = tee_slots,
};
/*[clinic input]
@@ -1048,7 +1165,8 @@ itertools_tee_impl(PyObject *module, PyObject *iterable, Py_ssize_t n)
copyable = it;
}
else {
- copyable = tee_fromiterable(it);
+ itertools_state *state = get_module_state(module);
+ copyable = tee_fromiterable(state, it);
Py_DECREF(it);
if (copyable == NULL) {
Py_DECREF(result);
@@ -1132,15 +1250,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;
@@ -1173,13 +1294,13 @@ cycle_next(cycleobject *lz)
lz->index++;
if (lz->index >= PyList_GET_SIZE(lz->saved))
lz->index = 0;
- Py_INCREF(item);
- return item;
+ return Py_NewRef(item);
}
static PyObject *
cycle_reduce(cycleobject *lz, PyObject *Py_UNUSED(ignored))
{
+ ITERTOOL_PICKLE_DEPRECATION;
/* Create a new cycle with the iterator tuple, then set the saved state */
if (lz->it == NULL) {
PyObject *it = PyObject_GetIter(lz->saved);
@@ -1203,6 +1324,7 @@ cycle_reduce(cycleobject *lz, PyObject *Py_UNUSED(ignored))
static PyObject *
cycle_setstate(cycleobject *lz, PyObject *state)
{
+ ITERTOOL_PICKLE_DEPRECATION;
PyObject *saved=NULL;
int firstpass;
if (!PyTuple_Check(state)) {
@@ -1228,48 +1350,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,
};
@@ -1311,8 +1410,7 @@ itertools_dropwhile_impl(PyTypeObject *type, PyObject *func, PyObject *seq)
Py_DECREF(it);
return NULL;
}
- Py_INCREF(func);
- lz->func = func;
+ lz->func = Py_NewRef(func);
lz->it = it;
lz->start = 0;
@@ -1322,15 +1420,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;
@@ -1372,12 +1473,14 @@ dropwhile_next(dropwhileobject *lz)
static PyObject *
dropwhile_reduce(dropwhileobject *lz, PyObject *Py_UNUSED(ignored))
{
+ ITERTOOL_PICKLE_DEPRECATION;
return Py_BuildValue("O(OO)l", Py_TYPE(lz), lz->func, lz->it, lz->start);
}
static PyObject *
dropwhile_setstate(dropwhileobject *lz, PyObject *state)
{
+ ITERTOOL_PICKLE_DEPRECATION;
int start = PyObject_IsTrue(state);
if (start < 0)
return NULL;
@@ -1393,48 +1496,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,
};
@@ -1474,8 +1554,7 @@ itertools_takewhile_impl(PyTypeObject *type, PyObject *func, PyObject *seq)
Py_DECREF(it);
return NULL;
}
- Py_INCREF(func);
- lz->func = func;
+ lz->func = Py_NewRef(func);
lz->it = it;
lz->stop = 0;
@@ -1485,15 +1564,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;
@@ -1531,12 +1613,14 @@ takewhile_next(takewhileobject *lz)
static PyObject *
takewhile_reduce(takewhileobject *lz, PyObject *Py_UNUSED(ignored))
{
+ ITERTOOL_PICKLE_DEPRECATION;
return Py_BuildValue("O(OO)l", Py_TYPE(lz), lz->func, lz->it, lz->stop);
}
static PyObject *
takewhile_reduce_setstate(takewhileobject *lz, PyObject *state)
{
+ ITERTOOL_PICKLE_DEPRECATION;
int stop = PyObject_IsTrue(state);
if (stop < 0)
@@ -1553,48 +1637,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,
};
@@ -1609,8 +1670,6 @@ typedef struct {
Py_ssize_t cnt;
} isliceobject;
-static PyTypeObject islice_type;
-
static PyObject *
islice_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
@@ -1620,7 +1679,9 @@ islice_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
Py_ssize_t numargs;
isliceobject *lz;
- if ((type == &islice_type || type->tp_init == islice_type.tp_init) &&
+ itertools_state *st = find_state_by_type(type);
+ PyTypeObject *islice_type = st->islice_type;
+ if ((type == islice_type || type->tp_init == islice_type->tp_init) &&
!_PyArg_NoKeywords("islice", kwds))
return NULL;
@@ -1699,14 +1760,17 @@ islice_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
static void
islice_dealloc(isliceobject *lz)
{
+ PyTypeObject *tp = Py_TYPE(lz);
PyObject_GC_UnTrack(lz);
Py_XDECREF(lz->it);
- Py_TYPE(lz)->tp_free(lz);
+ tp->tp_free(lz);
+ Py_DECREF(tp);
}
static int
islice_traverse(isliceobject *lz, visitproc visit, void *arg)
{
+ Py_VISIT(Py_TYPE(lz));
Py_VISIT(lz->it);
return 0;
}
@@ -1753,6 +1817,7 @@ empty:
static PyObject *
islice_reduce(isliceobject *lz, PyObject *Py_UNUSED(ignored))
{
+ ITERTOOL_PICKLE_DEPRECATION;
/* When unpickled, generate a new object with the same bounds,
* then 'setstate' with the next and count
*/
@@ -1771,8 +1836,7 @@ islice_reduce(isliceobject *lz, PyObject *Py_UNUSED(ignored))
return Py_BuildValue("O(Nn)n", Py_TYPE(lz), empty_it, 0, 0);
}
if (lz->stop == -1) {
- stop = Py_None;
- Py_INCREF(stop);
+ stop = Py_NewRef(Py_None);
} else {
stop = PyLong_FromSsize_t(lz->stop);
if (stop == NULL)
@@ -1786,6 +1850,7 @@ islice_reduce(isliceobject *lz, PyObject *Py_UNUSED(ignored))
static PyObject *
islice_setstate(isliceobject *lz, PyObject *state)
{
+ ITERTOOL_PICKLE_DEPRECATION;
Py_ssize_t cnt = PyLong_AsSsize_t(state);
if (cnt == -1 && PyErr_Occurred())
@@ -1813,48 +1878,25 @@ specified as another value, step determines how many values are\n\
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_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 */
- 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 */
+static PyType_Slot islice_slots[] = {
+ {Py_tp_dealloc, islice_dealloc},
+ {Py_tp_getattro, PyObject_GenericGetAttr},
+ {Py_tp_doc, (void *)islice_doc},
+ {Py_tp_traverse, islice_traverse},
+ {Py_tp_iter, PyObject_SelfIter},
+ {Py_tp_iternext, islice_next},
+ {Py_tp_methods, islice_methods},
+ {Py_tp_new, islice_new},
+ {Py_tp_free, PyObject_GC_Del},
+ {0, NULL},
+};
+
+static PyType_Spec islice_spec = {
+ .name = "itertools.islice",
+ .basicsize = sizeof(isliceobject),
+ .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE |
+ Py_TPFLAGS_IMMUTABLETYPE),
+ .slots = islice_slots,
};
@@ -1893,8 +1935,7 @@ itertools_starmap_impl(PyTypeObject *type, PyObject *func, PyObject *seq)
Py_DECREF(it);
return NULL;
}
- Py_INCREF(func);
- lz->func = func;
+ lz->func = Py_NewRef(func);
lz->it = it;
return (PyObject *)lz;
@@ -1903,15 +1944,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;
@@ -1942,6 +1986,7 @@ starmap_next(starmapobject *lz)
static PyObject *
starmap_reduce(starmapobject *lz, PyObject *Py_UNUSED(ignored))
{
+ ITERTOOL_PICKLE_DEPRECATION;
/* Just pickle the iterator */
return Py_BuildValue("O(OO)", Py_TYPE(lz), lz->func, lz->it);
}
@@ -1952,48 +1997,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,
};
@@ -2005,8 +2027,6 @@ typedef struct {
PyObject *active; /* Currently running input iterator */
} chainobject;
-static PyTypeObject chain_type;
-
static PyObject *
chain_new_internal(PyTypeObject *type, PyObject *source)
{
@@ -2028,7 +2048,9 @@ chain_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
PyObject *source;
- if ((type == &chain_type || type->tp_init == chain_type.tp_init) &&
+ itertools_state *state = find_state_by_type(type);
+ PyTypeObject *chain_type = state->chain_type;
+ if ((type == chain_type || type->tp_init == chain_type->tp_init) &&
!_PyArg_NoKeywords("chain", kwds))
return NULL;
@@ -2063,15 +2085,18 @@ itertools_chain_from_iterable(PyTypeObject *type, PyObject *arg)
static void
chain_dealloc(chainobject *lz)
{
+ PyTypeObject *tp = Py_TYPE(lz);
PyObject_GC_UnTrack(lz);
Py_XDECREF(lz->active);
Py_XDECREF(lz->source);
- Py_TYPE(lz)->tp_free(lz);
+ tp->tp_free(lz);
+ Py_DECREF(tp);
}
static int
chain_traverse(chainobject *lz, visitproc visit, void *arg)
{
+ Py_VISIT(Py_TYPE(lz));
Py_VISIT(lz->source);
Py_VISIT(lz->active);
return 0;
@@ -2118,6 +2143,7 @@ chain_next(chainobject *lz)
static PyObject *
chain_reduce(chainobject *lz, PyObject *Py_UNUSED(ignored))
{
+ ITERTOOL_PICKLE_DEPRECATION;
if (lz->source) {
/* we can't pickle function objects (itertools.from_iterable) so
* we must use setstate to replace the iterable. One day we
@@ -2137,6 +2163,7 @@ chain_reduce(chainobject *lz, PyObject *Py_UNUSED(ignored))
static PyObject *
chain_setstate(chainobject *lz, PyObject *state)
{
+ ITERTOOL_PICKLE_DEPRECATION;
PyObject *source, *active=NULL;
if (!PyTuple_Check(state)) {
@@ -2176,48 +2203,25 @@ static PyMethodDef chain_methods[] = {
{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_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 */
- 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 */
+static PyType_Slot chain_slots[] = {
+ {Py_tp_dealloc, chain_dealloc},
+ {Py_tp_getattro, PyObject_GenericGetAttr},
+ {Py_tp_doc, (void *)chain_doc},
+ {Py_tp_traverse, chain_traverse},
+ {Py_tp_iter, PyObject_SelfIter},
+ {Py_tp_iternext, chain_next},
+ {Py_tp_methods, chain_methods},
+ {Py_tp_new, chain_new},
+ {Py_tp_free, PyObject_GC_Del},
+ {0, NULL},
+};
+
+static PyType_Spec chain_spec = {
+ .name = "itertools.chain",
+ .basicsize = sizeof(chainobject),
+ .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE |
+ Py_TPFLAGS_IMMUTABLETYPE),
+ .slots = chain_slots,
};
@@ -2231,8 +2235,6 @@ typedef struct {
int stopped; /* set to 1 when the iterator is exhausted */
} productobject;
-static PyTypeObject product_type;
-
static PyObject *
product_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
@@ -2319,22 +2321,22 @@ error:
static void
product_dealloc(productobject *lz)
{
+ PyTypeObject *tp = 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);
+ tp->tp_free(lz);
+ Py_DECREF(tp);
}
static PyObject *
product_sizeof(productobject *lz, void *unused)
{
- Py_ssize_t res;
-
- res = _PyObject_SIZE(Py_TYPE(lz));
- res += PyTuple_GET_SIZE(lz->pools) * sizeof(Py_ssize_t);
- return PyLong_FromSsize_t(res);
+ size_t res = _PyObject_SIZE(Py_TYPE(lz));
+ res += (size_t)PyTuple_GET_SIZE(lz->pools) * sizeof(Py_ssize_t);
+ return PyLong_FromSize_t(res);
}
PyDoc_STRVAR(sizeof_doc, "Returns size in memory, in bytes.");
@@ -2342,6 +2344,7 @@ PyDoc_STRVAR(sizeof_doc, "Returns size in memory, in bytes.");
static int
product_traverse(productobject *lz, visitproc visit, void *arg)
{
+ Py_VISIT(Py_TYPE(lz));
Py_VISIT(lz->pools);
Py_VISIT(lz->result);
return 0;
@@ -2426,8 +2429,7 @@ product_next(productobject *lz)
goto empty;
}
- Py_INCREF(result);
- return result;
+ return Py_NewRef(result);
empty:
lz->stopped = 1;
@@ -2437,6 +2439,7 @@ empty:
static PyObject *
product_reduce(productobject *lz, PyObject *Py_UNUSED(ignored))
{
+ ITERTOOL_PICKLE_DEPRECATION;
if (lz->stopped) {
return Py_BuildValue("O(())", Py_TYPE(lz));
} else if (lz->result == NULL) {
@@ -2467,6 +2470,7 @@ product_reduce(productobject *lz, PyObject *Py_UNUSED(ignored))
static PyObject *
product_setstate(productobject *lz, PyObject *state)
{
+ ITERTOOL_PICKLE_DEPRECATION;
PyObject *result;
Py_ssize_t n, i;
@@ -2534,48 +2538,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((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_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 */
- 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 */
+static PyType_Slot product_slots[] = {
+ {Py_tp_dealloc, product_dealloc},
+ {Py_tp_getattro, PyObject_GenericGetAttr},
+ {Py_tp_doc, (void *)product_doc},
+ {Py_tp_traverse, product_traverse},
+ {Py_tp_iter, PyObject_SelfIter},
+ {Py_tp_iternext, product_next},
+ {Py_tp_methods, product_methods},
+ {Py_tp_new, product_new},
+ {Py_tp_free, PyObject_GC_Del},
+ {0, NULL},
+};
+
+static PyType_Spec product_spec = {
+ .name = "itertools.product",
+ .basicsize = sizeof(productobject),
+ .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE |
+ Py_TPFLAGS_IMMUTABLETYPE),
+ .slots = product_slots,
};
@@ -2653,27 +2634,28 @@ 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 *
combinations_sizeof(combinationsobject *co, void *unused)
{
- Py_ssize_t res;
-
- res = _PyObject_SIZE(Py_TYPE(co));
- res += co->r * sizeof(Py_ssize_t);
- return PyLong_FromSsize_t(res);
+ size_t res = _PyObject_SIZE(Py_TYPE(co));
+ res += (size_t)co->r * sizeof(Py_ssize_t);
+ return PyLong_FromSize_t(res);
}
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;
@@ -2757,8 +2739,7 @@ combinations_next(combinationsobject *co)
}
}
- Py_INCREF(result);
- return result;
+ return Py_NewRef(result);
empty:
co->stopped = 1;
@@ -2768,6 +2749,7 @@ empty:
static PyObject *
combinations_reduce(combinationsobject *lz, PyObject *Py_UNUSED(ignored))
{
+ ITERTOOL_PICKLE_DEPRECATION;
if (lz->result == NULL) {
return Py_BuildValue("O(On)", Py_TYPE(lz), lz->pool, lz->r);
} else if (lz->stopped) {
@@ -2797,6 +2779,7 @@ combinations_reduce(combinationsobject *lz, PyObject *Py_UNUSED(ignored))
static PyObject *
combinations_setstate(combinationsobject *lz, PyObject *state)
{
+ ITERTOOL_PICKLE_DEPRECATION;
PyObject *result;
Py_ssize_t i;
Py_ssize_t n = PyTuple_GET_SIZE(lz->pool);
@@ -2845,48 +2828,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,
};
@@ -2990,27 +2950,28 @@ 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 *
cwr_sizeof(cwrobject *co, void *unused)
{
- Py_ssize_t res;
-
- res = _PyObject_SIZE(Py_TYPE(co));
- res += co->r * sizeof(Py_ssize_t);
- return PyLong_FromSsize_t(res);
+ size_t res = _PyObject_SIZE(Py_TYPE(co));
+ res += (size_t)co->r * sizeof(Py_ssize_t);
+ return PyLong_FromSize_t(res);
}
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;
@@ -3088,8 +3049,7 @@ cwr_next(cwrobject *co)
}
}
- Py_INCREF(result);
- return result;
+ return Py_NewRef(result);
empty:
co->stopped = 1;
@@ -3099,6 +3059,7 @@ empty:
static PyObject *
cwr_reduce(cwrobject *lz, PyObject *Py_UNUSED(ignored))
{
+ ITERTOOL_PICKLE_DEPRECATION;
if (lz->result == NULL) {
return Py_BuildValue("O(On)", Py_TYPE(lz), lz->pool, lz->r);
} else if (lz->stopped) {
@@ -3127,6 +3088,7 @@ cwr_reduce(cwrobject *lz, PyObject *Py_UNUSED(ignored))
static PyObject *
cwr_setstate(cwrobject *lz, PyObject *state)
{
+ ITERTOOL_PICKLE_DEPRECATION;
PyObject *result;
Py_ssize_t n, i;
@@ -3172,48 +3134,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,
};
@@ -3336,28 +3275,29 @@ 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 *
permutations_sizeof(permutationsobject *po, void *unused)
{
- Py_ssize_t res;
-
- res = _PyObject_SIZE(Py_TYPE(po));
- res += PyTuple_GET_SIZE(po->pool) * sizeof(Py_ssize_t);
- res += po->r * sizeof(Py_ssize_t);
- return PyLong_FromSsize_t(res);
+ size_t res = _PyObject_SIZE(Py_TYPE(po));
+ res += (size_t)PyTuple_GET_SIZE(po->pool) * sizeof(Py_ssize_t);
+ res += (size_t)po->r * sizeof(Py_ssize_t);
+ return PyLong_FromSize_t(res);
}
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;
@@ -3446,8 +3386,7 @@ permutations_next(permutationsobject *po)
if (i < 0)
goto empty;
}
- Py_INCREF(result);
- return result;
+ return Py_NewRef(result);
empty:
po->stopped = 1;
@@ -3457,6 +3396,7 @@ empty:
static PyObject *
permutations_reduce(permutationsobject *po, PyObject *Py_UNUSED(ignored))
{
+ ITERTOOL_PICKLE_DEPRECATION;
if (po->result == NULL) {
return Py_BuildValue("O(On)", Py_TYPE(po), po->pool, po->r);
} else if (po->stopped) {
@@ -3499,6 +3439,7 @@ permutations_reduce(permutationsobject *po, PyObject *Py_UNUSED(ignored))
static PyObject *
permutations_setstate(permutationsobject *po, PyObject *state)
{
+ ITERTOOL_PICKLE_DEPRECATION;
PyObject *indices, *cycles, *result;
Py_ssize_t n, i;
@@ -3564,48 +3505,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,
};
@@ -3617,6 +3535,7 @@ typedef struct {
PyObject *it;
PyObject *binop;
PyObject *initial;
+ itertools_state *state;
} accumulateobject;
/*[clinic input]
@@ -3650,30 +3569,32 @@ itertools_accumulate_impl(PyTypeObject *type, PyObject *iterable,
}
if (binop != Py_None) {
- Py_XINCREF(binop);
- lz->binop = binop;
+ lz->binop = Py_XNewRef(binop);
}
lz->total = NULL;
lz->it = it;
- Py_XINCREF(initial);
- lz->initial = initial;
+ lz->initial = Py_XNewRef(initial);
+ lz->state = find_state_by_type(type);
return (PyObject *)lz;
}
static void
accumulate_dealloc(accumulateobject *lz)
{
+ PyTypeObject *tp = Py_TYPE(lz);
PyObject_GC_UnTrack(lz);
Py_XDECREF(lz->binop);
Py_XDECREF(lz->total);
Py_XDECREF(lz->it);
Py_XDECREF(lz->initial);
- Py_TYPE(lz)->tp_free(lz);
+ tp->tp_free(lz);
+ Py_DECREF(tp);
}
static int
accumulate_traverse(accumulateobject *lz, visitproc visit, void *arg)
{
+ Py_VISIT(Py_TYPE(lz));
Py_VISIT(lz->binop);
Py_VISIT(lz->it);
Py_VISIT(lz->total);
@@ -3688,18 +3609,15 @@ accumulate_next(accumulateobject *lz)
if (lz->initial != Py_None) {
lz->total = lz->initial;
- Py_INCREF(Py_None);
- lz->initial = Py_None;
- Py_INCREF(lz->total);
- return lz->total;
+ lz->initial = Py_NewRef(Py_None);
+ return Py_NewRef(lz->total);
}
val = (*Py_TYPE(lz->it)->tp_iternext)(lz->it);
if (val == NULL)
return NULL;
if (lz->total == NULL) {
- Py_INCREF(val);
- lz->total = val;
+ lz->total = Py_NewRef(val);
return lz->total;
}
@@ -3719,13 +3637,14 @@ accumulate_next(accumulateobject *lz)
static PyObject *
accumulate_reduce(accumulateobject *lz, PyObject *Py_UNUSED(ignored))
{
+ ITERTOOL_PICKLE_DEPRECATION;
+ itertools_state *state = lz->state;
+
if (lz->initial != Py_None) {
PyObject *it;
assert(lz->total == NULL);
- if (PyType_Ready(&chain_type) < 0)
- return NULL;
- it = PyObject_CallFunction((PyObject *)&chain_type, "(O)O",
+ it = PyObject_CallFunction((PyObject *)(state->chain_type), "(O)O",
lz->initial, lz->it);
if (it == NULL)
return NULL;
@@ -3735,11 +3654,7 @@ accumulate_reduce(accumulateobject *lz, PyObject *Py_UNUSED(ignored))
if (lz->total == Py_None) {
PyObject *it;
- if (PyType_Ready(&chain_type) < 0)
- return NULL;
- if (PyType_Ready(&islice_type) < 0)
- return NULL;
- it = PyObject_CallFunction((PyObject *)&chain_type, "(O)O",
+ it = PyObject_CallFunction((PyObject *)(state->chain_type), "(O)O",
lz->total, lz->it);
if (it == NULL)
return NULL;
@@ -3747,7 +3662,8 @@ accumulate_reduce(accumulateobject *lz, PyObject *Py_UNUSED(ignored))
it, lz->binop ? lz->binop : Py_None);
if (it == NULL)
return NULL;
- return Py_BuildValue("O(NiO)", &islice_type, it, 1, Py_None);
+
+ return Py_BuildValue("O(NiO)", state->islice_type, it, 1, Py_None);
}
return Py_BuildValue("O(OO)O", Py_TYPE(lz),
lz->it, lz->binop?lz->binop:Py_None,
@@ -3757,6 +3673,7 @@ accumulate_reduce(accumulateobject *lz, PyObject *Py_UNUSED(ignored))
static PyObject *
accumulate_setstate(accumulateobject *lz, PyObject *state)
{
+ ITERTOOL_PICKLE_DEPRECATION;
Py_INCREF(state);
Py_XSETREF(lz->total, state);
Py_RETURN_NONE;
@@ -3770,48 +3687,25 @@ static PyMethodDef accumulate_methods[] = {
{NULL, NULL} /* sentinel */
};
-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_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_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 */
+static PyType_Slot accumulate_slots[] = {
+ {Py_tp_dealloc, accumulate_dealloc},
+ {Py_tp_getattro, PyObject_GenericGetAttr},
+ {Py_tp_doc, (void *)itertools_accumulate__doc__},
+ {Py_tp_traverse, accumulate_traverse},
+ {Py_tp_iter, PyObject_SelfIter},
+ {Py_tp_iternext, accumulate_next},
+ {Py_tp_methods, accumulate_methods},
+ {Py_tp_new, itertools_accumulate},
+ {Py_tp_free, PyObject_GC_Del},
+ {0, NULL},
+};
+
+static PyType_Spec accumulate_spec = {
+ .name = "itertools.accumulate",
+ .basicsize = sizeof(accumulateobject),
+ .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE |
+ Py_TPFLAGS_IMMUTABLETYPE),
+ .slots = accumulate_slots,
};
@@ -3872,15 +3766,18 @@ fail:
static void
compress_dealloc(compressobject *lz)
{
+ PyTypeObject *tp = Py_TYPE(lz);
PyObject_GC_UnTrack(lz);
Py_XDECREF(lz->data);
Py_XDECREF(lz->selectors);
- Py_TYPE(lz)->tp_free(lz);
+ tp->tp_free(lz);
+ Py_DECREF(tp);
}
static int
compress_traverse(compressobject *lz, visitproc visit, void *arg)
{
+ Py_VISIT(Py_TYPE(lz));
Py_VISIT(lz->data);
Py_VISIT(lz->selectors);
return 0;
@@ -3925,6 +3822,7 @@ compress_next(compressobject *lz)
static PyObject *
compress_reduce(compressobject *lz, PyObject *Py_UNUSED(ignored))
{
+ ITERTOOL_PICKLE_DEPRECATION;
return Py_BuildValue("O(OO)", Py_TYPE(lz),
lz->data, lz->selectors);
}
@@ -3935,48 +3833,25 @@ static PyMethodDef compress_methods[] = {
{NULL, NULL} /* sentinel */
};
-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_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_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 */
+static PyType_Slot compress_slots[] = {
+ {Py_tp_dealloc, compress_dealloc},
+ {Py_tp_getattro, PyObject_GenericGetAttr},
+ {Py_tp_doc, (void *)itertools_compress__doc__},
+ {Py_tp_traverse, compress_traverse},
+ {Py_tp_iter, PyObject_SelfIter},
+ {Py_tp_iternext, compress_next},
+ {Py_tp_methods, compress_methods},
+ {Py_tp_new, itertools_compress},
+ {Py_tp_free, PyObject_GC_Del},
+ {0, NULL},
+};
+
+static PyType_Spec compress_spec = {
+ .name = "itertools.compress",
+ .basicsize = sizeof(compressobject),
+ .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE |
+ Py_TPFLAGS_IMMUTABLETYPE),
+ .slots = compress_slots,
};
@@ -4017,8 +3892,7 @@ itertools_filterfalse_impl(PyTypeObject *type, PyObject *func, PyObject *seq)
Py_DECREF(it);
return NULL;
}
- Py_INCREF(func);
- lz->func = func;
+ lz->func = Py_NewRef(func);
lz->it = it;
return (PyObject *)lz;
@@ -4027,15 +3901,18 @@ itertools_filterfalse_impl(PyTypeObject *type, PyObject *func, PyObject *seq)
static void
filterfalse_dealloc(filterfalseobject *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
filterfalse_traverse(filterfalseobject *lz, visitproc visit, void *arg)
{
+ Py_VISIT(Py_TYPE(lz));
Py_VISIT(lz->it);
Py_VISIT(lz->func);
return 0;
@@ -4078,6 +3955,7 @@ filterfalse_next(filterfalseobject *lz)
static PyObject *
filterfalse_reduce(filterfalseobject *lz, PyObject *Py_UNUSED(ignored))
{
+ ITERTOOL_PICKLE_DEPRECATION;
return Py_BuildValue("O(OO)", Py_TYPE(lz), lz->func, lz->it);
}
@@ -4087,48 +3965,25 @@ static PyMethodDef filterfalse_methods[] = {
{NULL, NULL} /* sentinel */
};
-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_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_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 */
+static PyType_Slot filterfalse_slots[] = {
+ {Py_tp_dealloc, filterfalse_dealloc},
+ {Py_tp_getattro, PyObject_GenericGetAttr},
+ {Py_tp_doc, (void *)itertools_filterfalse__doc__},
+ {Py_tp_traverse, filterfalse_traverse},
+ {Py_tp_iter, PyObject_SelfIter},
+ {Py_tp_iternext, filterfalse_next},
+ {Py_tp_methods, filterfalse_methods},
+ {Py_tp_new, itertools_filterfalse},
+ {Py_tp_free, PyObject_GC_Del},
+ {0, NULL},
+};
+
+static PyType_Spec filterfalse_spec = {
+ .name = "itertools.filterfalse",
+ .basicsize = sizeof(filterfalseobject),
+ .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE |
+ Py_TPFLAGS_IMMUTABLETYPE),
+ .slots = filterfalse_slots,
};
@@ -4254,15 +4109,18 @@ itertools_count_impl(PyTypeObject *type, PyObject *long_cnt,
static void
count_dealloc(countobject *lz)
{
+ PyTypeObject *tp = Py_TYPE(lz);
PyObject_GC_UnTrack(lz);
Py_XDECREF(lz->long_cnt);
Py_XDECREF(lz->long_step);
- Py_TYPE(lz)->tp_free(lz);
+ tp->tp_free(lz);
+ Py_DECREF(tp);
}
static int
count_traverse(countobject *lz, visitproc visit, void *arg)
{
+ Py_VISIT(Py_TYPE(lz));
Py_VISIT(lz->long_cnt);
Py_VISIT(lz->long_step);
return 0;
@@ -4325,6 +4183,7 @@ count_repr(countobject *lz)
static PyObject *
count_reduce(countobject *lz, PyObject *Py_UNUSED(ignored))
{
+ ITERTOOL_PICKLE_DEPRECATION;
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);
@@ -4336,48 +4195,26 @@ static PyMethodDef count_methods[] = {
{NULL, NULL} /* sentinel */
};
-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_vectorcall_offset */
- 0, /* tp_getattr */
- 0, /* tp_setattr */
- 0, /* tp_as_async */
- (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 */
- 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 */
+static PyType_Slot count_slots[] = {
+ {Py_tp_dealloc, count_dealloc},
+ {Py_tp_repr, count_repr},
+ {Py_tp_getattro, PyObject_GenericGetAttr},
+ {Py_tp_doc, (void *)itertools_count__doc__},
+ {Py_tp_traverse, count_traverse},
+ {Py_tp_iter, PyObject_SelfIter},
+ {Py_tp_iternext, count_next},
+ {Py_tp_methods, count_methods},
+ {Py_tp_new, itertools_count},
+ {Py_tp_free, PyObject_GC_Del},
+ {0, NULL},
+};
+
+static PyType_Spec count_spec = {
+ .name = "itertools.count",
+ .basicsize = sizeof(countobject),
+ .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE |
+ Py_TPFLAGS_IMMUTABLETYPE),
+ .slots = count_slots,
};
@@ -4389,8 +4226,6 @@ typedef struct {
Py_ssize_t cnt;
} repeatobject;
-static PyTypeObject repeat_type;
-
static PyObject *
repeat_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
@@ -4412,8 +4247,7 @@ repeat_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
ro = (repeatobject *)type->tp_alloc(type, 0);
if (ro == NULL)
return NULL;
- Py_INCREF(element);
- ro->element = element;
+ ro->element = Py_NewRef(element);
ro->cnt = cnt;
return (PyObject *)ro;
}
@@ -4421,14 +4255,17 @@ repeat_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
static void
repeat_dealloc(repeatobject *ro)
{
+ PyTypeObject *tp = Py_TYPE(ro);
PyObject_GC_UnTrack(ro);
Py_XDECREF(ro->element);
- Py_TYPE(ro)->tp_free(ro);
+ tp->tp_free(ro);
+ Py_DECREF(tp);
}
static int
repeat_traverse(repeatobject *ro, visitproc visit, void *arg)
{
+ Py_VISIT(Py_TYPE(ro));
Py_VISIT(ro->element);
return 0;
}
@@ -4440,8 +4277,7 @@ repeat_next(repeatobject *ro)
return NULL;
if (ro->cnt > 0)
ro->cnt--;
- Py_INCREF(ro->element);
- return ro->element;
+ return Py_NewRef(ro->element);
}
static PyObject *
@@ -4471,6 +4307,7 @@ PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(
static PyObject *
repeat_reduce(repeatobject *ro, PyObject *Py_UNUSED(ignored))
{
+ ITERTOOL_PICKLE_DEPRECATION;
/* unpickle this so that a new repeat iterator is constructed with an
* object, then call __setstate__ on it to set cnt
*/
@@ -4491,48 +4328,26 @@ PyDoc_STRVAR(repeat_doc,
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_vectorcall_offset */
- 0, /* tp_getattr */
- 0, /* tp_setattr */
- 0, /* tp_as_async */
- (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 */
- 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 */
+static PyType_Slot repeat_slots[] = {
+ {Py_tp_dealloc, repeat_dealloc},
+ {Py_tp_repr, repeat_repr},
+ {Py_tp_getattro, PyObject_GenericGetAttr},
+ {Py_tp_doc, (void *)repeat_doc},
+ {Py_tp_traverse, repeat_traverse},
+ {Py_tp_iter, PyObject_SelfIter},
+ {Py_tp_iternext, repeat_next},
+ {Py_tp_methods, repeat_methods},
+ {Py_tp_new, repeat_new},
+ {Py_tp_free, PyObject_GC_Del},
+ {0, NULL},
+};
+
+static PyType_Spec repeat_spec = {
+ .name = "itertools.repeat",
+ .basicsize = sizeof(repeatobject),
+ .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE |
+ Py_TPFLAGS_IMMUTABLETYPE),
+ .slots = repeat_slots,
};
@@ -4547,8 +4362,6 @@ typedef struct {
PyObject *fillvalue;
} ziplongestobject;
-static PyTypeObject ziplongest_type;
-
static PyObject *
zip_longest_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
@@ -4613,24 +4426,26 @@ zip_longest_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
lz->tuplesize = tuplesize;
lz->numactive = tuplesize;
lz->result = result;
- Py_INCREF(fillvalue);
- lz->fillvalue = fillvalue;
+ lz->fillvalue = Py_NewRef(fillvalue);
return (PyObject *)lz;
}
static void
zip_longest_dealloc(ziplongestobject *lz)
{
+ PyTypeObject *tp = 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);
+ tp->tp_free(lz);
+ Py_DECREF(tp);
}
static int
zip_longest_traverse(ziplongestobject *lz, visitproc visit, void *arg)
{
+ Py_VISIT(Py_TYPE(lz));
Py_VISIT(lz->ittuple);
Py_VISIT(lz->result);
Py_VISIT(lz->fillvalue);
@@ -4656,8 +4471,7 @@ zip_longest_next(ziplongestobject *lz)
for (i=0 ; i < tuplesize ; i++) {
it = PyTuple_GET_ITEM(lz->ittuple, i);
if (it == NULL) {
- Py_INCREF(lz->fillvalue);
- item = lz->fillvalue;
+ item = Py_NewRef(lz->fillvalue);
} else {
item = PyIter_Next(it);
if (item == NULL) {
@@ -4667,8 +4481,7 @@ zip_longest_next(ziplongestobject *lz)
Py_DECREF(result);
return NULL;
} else {
- Py_INCREF(lz->fillvalue);
- item = lz->fillvalue;
+ item = Py_NewRef(lz->fillvalue);
PyTuple_SET_ITEM(lz->ittuple, i, NULL);
Py_DECREF(it);
}
@@ -4690,8 +4503,7 @@ zip_longest_next(ziplongestobject *lz)
for (i=0 ; i < tuplesize ; i++) {
it = PyTuple_GET_ITEM(lz->ittuple, i);
if (it == NULL) {
- Py_INCREF(lz->fillvalue);
- item = lz->fillvalue;
+ item = Py_NewRef(lz->fillvalue);
} else {
item = PyIter_Next(it);
if (item == NULL) {
@@ -4701,8 +4513,7 @@ zip_longest_next(ziplongestobject *lz)
Py_DECREF(result);
return NULL;
} else {
- Py_INCREF(lz->fillvalue);
- item = lz->fillvalue;
+ item = Py_NewRef(lz->fillvalue);
PyTuple_SET_ITEM(lz->ittuple, i, NULL);
Py_DECREF(it);
}
@@ -4717,7 +4528,7 @@ zip_longest_next(ziplongestobject *lz)
static PyObject *
zip_longest_reduce(ziplongestobject *lz, PyObject *Py_UNUSED(ignored))
{
-
+ ITERTOOL_PICKLE_DEPRECATION;
/* Create a new tuple with empty sequences where appropriate to pickle.
* Then use setstate to set the fillvalue
*/
@@ -4744,6 +4555,7 @@ zip_longest_reduce(ziplongestobject *lz, PyObject *Py_UNUSED(ignored))
static PyObject *
zip_longest_setstate(ziplongestobject *lz, PyObject *state)
{
+ ITERTOOL_PICKLE_DEPRECATION;
Py_INCREF(state);
Py_XSETREF(lz->fillvalue, state);
Py_RETURN_NONE;
@@ -4768,48 +4580,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\
");
-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_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 */
- 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 */
+static PyType_Slot ziplongest_slots[] = {
+ {Py_tp_dealloc, zip_longest_dealloc},
+ {Py_tp_getattro, PyObject_GenericGetAttr},
+ {Py_tp_doc, (void *)zip_longest_doc},
+ {Py_tp_traverse, zip_longest_traverse},
+ {Py_tp_iter, PyObject_SelfIter},
+ {Py_tp_iternext, zip_longest_next},
+ {Py_tp_methods, zip_longest_methods},
+ {Py_tp_new, zip_longest_new},
+ {Py_tp_free, PyObject_GC_Del},
+ {0, NULL},
+};
+
+static PyType_Spec ziplongest_spec = {
+ .name = "itertools.zip_longest",
+ .basicsize = sizeof(ziplongestobject),
+ .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE |
+ Py_TPFLAGS_IMMUTABLETYPE),
+ .slots = ziplongest_slots,
};
@@ -4825,6 +4614,7 @@ repeat(elem [,n]) --> elem, elem, elem, ... endlessly or up to n times\n\
\n\
Iterators terminating on the shortest input sequence:\n\
accumulate(p[, func]) --> p0, p0+p1, p0+p1+p2\n\
+batched(p, n) --> [p0, p1, ..., p_n-1], [p_n, p_n+1, ..., p_2n-1], ...\n\
chain(p, q, ...) --> p0, p1, ... plast, q0, q1, ...\n\
chain.from_iterable([p, q, ...]) --> p0, p1, ... plast, q0, q1, ...\n\
compress(data, selectors) --> (d[0] if s[0]), (d[1] if s[1]), ...\n\
@@ -4847,45 +4637,114 @@ combinations_with_replacement(p, r)\n\
");
static int
-itertoolsmodule_exec(PyObject *m)
-{
- 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,
- &pairwise_type,
- &permutations_type,
- &product_type,
- &repeat_type,
- &groupby_type,
- &_grouper_type,
- &tee_type,
- &teedataobject_type
- };
-
- Py_SET_TYPE(&teedataobject_type, &PyType_Type);
-
- for (size_t i = 0; i < Py_ARRAY_LENGTH(typelist); i++) {
- if (PyModule_AddType(m, typelist[i]) < 0) {
- return -1;
- }
- }
+itertoolsmodule_traverse(PyObject *mod, visitproc visit, void *arg)
+{
+ itertools_state *state = get_module_state(mod);
+ Py_VISIT(state->accumulate_type);
+ Py_VISIT(state->batched_type);
+ Py_VISIT(state->chain_type);
+ Py_VISIT(state->combinations_type);
+ Py_VISIT(state->compress_type);
+ Py_VISIT(state->count_type);
+ Py_VISIT(state->cwr_type);
+ Py_VISIT(state->cycle_type);
+ Py_VISIT(state->dropwhile_type);
+ Py_VISIT(state->filterfalse_type);
+ Py_VISIT(state->groupby_type);
+ Py_VISIT(state->_grouper_type);
+ Py_VISIT(state->islice_type);
+ Py_VISIT(state->pairwise_type);
+ Py_VISIT(state->permutations_type);
+ Py_VISIT(state->product_type);
+ Py_VISIT(state->repeat_type);
+ Py_VISIT(state->starmap_type);
+ Py_VISIT(state->takewhile_type);
+ Py_VISIT(state->tee_type);
+ Py_VISIT(state->teedataobject_type);
+ Py_VISIT(state->ziplongest_type);
+ return 0;
+}
+static int
+itertoolsmodule_clear(PyObject *mod)
+{
+ itertools_state *state = get_module_state(mod);
+ Py_CLEAR(state->accumulate_type);
+ Py_CLEAR(state->batched_type);
+ Py_CLEAR(state->chain_type);
+ Py_CLEAR(state->combinations_type);
+ Py_CLEAR(state->compress_type);
+ Py_CLEAR(state->count_type);
+ Py_CLEAR(state->cwr_type);
+ Py_CLEAR(state->cycle_type);
+ Py_CLEAR(state->dropwhile_type);
+ Py_CLEAR(state->filterfalse_type);
+ Py_CLEAR(state->groupby_type);
+ Py_CLEAR(state->_grouper_type);
+ Py_CLEAR(state->islice_type);
+ Py_CLEAR(state->pairwise_type);
+ Py_CLEAR(state->permutations_type);
+ Py_CLEAR(state->product_type);
+ Py_CLEAR(state->repeat_type);
+ Py_CLEAR(state->starmap_type);
+ Py_CLEAR(state->takewhile_type);
+ Py_CLEAR(state->tee_type);
+ Py_CLEAR(state->teedataobject_type);
+ Py_CLEAR(state->ziplongest_type);
+ return 0;
+}
+
+static void
+itertoolsmodule_free(void *mod)
+{
+ (void)itertoolsmodule_clear((PyObject *)mod);
+}
+
+#define ADD_TYPE(module, type, spec) \
+do { \
+ type = (PyTypeObject *)PyType_FromModuleAndSpec(module, spec, NULL); \
+ if (type == NULL) { \
+ return -1; \
+ } \
+ if (PyModule_AddType(module, type) < 0) { \
+ return -1; \
+ } \
+} while (0)
+
+static int
+itertoolsmodule_exec(PyObject *mod)
+{
+ itertools_state *state = get_module_state(mod);
+ ADD_TYPE(mod, state->accumulate_type, &accumulate_spec);
+ ADD_TYPE(mod, state->batched_type, &batched_spec);
+ ADD_TYPE(mod, state->chain_type, &chain_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->cycle_type, &cycle_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->_grouper_type, &_grouper_spec);
+ ADD_TYPE(mod, state->islice_type, &islice_spec);
+ ADD_TYPE(mod, state->pairwise_type, &pairwise_spec);
+ ADD_TYPE(mod, state->permutations_type, &permutations_spec);
+ ADD_TYPE(mod, state->product_type, &product_spec);
+ ADD_TYPE(mod, state->repeat_type, &repeat_spec);
+ ADD_TYPE(mod, state->starmap_type, &starmap_spec);
+ ADD_TYPE(mod, state->takewhile_type, &takewhile_spec);
+ ADD_TYPE(mod, state->tee_type, &tee_spec);
+ ADD_TYPE(mod, state->teedataobject_type, &teedataobject_spec);
+ ADD_TYPE(mod, state->ziplongest_type, &ziplongest_spec);
+
+ Py_SET_TYPE(state->teedataobject_type, &PyType_Type);
return 0;
}
static struct PyModuleDef_Slot itertoolsmodule_slots[] = {
{Py_mod_exec, itertoolsmodule_exec},
+ {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED},
{0, NULL}
};
@@ -4896,15 +4755,15 @@ static PyMethodDef module_methods[] = {
static struct PyModuleDef itertoolsmodule = {
- PyModuleDef_HEAD_INIT,
- "itertools",
- module_doc,
- 0,
- module_methods,
- itertoolsmodule_slots,
- NULL,
- NULL,
- NULL
+ .m_base = PyModuleDef_HEAD_INIT,
+ .m_name = "itertools",
+ .m_doc = module_doc,
+ .m_size = sizeof(itertools_state),
+ .m_methods = module_methods,
+ .m_slots = itertoolsmodule_slots,
+ .m_traverse = itertoolsmodule_traverse,
+ .m_clear = itertoolsmodule_clear,
+ .m_free = itertoolsmodule_free,
};
PyMODINIT_FUNC