Skip to content

Commit 343abef

Browse files
pythongh-101277: Add tee type to module state
1 parent 27ee72c commit 343abef

File tree

2 files changed

+48
-57
lines changed

2 files changed

+48
-57
lines changed

Modules/clinic/itertoolsmodule.c.h

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Modules/itertoolsmodule.c

Lines changed: 45 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include "pycore_long.h" // _PyLong_GetZero()
55
#include "pycore_object.h" // _PyObject_GC_TRACK()
66
#include "pycore_tuple.h" // _PyTuple_ITEMS()
7+
#include "structmember.h" // PyMemberDef
78
#include <stddef.h> // offsetof()
89

910
/* Itertools module written and maintained
@@ -29,6 +30,7 @@ typedef struct {
2930
PyTypeObject *repeat_type;
3031
PyTypeObject *starmap_type;
3132
PyTypeObject *takewhile_type;
33+
PyTypeObject *tee_type;
3234
PyTypeObject *ziplongest_type;
3335
} itertools_state;
3436

@@ -55,7 +57,7 @@ module itertools
5557
class itertools.groupby "groupbyobject *" "clinic_state()->groupby_type"
5658
class itertools._grouper "_grouperobject *" "clinic_state()->_grouper_type"
5759
class itertools.teedataobject "teedataobject *" "&teedataobject_type"
58-
class itertools._tee "teeobject *" "&tee_type"
60+
class itertools._tee "teeobject *" "clinic_state()->tee_type"
5961
class itertools.batched "batchedobject *" "&batched_type"
6062
class itertools.cycle "cycleobject *" "clinic_state()->cycle_type"
6163
class itertools.dropwhile "dropwhileobject *" "clinic_state()->dropwhile_type"
@@ -71,10 +73,9 @@ class itertools.filterfalse "filterfalseobject *" "clinic_state()->filterfalse_t
7173
class itertools.count "countobject *" "clinic_state()->count_type"
7274
class itertools.pairwise "pairwiseobject *" "clinic_state()->pairwise_type"
7375
[clinic start generated code]*/
74-
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=102319065d3e090b]*/
76+
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=2de6179a0523a80d]*/
7577

7678
static PyTypeObject teedataobject_type;
77-
static PyTypeObject tee_type;
7879
static PyTypeObject batched_type;
7980

8081
#include "clinic/itertoolsmodule.c.h"
@@ -971,18 +972,18 @@ tee_next(teeobject *to)
971972
static int
972973
tee_traverse(teeobject *to, visitproc visit, void *arg)
973974
{
975+
Py_VISIT(Py_TYPE(to));
974976
Py_VISIT((PyObject *)to->dataobj);
975977
return 0;
976978
}
977979

