5
5
#include "pycore_moduleobject.h" // _PyModule_GetState()
6
6
#include "pycore_object.h" // _PyObject_GC_TRACK()
7
7
#include "pycore_tuple.h" // _PyTuple_ITEMS()
8
+ #include "structmember.h" // PyMemberDef
8
9
#include <stddef.h> // offsetof()
9
10
10
11
/* Itertools module written and maintained
@@ -30,6 +31,7 @@ typedef struct {
30
31
PyTypeObject * repeat_type ;
31
32
PyTypeObject * starmap_type ;
32
33
PyTypeObject * takewhile_type ;
34
+ PyTypeObject * tee_type ;
33
35
PyTypeObject * ziplongest_type ;
34
36
} itertools_state ;
35
37
@@ -64,7 +66,7 @@ module itertools
64
66
class itertools.groupby "groupbyobject *" "clinic_state()->groupby_type"
65
67
class itertools._grouper "_grouperobject *" "clinic_state()->_grouper_type"
66
68
class itertools.teedataobject "teedataobject *" "&teedataobject_type"
67
- class itertools._tee "teeobject *" "& tee_type"
69
+ class itertools._tee "teeobject *" "clinic_state()-> tee_type"
68
70
class itertools.batched "batchedobject *" "&batched_type"
69
71
class itertools.cycle "cycleobject *" "clinic_state()->cycle_type"
70
72
class itertools.dropwhile "dropwhileobject *" "clinic_state()->dropwhile_type"
@@ -80,10 +82,9 @@ class itertools.filterfalse "filterfalseobject *" "clinic_state()->filterfalse_t
80
82
class itertools.count "countobject *" "clinic_state()->count_type"
81
83
class itertools.pairwise "pairwiseobject *" "clinic_state()->pairwise_type"
82
84
[clinic start generated code]*/
83
- /*[clinic end generated code: output=da39a3ee5e6b4b0d input=102319065d3e090b ]*/
85
+ /*[clinic end generated code: output=da39a3ee5e6b4b0d input=2de6179a0523a80d ]*/
84
86
85
87
static PyTypeObject teedataobject_type ;
86
- static PyTypeObject tee_type ;
87
88
static PyTypeObject batched_type ;
88
89
89
90
#define clinic_state () (find_state_by_type(type))
@@ -984,18 +985,18 @@ tee_next(teeobject *to)
984
985
static int
985
986
tee_traverse (teeobject * to , visitproc visit , void * arg )
986
987
{
988
+ Py_VISIT (Py_TYPE (to ));
987
989
Py_VISIT ((PyObject * )to -> dataobj );
988
990
return 0 ;
989
991
}
990
992
991
993
static PyObject *
992
994
tee_copy (teeobject * to , PyObject * Py_UNUSED (ignored ))
993
995
{
994
- teeobject * newto ;
995
-
996
- newto = PyObject_GC_New (teeobject , & tee_type );
997
- if (newto == NULL )
996
+ teeobject * newto = PyObject_GC_New (teeobject , Py_TYPE (to ));
997
+ if (newto == NULL ) {
998
998
return NULL ;
999
+ }
999
1000
newto -> dataobj = (teedataobject * )Py_NewRef (to -> dataobj );
1000
1001
newto -> index = to -> index ;
1001
1002
newto -> weakreflist = NULL ;
@@ -1006,15 +1007,15 @@ tee_copy(teeobject *to, PyObject *Py_UNUSED(ignored))
1006
1007
PyDoc_STRVAR (teecopy_doc , "Returns an independent iterator." );
1007
1008
1008
1009
static PyObject *
1009
- tee_fromiterable (PyObject * iterable )
1010
+ tee_fromiterable (itertools_state * state , PyObject * iterable )
1010
1011
{
1011
1012
teeobject * to ;
1012
1013
PyObject * it ;
1013
1014
1014
1015
it = PyObject_GetIter (iterable );
1015
1016
if (it == NULL )
1016
1017
return NULL ;
1017
- if (PyObject_TypeCheck (it , & tee_type )) {
1018
+ if (PyObject_TypeCheck (it , state -> tee_type )) {
1018
1019
to = (teeobject * )tee_copy ((teeobject * )it , NULL );
1019
1020
goto done ;
1020
1021
}
@@ -1024,7 +1025,7 @@ tee_fromiterable(PyObject *iterable)
1024
1025
to = NULL ;
1025
1026
goto done ;
1026
1027
}
1027
- to = PyObject_GC_New (teeobject , & tee_type );
1028
+ to = PyObject_GC_New (teeobject , state -> tee_type );
1028
1029
if (to == NULL ) {
1029
1030
Py_DECREF (dataobj );
1030
1031
goto done ;
@@ -1050,7 +1051,8 @@ static PyObject *
1050
1051
itertools__tee_impl (PyTypeObject * type , PyObject * iterable )
1051
1052
/*[clinic end generated code: output=b02d3fd26c810c3f input=adc0779d2afe37a2]*/
1052
1053
{
1053
- return tee_fromiterable (iterable );
1054
+ itertools_state * state = find_state_by_type (type );
1055
+ return tee_fromiterable (state , iterable );
1054
1056
}
1055
1057
1056
1058
static int
@@ -1065,9 +1067,11 @@ tee_clear(teeobject *to)
1065
1067
static void
1066
1068
tee_dealloc (teeobject * to )
1067
1069
{
1070
+ PyTypeObject * tp = Py_TYPE (to );
1068
1071
PyObject_GC_UnTrack (to );
1069
1072
tee_clear (to );
1070
1073
PyObject_GC_Del (to );
1074
+ Py_DECREF (tp );
1071
1075
}
1072
1076
1073
1077
static PyObject *
@@ -1105,47 +1109,31 @@ static PyMethodDef tee_methods[] = {
1105
1109
{NULL , NULL } /* sentinel */
1106
1110
};
1107
1111
1108
- static PyTypeObject tee_type = {
1109
- PyVarObject_HEAD_INIT (NULL , 0 )
1110
- "itertools._tee" , /* tp_name */
1111
- sizeof (teeobject ), /* tp_basicsize */
1112
- 0 , /* tp_itemsize */
1113
- /* methods */
1114
- (destructor )tee_dealloc , /* tp_dealloc */
1115
- 0 , /* tp_vectorcall_offset */
1116
- 0 , /* tp_getattr */
1117
- 0 , /* tp_setattr */
1118
- 0 , /* tp_as_async */
1119
- 0 , /* tp_repr */
1120
- 0 , /* tp_as_number */
1121
- 0 , /* tp_as_sequence */
1122
- 0 , /* tp_as_mapping */
1123
- 0 , /* tp_hash */
1124
- 0 , /* tp_call */
1125
- 0 , /* tp_str */
1126
- 0 , /* tp_getattro */
1127
- 0 , /* tp_setattro */
1128
- 0 , /* tp_as_buffer */
1129
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC , /* tp_flags */
1130
- itertools__tee__doc__ , /* tp_doc */
1131
- (traverseproc )tee_traverse , /* tp_traverse */
1132
- (inquiry )tee_clear , /* tp_clear */
1133
- 0 , /* tp_richcompare */
1134
- offsetof(teeobject , weakreflist ), /* tp_weaklistoffset */
1135
- PyObject_SelfIter , /* tp_iter */
1136
- (iternextfunc )tee_next , /* tp_iternext */
1137
- tee_methods , /* tp_methods */
1138
- 0 , /* tp_members */
1139
- 0 , /* tp_getset */
1140
- 0 , /* tp_base */
1141
- 0 , /* tp_dict */
1142
- 0 , /* tp_descr_get */
1143
- 0 , /* tp_descr_set */
1144
- 0 , /* tp_dictoffset */
1145
- 0 , /* tp_init */
1146
- 0 , /* tp_alloc */
1147
- itertools__tee , /* tp_new */
1148
- PyObject_GC_Del , /* tp_free */
1112
+ static PyMemberDef tee_members [] = {
1113
+ {"__weaklistoffset__" , T_PYSSIZET , offsetof(teeobject , weakreflist ), READONLY },
1114
+ {NULL },
1115
+ };
1116
+
1117
+ static PyType_Slot tee_slots [] = {
1118
+ {Py_tp_dealloc , tee_dealloc },
1119
+ {Py_tp_doc , (void * )itertools__tee__doc__ },
1120
+ {Py_tp_traverse , tee_traverse },
1121
+ {Py_tp_clear , tee_clear },
1122
+ {Py_tp_iter , PyObject_SelfIter },
1123
+ {Py_tp_iternext , tee_next },
1124
+ {Py_tp_methods , tee_methods },
1125
+ {Py_tp_members , tee_members },
1126
+ {Py_tp_new , itertools__tee },
1127
+ {Py_tp_free , PyObject_GC_Del },
1128
+ {0 , NULL },
1129
+ };
1130
+
1131
+ static PyType_Spec tee_spec = {
1132
+ .name = "itertools._tee" ,
1133
+ .basicsize = sizeof (teeobject ),
1134
+ .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
1135
+ Py_TPFLAGS_IMMUTABLETYPE ),
1136
+ .slots = tee_slots ,
1149
1137
};
1150
1138
1151
1139
/*[clinic input]
@@ -1187,7 +1175,8 @@ itertools_tee_impl(PyObject *module, PyObject *iterable, Py_ssize_t n)
1187
1175
copyable = it ;
1188
1176
}
1189
1177
else {
1190
- copyable = tee_fromiterable (it );
1178
+ itertools_state * state = get_module_state (module );
1179
+ copyable = tee_fromiterable (state , it );
1191
1180
Py_DECREF (it );
1192
1181
if (copyable == NULL ) {
1193
1182
Py_DECREF (result );
@@ -4651,6 +4640,7 @@ itertoolsmodule_traverse(PyObject *mod, visitproc visit, void *arg)
4651
4640
Py_VISIT (state -> repeat_type );
4652
4641
Py_VISIT (state -> starmap_type );
4653
4642
Py_VISIT (state -> takewhile_type );
4643
+ Py_VISIT (state -> tee_type );
4654
4644
Py_VISIT (state -> ziplongest_type );
4655
4645
return 0 ;
4656
4646
}
@@ -4677,6 +4667,7 @@ itertoolsmodule_clear(PyObject *mod)
4677
4667
Py_CLEAR (state -> repeat_type );
4678
4668
Py_CLEAR (state -> starmap_type );
4679
4669
Py_CLEAR (state -> takewhile_type );
4670
+ Py_CLEAR (state -> tee_type );
4680
4671
Py_CLEAR (state -> ziplongest_type );
4681
4672
return 0 ;
4682
4673
}
@@ -4720,11 +4711,11 @@ itertoolsmodule_exec(PyObject *mod)
4720
4711
ADD_TYPE (mod , state -> repeat_type , & repeat_spec );
4721
4712
ADD_TYPE (mod , state -> starmap_type , & starmap_spec );
4722
4713
ADD_TYPE (mod , state -> takewhile_type , & takewhile_spec );
4714
+ ADD_TYPE (mod , state -> tee_type , & tee_spec );
4723
4715
ADD_TYPE (mod , state -> ziplongest_type , & ziplongest_spec );
4724
4716
4725
4717
PyTypeObject * typelist [] = {
4726
4718
& batched_type ,
4727
- & tee_type ,
4728
4719
& teedataobject_type
4729
4720
};
4730
4721
0 commit comments