4
4
#include "pycore_long.h" // _PyLong_GetZero()
5
5
#include "pycore_object.h" // _PyObject_GC_TRACK()
6
6
#include "pycore_tuple.h" // _PyTuple_ITEMS()
7
+ #include "structmember.h" // PyMemberDef
7
8
#include <stddef.h> // offsetof()
8
9
9
10
/* Itertools module written and maintained
@@ -29,6 +30,7 @@ typedef struct {
29
30
PyTypeObject * repeat_type ;
30
31
PyTypeObject * starmap_type ;
31
32
PyTypeObject * takewhile_type ;
33
+ PyTypeObject * tee_type ;
32
34
PyTypeObject * ziplongest_type ;
33
35
} itertools_state ;
34
36
@@ -55,7 +57,7 @@ module itertools
55
57
class itertools.groupby "groupbyobject *" "clinic_state()->groupby_type"
56
58
class itertools._grouper "_grouperobject *" "clinic_state()->_grouper_type"
57
59
class itertools.teedataobject "teedataobject *" "&teedataobject_type"
58
- class itertools._tee "teeobject *" "& tee_type"
60
+ class itertools._tee "teeobject *" "clinic_state()-> tee_type"
59
61
class itertools.batched "batchedobject *" "&batched_type"
60
62
class itertools.cycle "cycleobject *" "clinic_state()->cycle_type"
61
63
class itertools.dropwhile "dropwhileobject *" "clinic_state()->dropwhile_type"
@@ -71,10 +73,9 @@ class itertools.filterfalse "filterfalseobject *" "clinic_state()->filterfalse_t
71
73
class itertools.count "countobject *" "clinic_state()->count_type"
72
74
class itertools.pairwise "pairwiseobject *" "clinic_state()->pairwise_type"
73
75
[clinic start generated code]*/
74
- /*[clinic end generated code: output=da39a3ee5e6b4b0d input=102319065d3e090b ]*/
76
+ /*[clinic end generated code: output=da39a3ee5e6b4b0d input=2de6179a0523a80d ]*/
75
77
76
78
static PyTypeObject teedataobject_type ;
77
- static PyTypeObject tee_type ;
78
79
static PyTypeObject batched_type ;
79
80
80
81
#include "clinic/itertoolsmodule.c.h"
@@ -971,18 +972,18 @@ tee_next(teeobject *to)
971
972
static int
972
973
tee_traverse (teeobject * to , visitproc visit , void * arg )
973
974
{
975
+ Py_VISIT (Py_TYPE (to ));
974
976
Py_VISIT ((PyObject * )to -> dataobj );
975
977
return 0 ;
976
978
}
977
979
978
980
static PyObject *
979
981
tee_copy (teeobject * to , PyObject * Py_UNUSED (ignored ))
980
982
{
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 ) {
985
985
return NULL ;
986
+ }
986
987
newto -> dataobj = (teedataobject * )Py_NewRef (to -> dataobj );
987
988
newto -> index = to -> index ;
988
989
newto -> weakreflist = NULL ;
@@ -993,15 +994,15 @@ tee_copy(teeobject *to, PyObject *Py_UNUSED(ignored))
993
994
PyDoc_STRVAR (teecopy_doc , "Returns an independent iterator." );
994
995
995
996
static PyObject *
996
- tee_fromiterable (PyObject * iterable )
997
+ tee_fromiterable (itertools_state * state , PyObject * iterable )
997
998
{
998
999
teeobject * to ;
999
1000
PyObject * it ;
1000
1001
1001
1002
it = PyObject_GetIter (iterable );
1002
1003
if (it == NULL )
1003
1004
return NULL ;
1004
- if (PyObject_TypeCheck (it , & tee_type )) {
1005
+ if (PyObject_TypeCheck (it , state -> tee_type )) {
1005
1006
to = (teeobject * )tee_copy ((teeobject * )it , NULL );
1006
1007
goto done ;
1007
1008
}
@@ -1011,7 +1012,7 @@ tee_fromiterable(PyObject *iterable)
1011
1012
to = NULL ;
1012
1013
goto done ;
1013
1014
}
1014
- to = PyObject_GC_New (teeobject , & tee_type );
1015
+ to = PyObject_GC_New (teeobject , state -> tee_type );
1015
1016
if (to == NULL ) {
1016
1017
Py_DECREF (dataobj );
1017
1018
goto done ;
@@ -1037,7 +1038,8 @@ static PyObject *
1037
1038
itertools__tee_impl (PyTypeObject * type , PyObject * iterable )
1038
1039
/*[clinic end generated code: output=b02d3fd26c810c3f input=adc0779d2afe37a2]*/
1039
1040
{
1040
- return tee_fromiterable (iterable );
1041
+ itertools_state * state = find_state_by_type (type );
1042
+ return tee_fromiterable (state , iterable );
1041
1043
}
1042
1044
1043
1045
static int
@@ -1052,9 +1054,11 @@ tee_clear(teeobject *to)
1052
1054
static void
1053
1055
tee_dealloc (teeobject * to )
1054
1056
{
1057
+ PyTypeObject * tp = Py_TYPE (to );
1055
1058
PyObject_GC_UnTrack (to );
1056
1059
tee_clear (to );
1057
1060
PyObject_GC_Del (to );
1061
+ Py_DECREF (tp );
1058
1062
}
1059
1063
1060
1064
static PyObject *
@@ -1092,47 +1096,31 @@ static PyMethodDef tee_methods[] = {
1092
1096
{NULL , NULL } /* sentinel */
1093
1097
};
1094
1098
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 ,
1136
1124
};
1137
1125
1138
1126
/*[clinic input]
@@ -1174,7 +1162,8 @@ itertools_tee_impl(PyObject *module, PyObject *iterable, Py_ssize_t n)
1174
1162
copyable = it ;
1175
1163
}
1176
1164
else {
1177
- copyable = tee_fromiterable (it );
1165
+ itertools_state * state = get_module_state (module );
1166
+ copyable = tee_fromiterable (state , it );
1178
1167
Py_DECREF (it );
1179
1168
if (copyable == NULL ) {
1180
1169
Py_DECREF (result );
@@ -4636,6 +4625,7 @@ itertoolsmodule_traverse(PyObject *mod, visitproc visit, void *arg)
4636
4625
Py_VISIT (state -> repeat_type );
4637
4626
Py_VISIT (state -> starmap_type );
4638
4627
Py_VISIT (state -> takewhile_type );
4628
+ Py_VISIT (state -> tee_type );
4639
4629
Py_VISIT (state -> ziplongest_type );
4640
4630
return 0 ;
4641
4631
}
@@ -4661,6 +4651,7 @@ itertoolsmodule_clear(PyObject *mod)
4661
4651
Py_CLEAR (state -> repeat_type );
4662
4652
Py_CLEAR (state -> starmap_type );
4663
4653
Py_CLEAR (state -> takewhile_type );
4654
+ Py_CLEAR (state -> tee_type );
4664
4655
Py_CLEAR (state -> ziplongest_type );
4665
4656
return 0 ;
4666
4657
}
@@ -4704,11 +4695,11 @@ itertoolsmodule_exec(PyObject *mod)
4704
4695
ADD_TYPE (mod , state -> repeat_type , & repeat_spec );
4705
4696
ADD_TYPE (mod , state -> starmap_type , & starmap_spec );
4706
4697
ADD_TYPE (mod , state -> takewhile_type , & takewhile_spec );
4698
+ ADD_TYPE (mod , state -> tee_type , & tee_spec );
4707
4699
ADD_TYPE (mod , state -> ziplongest_type , & ziplongest_spec );
4708
4700
4709
4701
PyTypeObject * typelist [] = {
4710
4702
& batched_type ,
4711
- & tee_type ,
4712
4703
& teedataobject_type
4713
4704
};
4714
4705
0 commit comments