99#include "pycore_range.h"
1010#include "pycore_tuple.h" // _PyTuple_ITEMS()
1111
12+ typedef struct {
13+ PyObject_HEAD
14+ PyObject * start ;
15+ PyObject * step ;
16+ PyObject * len ;
17+ } longrangeiterobject ;
18+
19+ /*[clinic input]
20+ class range_iterator "_PyRangeIterObject *" "&PyRangeIter_Type"
21+ class longrange_iterator "longrangeiterobject *" "&PyLongRangeIter_Type"
22+ [clinic start generated code]*/
23+ /*[clinic end generated code: output=da39a3ee5e6b4b0d input=c7d97a63d1cfa6b3]*/
24+
25+ #include "clinic/rangeobject.c.h"
26+
1227
1328/* Support objects whose length is > PY_SSIZE_T_MAX.
1429
@@ -830,30 +845,46 @@ PyTypeObject PyRange_Type = {
830845static PyObject *
831846rangeiter_next (PyObject * op )
832847{
848+ PyObject * ret = NULL ;
849+ Py_BEGIN_CRITICAL_SECTION (op );
833850 _PyRangeIterObject * r = (_PyRangeIterObject * )op ;
834851 if (r -> len > 0 ) {
835852 long result = r -> start ;
836853 r -> start = result + r -> step ;
837854 r -> len -- ;
838- return PyLong_FromLong (result );
855+ ret = PyLong_FromLong (result );
839856 }
840- return NULL ;
857+ Py_END_CRITICAL_SECTION ();
858+ return ret ;
841859}
842860
861+ /*[clinic input]
862+ @critical_section
863+ range_iterator.__length_hint__
864+ self as r: self(type="_PyRangeIterObject *")
865+
866+ Private method returning an estimate of len(list(it)).
867+ [clinic start generated code]*/
868+
843869static PyObject *
844- rangeiter_len (PyObject * op , PyObject * Py_UNUSED (ignored ))
870+ range_iterator___length_hint___impl (_PyRangeIterObject * r )
871+ /*[clinic end generated code: output=9ba6f22b1fc23dcc input=e3eb311e99d76e43]*/
845872{
846- _PyRangeIterObject * r = (_PyRangeIterObject * )op ;
847873 return PyLong_FromLong (r -> len );
848874}
849875
850- PyDoc_STRVAR (length_hint_doc ,
851- "Private method returning an estimate of len(list(it))." );
876+ /*[clinic input]
877+ @critical_section
878+ range_iterator.__reduce__
879+ self as r: self(type="_PyRangeIterObject *")
880+
881+ Return state information for pickling.
882+ [clinic start generated code]*/
852883
853884static PyObject *
854- rangeiter_reduce (PyObject * op , PyObject * Py_UNUSED (ignored ))
885+ range_iterator___reduce___impl (_PyRangeIterObject * r )
886+ /*[clinic end generated code: output=c44d53750c388415 input=75a25b7076dc2c54]*/
855887{
856- _PyRangeIterObject * r = (_PyRangeIterObject * )op ;
857888 PyObject * start = NULL , * stop = NULL , * step = NULL ;
858889 PyObject * range ;
859890
@@ -881,10 +912,20 @@ rangeiter_reduce(PyObject *op, PyObject *Py_UNUSED(ignored))
881912 return NULL ;
882913}
883914
915+ /*[clinic input]
916+ @critical_section
917+ range_iterator.__setstate__
918+ self as r: self(type="_PyRangeIterObject *")
919+ state: object
920+ /
921+
922+ Set state information for unpickling.
923+ [clinic start generated code]*/
924+
884925static PyObject *
885- rangeiter_setstate (PyObject * op , PyObject * state )
926+ range_iterator___setstate___impl (_PyRangeIterObject * r , PyObject * state )
927+ /*[clinic end generated code: output=464b3cbafc2e3562 input=c8c84fab2519d200]*/
886928{
887- _PyRangeIterObject * r = (_PyRangeIterObject * )op ;
888929 long index = PyLong_AsLong (state );
889930 if (index == -1 && PyErr_Occurred ())
890931 return NULL ;
@@ -904,13 +945,10 @@ rangeiter_dealloc(PyObject *self)
904945 _Py_FREELIST_FREE (range_iters , (_PyRangeIterObject * )self , PyObject_Free );
905946}
906947
907- PyDoc_STRVAR (reduce_doc , "Return state information for pickling." );
908- PyDoc_STRVAR (setstate_doc , "Set state information for unpickling." );
909-
910948static PyMethodDef rangeiter_methods [] = {
911- { "__length_hint__" , rangeiter_len , METH_NOARGS , length_hint_doc },
912- { "__reduce__" , rangeiter_reduce , METH_NOARGS , reduce_doc },
913- { "__setstate__" , rangeiter_setstate , METH_O , setstate_doc },
949+ RANGE_ITERATOR___LENGTH_HINT___METHODDEF
950+ RANGE_ITERATOR___REDUCE___METHODDEF
951+ RANGE_ITERATOR___SETSTATE___METHODDEF
914952 {NULL , NULL } /* sentinel */
915953};
916954
@@ -995,25 +1033,34 @@ fast_range_iter(long start, long stop, long step, long len)
9951033 return (PyObject * )it ;
9961034}
9971035
998- typedef struct {
999- PyObject_HEAD
1000- PyObject * start ;
1001- PyObject * step ;
1002- PyObject * len ;
1003- } longrangeiterobject ;
1036+ /*[clinic input]
1037+ @critical_section
1038+ longrange_iterator.__length_hint__
1039+ self as r: self(type="longrangeiterobject *")
1040+
1041+ Private method returning an estimate of len(list(it)).
1042+ [clinic start generated code]*/
10041043
10051044static PyObject *
1006- longrangeiter_len (PyObject * op , PyObject * Py_UNUSED (ignored ))
1045+ longrange_iterator___length_hint___impl (longrangeiterobject * r )
1046+ /*[clinic end generated code: output=e1bce24da7e8bfde input=ba94b050d940411e]*/
10071047{
1008- longrangeiterobject * r = (longrangeiterobject * )op ;
10091048 Py_INCREF (r -> len );
10101049 return r -> len ;
10111050}
10121051
1052+ /*[clinic input]
1053+ @critical_section
1054+ longrange_iterator.__reduce__
1055+ self as r: self(type="longrangeiterobject *")
1056+
1057+ Return state information for pickling.
1058+ [clinic start generated code]*/
1059+
10131060static PyObject *
1014- longrangeiter_reduce (PyObject * op , PyObject * Py_UNUSED (ignored ))
1061+ longrange_iterator___reduce___impl (longrangeiterobject * r )
1062+ /*[clinic end generated code: output=0077f94ae2a4e99a input=2e8930e897ace086]*/
10151063{
1016- longrangeiterobject * r = (longrangeiterobject * )op ;
10171064 PyObject * product , * stop = NULL ;
10181065 PyObject * range ;
10191066
@@ -1039,15 +1086,25 @@ longrangeiter_reduce(PyObject *op, PyObject *Py_UNUSED(ignored))
10391086 range , Py_None );
10401087}
10411088
1089+ /*[clinic input]
1090+ @critical_section
1091+ longrange_iterator.__setstate__
1092+ self as r: self(type="longrangeiterobject *")
1093+ state: object
1094+ /
1095+
1096+ Set state information for unpickling.
1097+ [clinic start generated code]*/
1098+
10421099static PyObject *
1043- longrangeiter_setstate (PyObject * op , PyObject * state )
1100+ longrange_iterator___setstate___impl (longrangeiterobject * r , PyObject * state )
1101+ /*[clinic end generated code: output=870787f0574f0da4 input=8b116de3018de824]*/
10441102{
10451103 if (!PyLong_CheckExact (state )) {
10461104 PyErr_Format (PyExc_TypeError , "state must be an int, not %T" , state );
10471105 return NULL ;
10481106 }
10491107
1050- longrangeiterobject * r = (longrangeiterobject * )op ;
10511108 PyObject * zero = _PyLong_GetZero (); // borrowed reference
10521109 int cmp ;
10531110
@@ -1085,9 +1142,9 @@ longrangeiter_setstate(PyObject *op, PyObject *state)
10851142}
10861143
10871144static PyMethodDef longrangeiter_methods [] = {
1088- { "__length_hint__" , longrangeiter_len , METH_NOARGS , length_hint_doc },
1089- { "__reduce__" , longrangeiter_reduce , METH_NOARGS , reduce_doc },
1090- { "__setstate__" , longrangeiter_setstate , METH_O , setstate_doc },
1145+ LONGRANGE_ITERATOR___LENGTH_HINT___METHODDEF
1146+ LONGRANGE_ITERATOR___REDUCE___METHODDEF
1147+ LONGRANGE_ITERATOR___SETSTATE___METHODDEF
10911148 {NULL , NULL } /* sentinel */
10921149};
10931150
@@ -1102,7 +1159,7 @@ longrangeiter_dealloc(PyObject *op)
11021159}
11031160
11041161static PyObject *
1105- longrangeiter_next (PyObject * op )
1162+ longrangeiter_next_lock_held (PyObject * op )
11061163{
11071164 longrangeiterobject * r = (longrangeiterobject * )op ;
11081165 if (PyObject_RichCompareBool (r -> len , _PyLong_GetZero (), Py_GT ) != 1 )
@@ -1123,6 +1180,16 @@ longrangeiter_next(PyObject *op)
11231180 return result ;
11241181}
11251182
1183+ static PyObject *
1184+ longrangeiter_next (PyObject * op )
1185+ {
1186+ PyObject * result ;
1187+ Py_BEGIN_CRITICAL_SECTION (op );
1188+ result = longrangeiter_next_lock_held (op );
1189+ Py_END_CRITICAL_SECTION ();
1190+ return result ;
1191+ }
1192+
11261193PyTypeObject PyLongRangeIter_Type = {
11271194 PyVarObject_HEAD_INIT (& PyType_Type , 0 )
11281195 "longrange_iterator" , /* tp_name */
0 commit comments