@@ -32,6 +32,7 @@ typedef struct {
32
32
PyTypeObject * starmap_type ;
33
33
PyTypeObject * takewhile_type ;
34
34
PyTypeObject * tee_type ;
35
+ PyTypeObject * teedataobject_type ;
35
36
PyTypeObject * ziplongest_type ;
36
37
} itertools_state ;
37
38
@@ -66,7 +67,7 @@ find_state_by_type(PyTypeObject *tp)
66
67
module itertools
67
68
class itertools.groupby "groupbyobject *" "clinic_state()->groupby_type"
68
69
class itertools._grouper "_grouperobject *" "clinic_state()->_grouper_type"
69
- class itertools.teedataobject "teedataobject *" "& teedataobject_type"
70
+ class itertools.teedataobject "teedataobject *" "clinic_state()-> teedataobject_type"
70
71
class itertools._tee "teeobject *" "clinic_state()->tee_type"
71
72
class itertools.batched "batchedobject *" "&batched_type"
72
73
class itertools.cycle "cycleobject *" "clinic_state()->cycle_type"
@@ -83,9 +84,8 @@ class itertools.filterfalse "filterfalseobject *" "clinic_state()->filterfalse_t
83
84
class itertools.count "countobject *" "clinic_state()->count_type"
84
85
class itertools.pairwise "pairwiseobject *" "clinic_state()->pairwise_type"
85
86
[clinic start generated code]*/
86
- /*[clinic end generated code: output=da39a3ee5e6b4b0d input=2de6179a0523a80d ]*/
87
+ /*[clinic end generated code: output=da39a3ee5e6b4b0d input=419423f2d82cf388 ]*/
87
88
88
- static PyTypeObject teedataobject_type ;
89
89
static PyTypeObject batched_type ;
90
90
91
91
#define clinic_state_by_cls () (get_module_state_by_cls(base_tp))
@@ -744,13 +744,13 @@ typedef struct {
744
744
} teeobject ;
745
745
746
746
static PyObject *
747
- teedataobject_newinternal (PyObject * it )
747
+ teedataobject_newinternal (itertools_state * state , PyObject * it )
748
748
{
749
- teedataobject * tdo ;
750
-
751
- tdo = PyObject_GC_New (teedataobject , & teedataobject_type );
752
- if (tdo == NULL )
749
+ teedataobject * tdo = PyObject_GC_New (teedataobject ,
750
+ state -> teedataobject_type );
751
+ if (tdo == NULL ) {
753
752
return NULL ;
753
+ }
754
754
755
755
tdo -> running = 0 ;
756
756
tdo -> numread = 0 ;
@@ -763,8 +763,11 @@ teedataobject_newinternal(PyObject *it)
763
763
static PyObject *
764
764
teedataobject_jumplink (teedataobject * tdo )
765
765
{
766
- if (tdo -> nextlink == NULL )
767
- tdo -> nextlink = teedataobject_newinternal (tdo -> it );
766
+ if (tdo -> nextlink == NULL ) {
767
+ PyTypeObject * tp = Py_TYPE (tdo );
768
+ itertools_state * state = find_state_by_type (tp );
769
+ tdo -> nextlink = teedataobject_newinternal (state , tdo -> it );
770
+ }
768
771
return Py_XNewRef (tdo -> nextlink );
769
772
}
770
773
@@ -800,6 +803,7 @@ teedataobject_traverse(teedataobject *tdo, visitproc visit, void * arg)
800
803
{
801
804
int i ;
802
805
806
+ Py_VISIT (Py_TYPE (tdo ));
803
807
Py_VISIT (tdo -> it );
804
808
for (i = 0 ; i < tdo -> numread ; i ++ )
805
809
Py_VISIT (tdo -> values [i ]);
@@ -808,9 +812,9 @@ teedataobject_traverse(teedataobject *tdo, visitproc visit, void * arg)
808
812
}
809
813
810
814
static void
811
- teedataobject_safe_decref (PyObject * obj )
815
+ teedataobject_safe_decref (PyObject * obj , PyTypeObject * tdo_type )
812
816
{
813
- while (obj && Py_IS_TYPE (obj , & teedataobject_type ) &&
817
+ while (obj && Py_IS_TYPE (obj , tdo_type ) &&
814
818
Py_REFCNT (obj ) == 1 ) {
815
819
PyObject * nextlink = ((teedataobject * )obj )-> nextlink ;
816
820
((teedataobject * )obj )-> nextlink = NULL ;
@@ -830,16 +834,19 @@ teedataobject_clear(teedataobject *tdo)
830
834
Py_CLEAR (tdo -> values [i ]);
831
835
tmp = tdo -> nextlink ;
832
836
tdo -> nextlink = NULL ;
833
- teedataobject_safe_decref (tmp );
837
+ itertools_state * state = find_state_by_type (Py_TYPE (tdo ));
838
+ teedataobject_safe_decref (tmp , state -> teedataobject_type );
834
839
return 0 ;
835
840
}
836
841
837
842
static void
838
843
teedataobject_dealloc (teedataobject * tdo )
839
844
{
845
+ PyTypeObject * tp = Py_TYPE (tdo );
840
846
PyObject_GC_UnTrack (tdo );
841
847
teedataobject_clear (tdo );
842
848
PyObject_GC_Del (tdo );
849
+ Py_DECREF (tp );
843
850
}
844
851
845
852
static PyObject *
@@ -878,9 +885,10 @@ itertools_teedataobject_impl(PyTypeObject *type, PyObject *it,
878
885
teedataobject * tdo ;
879
886
Py_ssize_t i , len ;
880
887
881
- assert (type == & teedataobject_type );
888
+ itertools_state * state = find_state_by_type (type );
889
+ assert (type == state -> teedataobject_type );
882
890
883
- tdo = (teedataobject * )teedataobject_newinternal (it );
891
+ tdo = (teedataobject * )teedataobject_newinternal (state , it );
884
892
if (!tdo )
885
893
return NULL ;
886
894
@@ -896,7 +904,7 @@ itertools_teedataobject_impl(PyTypeObject *type, PyObject *it,
896
904
897
905
if (len == LINKCELLS ) {
898
906
if (next != Py_None ) {
899
- if (!Py_IS_TYPE (next , & teedataobject_type ))
907
+ if (!Py_IS_TYPE (next , state -> teedataobject_type ))
900
908
goto err ;
901
909
assert (tdo -> nextlink == NULL );
902
910
tdo -> nextlink = Py_NewRef (next );
@@ -919,47 +927,24 @@ static PyMethodDef teedataobject_methods[] = {
919
927
{NULL , NULL } /* sentinel */
920
928
};
921
929
922
- static PyTypeObject teedataobject_type = {
923
- PyVarObject_HEAD_INIT (0 , 0 ) /* Must fill in type value later */
924
- "itertools._tee_dataobject" , /* tp_name */
925
- sizeof (teedataobject ), /* tp_basicsize */
926
- 0 , /* tp_itemsize */
927
- /* methods */
928
- (destructor )teedataobject_dealloc , /* tp_dealloc */
929
- 0 , /* tp_vectorcall_offset */
930
- 0 , /* tp_getattr */
931
- 0 , /* tp_setattr */
932
- 0 , /* tp_as_async */
933
- 0 , /* tp_repr */
934
- 0 , /* tp_as_number */
935
- 0 , /* tp_as_sequence */
936
- 0 , /* tp_as_mapping */
937
- 0 , /* tp_hash */
938
- 0 , /* tp_call */
939
- 0 , /* tp_str */
940
- PyObject_GenericGetAttr , /* tp_getattro */
941
- 0 , /* tp_setattro */
942
- 0 , /* tp_as_buffer */
943
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC , /* tp_flags */
944
- itertools_teedataobject__doc__ , /* tp_doc */
945
- (traverseproc )teedataobject_traverse , /* tp_traverse */
946
- (inquiry )teedataobject_clear , /* tp_clear */
947
- 0 , /* tp_richcompare */
948
- 0 , /* tp_weaklistoffset */
949
- 0 , /* tp_iter */
950
- 0 , /* tp_iternext */
951
- teedataobject_methods , /* tp_methods */
952
- 0 , /* tp_members */
953
- 0 , /* tp_getset */
954
- 0 , /* tp_base */
955
- 0 , /* tp_dict */
956
- 0 , /* tp_descr_get */
957
- 0 , /* tp_descr_set */
958
- 0 , /* tp_dictoffset */
959
- 0 , /* tp_init */
960
- 0 , /* tp_alloc */
961
- itertools_teedataobject , /* tp_new */
962
- PyObject_GC_Del , /* tp_free */
930
+ static PyType_Slot teedataobject_slots [] = {
931
+ {Py_tp_dealloc , teedataobject_dealloc },
932
+ {Py_tp_getattro , PyObject_GenericGetAttr },
933
+ {Py_tp_doc , (void * )itertools_teedataobject__doc__ },
934
+ {Py_tp_traverse , teedataobject_traverse },
935
+ {Py_tp_clear , teedataobject_clear },
936
+ {Py_tp_methods , teedataobject_methods },
937
+ {Py_tp_new , itertools_teedataobject },
938
+ {Py_tp_free , PyObject_GC_Del },
939
+ {0 , NULL },
940
+ };
941
+
942
+ static PyType_Spec teedataobject_spec = {
943
+ .name = "itertools._tee_dataobject" ,
944
+ .basicsize = sizeof (teedataobject ),
945
+ .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
946
+ Py_TPFLAGS_IMMUTABLETYPE ),
947
+ .slots = teedataobject_slots ,
963
948
};
964
949
965
950
@@ -1020,7 +1005,7 @@ tee_fromiterable(itertools_state *state, PyObject *iterable)
1020
1005
goto done ;
1021
1006
}
1022
1007
1023
- PyObject * dataobj = teedataobject_newinternal (it );
1008
+ PyObject * dataobj = teedataobject_newinternal (state , it );
1024
1009
if (!dataobj ) {
1025
1010
to = NULL ;
1026
1011
goto done ;
@@ -1089,7 +1074,9 @@ tee_setstate(teeobject *to, PyObject *state)
1089
1074
PyErr_SetString (PyExc_TypeError , "state is not a tuple" );
1090
1075
return NULL ;
1091
1076
}
1092
- if (!PyArg_ParseTuple (state , "O!i" , & teedataobject_type , & tdo , & index )) {
1077
+ itertools_state * m_state = find_state_by_type (Py_TYPE (to ));
1078
+ PyTypeObject * tdo_type = m_state -> teedataobject_type ;
1079
+ if (!PyArg_ParseTuple (state , "O!i" , tdo_type , & tdo , & index )) {
1093
1080
return NULL ;
1094
1081
}
1095
1082
if (index < 0 || index > LINKCELLS ) {
@@ -4712,14 +4699,14 @@ itertoolsmodule_exec(PyObject *mod)
4712
4699
ADD_TYPE (mod , state -> starmap_type , & starmap_spec );
4713
4700
ADD_TYPE (mod , state -> takewhile_type , & takewhile_spec );
4714
4701
ADD_TYPE (mod , state -> tee_type , & tee_spec );
4702
+ ADD_TYPE (mod , state -> teedataobject_type , & teedataobject_spec );
4715
4703
ADD_TYPE (mod , state -> ziplongest_type , & ziplongest_spec );
4716
4704
4717
4705
PyTypeObject * typelist [] = {
4718
4706
& batched_type ,
4719
- & teedataobject_type
4720
4707
};
4721
4708
4722
- Py_SET_TYPE (& teedataobject_type , & PyType_Type );
4709
+ Py_SET_TYPE (state -> teedataobject_type , & PyType_Type );
4723
4710
4724
4711
for (size_t i = 0 ; i < Py_ARRAY_LENGTH (typelist ); i ++ ) {
4725
4712
if (PyModule_AddType (mod , typelist [i ]) < 0 ) {
0 commit comments