978980
static PyObject *
979981
tee_copy(teeobject *to, PyObject *Py_UNUSED(ignored))
980982
{
981-
teeobject *newto;
982-
983-
newto = PyObject_GC_New(teeobject, &tee_type);
984-
if (newto == NULL)
983+
teeobject *newto = PyObject_GC_New(teeobject, Py_TYPE(to));
984+
if (newto == NULL) {
985985
return NULL;
986+
}
986987
newto->dataobj = (teedataobject*)Py_NewRef(to->dataobj);
987988
newto->index = to->index;
988989
newto->weakreflist = NULL;
@@ -993,15 +994,15 @@ tee_copy(teeobject *to, PyObject *Py_UNUSED(ignored))
993994
PyDoc_STRVAR(teecopy_doc, "Returns an independent iterator.");
994995

995996
static PyObject *
996-
tee_fromiterable(PyObject *iterable)
997+
tee_fromiterable(itertools_state *state, PyObject *iterable)
997998
{
998999
teeobject *to;
9991000
PyObject *it;
10001001

10011002
it = PyObject_GetIter(iterable);
10021003
if (it == NULL)
10031004
return NULL;
1004-
if (PyObject_TypeCheck(it, &tee_type)) {
1005+
if (PyObject_TypeCheck(it, state->tee_type)) {
10051006
to = (teeobject *)tee_copy((teeobject *)it, NULL);
10061007
goto done;
10071008
}
@@ -1011,7 +1012,7 @@ tee_fromiterable(PyObject *iterable)
10111012
to = NULL;
10121013
goto done;
10131014
}
1014-
to = PyObject_GC_New(teeobject, &tee_type);
1015+
to = PyObject_GC_New(teeobject, state->tee_type);
10151016
if (to == NULL) {
10161017
Py_DECREF(dataobj);
10171018
goto done;
@@ -1037,7 +1038,8 @@ static PyObject *
10371038
itertools__tee_impl(PyTypeObject *type, PyObject *iterable)
10381039
/*[clinic end generated code: output=b02d3fd26c810c3f input=adc0779d2afe37a2]*/
10391040
{
1040-
return tee_fromiterable(iterable);
1041+
itertools_state *state = find_state_by_type(type);
1042+
return tee_fromiterable(state, iterable);
10411043
}
10421044

10431045
static int
@@ -1052,9 +1054,11 @@ tee_clear(teeobject *to)
10521054
static void
10531055
tee_dealloc(teeobject *to)
10541056
{
1057+
PyTypeObject *tp = Py_TYPE(to);
10551058
PyObject_GC_UnTrack(to);
10561059
tee_clear(to);
10571060
PyObject_GC_Del(to);
1061+
Py_DECREF(tp);
10581062
}
10591063

10601064
static PyObject *
@@ -1092,47 +1096,31 @@ static PyMethodDef tee_methods[] = {
10921096
{NULL, NULL} /* sentinel */
10931097
};
10941098

1095-
static PyTypeObject tee_type = {
1096-
PyVarObject_HEAD_INIT(NULL, 0)
1097-
"itertools._tee", /* tp_name */
1098-
sizeof(teeobject), /* tp_basicsize */
1099-
0, /* tp_itemsize */
1100-
/* methods */
1101-
(destructor)tee_dealloc, /* tp_dealloc */
1102-
0, /* tp_vectorcall_offset */
1103-
0, /* tp_getattr */
1104-
0, /* tp_setattr */
1105-
0, /* tp_as_async */
1106-
0, /* tp_repr */
1107-
0, /* tp_as_number */
1108-
0, /* tp_as_sequence */
1109-
0, /* tp_as_mapping */
1110-
0, /* tp_hash */
1111-
0, /* tp_call */
1112-
0, /* tp_str */
1113-
0, /* tp_getattro */
1114-
0, /* tp_setattro */
1115-
0, /* tp_as_buffer */
1116-
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
1117-
itertools__tee__doc__, /* tp_doc */
1118-
(traverseproc)tee_traverse, /* tp_traverse */
1119-
(inquiry)tee_clear, /* tp_clear */
1120-
0, /* tp_richcompare */
1121-
offsetof(teeobject, weakreflist), /* tp_weaklistoffset */
1122-
PyObject_SelfIter, /* tp_iter */
1123-
(iternextfunc)tee_next, /* tp_iternext */
1124-
tee_methods, /* tp_methods */
1125-
0, /* tp_members */
1126-
0, /* tp_getset */
1127-
0, /* tp_base */
1128-
0, /* tp_dict */
1129-
0, /* tp_descr_get */
1130-
0, /* tp_descr_set */
1131-
0, /* tp_dictoffset */
1132-
0, /* tp_init */
1133-
0, /* tp_alloc */
1134-
itertools__tee, /* tp_new */
1135-
PyObject_GC_Del, /* tp_free */
1099+
static PyMemberDef tee_members[] = {
1100+
{"__weaklistoffset__", T_PYSSIZET, offsetof(teeobject, weakreflist), READONLY},
1101+
{NULL},
1102+
};
1103+
1104+
static PyType_Slot tee_slots[] = {
1105+
{Py_tp_dealloc, tee_dealloc},
1106+
{Py_tp_doc, (void *)itertools__tee__doc__},
1107+
{Py_tp_traverse, tee_traverse},
1108+
{Py_tp_clear, tee_clear},
1109+
{Py_tp_iter, PyObject_SelfIter},
1110+
{Py_tp_iternext, tee_next},
1111+
{Py_tp_methods, tee_methods},
1112+
{Py_tp_members, tee_members},
1113+
{Py_tp_new, itertools__tee},
1114+
{Py_tp_free, PyObject_GC_Del},
1115+
{0, NULL},
1116+
};
1117+
1118+
static PyType_Spec tee_spec = {
1119+
.name = "itertools._tee",
1120+
.basicsize = sizeof(teeobject),
1121+
.flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
1122+
Py_TPFLAGS_IMMUTABLETYPE),
1123+
.slots = tee_slots,
11361124
};
11371125

11381126
/*[clinic input]
@@ -1174,7 +1162,8 @@ itertools_tee_impl(PyObject *module, PyObject *iterable, Py_ssize_t n)
11741162
copyable = it;
11751163
}
11761164
else {
1177-
copyable = tee_fromiterable(it);
1165+
itertools_state *state = get_module_state(module);
1166+
copyable = tee_fromiterable(state, it);
11781167
Py_DECREF(it);
11791168
if (copyable == NULL) {
11801169
Py_DECREF(result);
@@ -4636,6 +4625,7 @@ itertoolsmodule_traverse(PyObject *mod, visitproc visit, void *arg)
46364625
Py_VISIT(state->repeat_type);
46374626
Py_VISIT(state->starmap_type);
46384627
Py_VISIT(state->takewhile_type);
4628+
Py_VISIT(state->tee_type);
46394629
Py_VISIT(state->ziplongest_type);
46404630
return 0;
46414631
}
@@ -4661,6 +4651,7 @@ itertoolsmodule_clear(PyObject *mod)
46614651
Py_CLEAR(state->repeat_type);
46624652
Py_CLEAR(state->starmap_type);
46634653
Py_CLEAR(state->takewhile_type);
4654+
Py_CLEAR(state->tee_type);
46644655
Py_CLEAR(state->ziplongest_type);
46654656
return 0;
46664657
}
@@ -4704,11 +4695,11 @@ itertoolsmodule_exec(PyObject *mod)
47044695
ADD_TYPE(mod, state->repeat_type, &repeat_spec);
47054696
ADD_TYPE(mod, state->starmap_type, &starmap_spec);
47064697
ADD_TYPE(mod, state->takewhile_type, &takewhile_spec);
4698+
ADD_TYPE(mod, state->tee_type, &tee_spec);
47074699
ADD_TYPE(mod, state->ziplongest_type, &ziplongest_spec);
47084700

47094701
PyTypeObject *typelist[] = {
47104702
&batched_type,
4711-
&tee_type,
47124703
&teedataobject_type
47134704
};
47144705

0 commit comments

Comments
 (0)