1 /* Range object implementation */
2 
3 #include "Python.h"
4 #include "pycore_abstract.h"   // _PyIndex_Check()
5 #include "pycore_tupleobject.h"
6 #include "structmember.h"         // PyMemberDef
7 
8 /* Support objects whose length is > PY_SSIZE_T_MAX.
9 
10    This could be sped up for small PyLongs if they fit in a Py_ssize_t.
11    This only matters on Win64.  Though we could use long long which
12    would presumably help perf.
13 */
14 
15 typedef struct {
16     PyObject_HEAD
17     PyObject *start;
18     PyObject *stop;
19     PyObject *step;
20     PyObject *length;
21 } rangeobject;
22 
23 _Py_IDENTIFIER(iter);
24 
25 /* Helper function for validating step.  Always returns a new reference or
26    NULL on error.
27 */
28 static PyObject *
validate_step(PyObject * step)29 validate_step(PyObject *step)
30 {
31     /* No step specified, use a step of 1. */
32     if (!step)
33         return PyLong_FromLong(1);
34 
35     step = PyNumber_Index(step);
36     if (step && _PyLong_Sign(step) == 0) {
37         PyErr_SetString(PyExc_ValueError,
38                         "range() arg 3 must not be zero");
39         Py_CLEAR(step);
40     }
41 
42     return step;
43 }
44 
45 static PyObject *
46 compute_range_length(PyObject *start, PyObject *stop, PyObject *step);
47 
48 static rangeobject *
make_range_object(PyTypeObject * type,PyObject * start,PyObject * stop,PyObject * step)49 make_range_object(PyTypeObject *type, PyObject *start,
50                   PyObject *stop, PyObject *step)
51 {
52     rangeobject *obj = NULL;
53     PyObject *length;
54     length = compute_range_length(start, stop, step);
55     if (length == NULL) {
56         return NULL;
57     }
58     obj = PyObject_New(rangeobject, type);
59     if (obj == NULL) {
60         Py_DECREF(length);
61         return NULL;
62     }
63     obj->start = start;
64     obj->stop = stop;
65     obj->step = step;
66     obj->length = length;
67     return obj;
68 }
69 
70 /* XXX(nnorwitz): should we error check if the user passes any empty ranges?
71    range(-10)
72    range(0, -5)
73    range(0, 5, -1)
74 */
75 static PyObject *
range_from_array(PyTypeObject * type,PyObject * const * args,Py_ssize_t num_args)76 range_from_array(PyTypeObject *type, PyObject *const *args, Py_ssize_t num_args)
77 {
78     rangeobject *obj;
79     PyObject *start = NULL, *stop = NULL, *step = NULL;
80 
81     switch (num_args) {
82         case 3:
83             step = args[2];
84             /* fallthrough */
85         case 2:
86             /* Convert borrowed refs to owned refs */
87             start = PyNumber_Index(args[0]);
88             if (!start) {
89                 return NULL;
90             }
91             stop = PyNumber_Index(args[1]);
92             if (!stop) {
93                 Py_DECREF(start);
94                 return NULL;
95             }
96             step = validate_step(step);  /* Caution, this can clear exceptions */
97             if (!step) {
98                 Py_DECREF(start);
99                 Py_DECREF(stop);
100                 return NULL;
101             }
102             break;
103         case 1:
104             stop = PyNumber_Index(args[0]);
105             if (!stop) {
106                 return NULL;
107             }
108             Py_INCREF(_PyLong_Zero);
109             start = _PyLong_Zero;
110             Py_INCREF(_PyLong_One);
111             step = _PyLong_One;
112             break;
113         case 0:
114             PyErr_SetString(PyExc_TypeError,
115                             "range expected at least 1 argument, got 0");
116             return NULL;
117         default:
118             PyErr_Format(PyExc_TypeError,
119                          "range expected at most 3 arguments, got %zd",
120                          num_args);
121             return NULL;
122     }
123     obj = make_range_object(type, start, stop, step);
124     if (obj != NULL) {
125         return (PyObject *) obj;
126     }
127 
128     /* Failed to create object, release attributes */
129     Py_DECREF(start);
130     Py_DECREF(stop);
131     Py_DECREF(step);
132     return NULL;
133 }
134 
135 static PyObject *
range_new(PyTypeObject * type,PyObject * args,PyObject * kw)136 range_new(PyTypeObject *type, PyObject *args, PyObject *kw)
137 {
138     if (!_PyArg_NoKeywords("range", kw))
139         return NULL;
140 
141     return range_from_array(type, _PyTuple_ITEMS(args), PyTuple_GET_SIZE(args));
142 }
143 
144 
145 static PyObject *
range_vectorcall(PyTypeObject * type,PyObject * const * args,size_t nargsf,PyObject * kwnames)146 range_vectorcall(PyTypeObject *type, PyObject *const *args,
147                  size_t nargsf, PyObject *kwnames)
148 {
149     Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
150     if (!_PyArg_NoKwnames("range", kwnames)) {
151         return NULL;
152     }
153     return range_from_array(type, args, nargs);
154 }
155 
156 PyDoc_STRVAR(range_doc,
157 "range(stop) -> range object\n\
158 range(start, stop[, step]) -> range object\n\
159 \n\
160 Return an object that produces a sequence of integers from start (inclusive)\n\
161 to stop (exclusive) by step.  range(i, j) produces i, i+1, i+2, ..., j-1.\n\
162 start defaults to 0, and stop is omitted!  range(4) produces 0, 1, 2, 3.\n\
163 These are exactly the valid indices for a list of 4 elements.\n\
164 When step is given, it specifies the increment (or decrement).");
165 
166 static void
range_dealloc(rangeobject * r)167 range_dealloc(rangeobject *r)
168 {
169     Py_DECREF(r->start);
170     Py_DECREF(r->stop);
171     Py_DECREF(r->step);
172     Py_DECREF(r->length);
173     PyObject_Del(r);
174 }
175 
176 /* Return number of items in range (lo, hi, step) as a PyLong object,
177  * when arguments are PyLong objects.  Arguments MUST return 1 with
178  * PyLong_Check().  Return NULL when there is an error.
179  */
180 static PyObject*
compute_range_length(PyObject * start,PyObject * stop,PyObject * step)181 compute_range_length(PyObject *start, PyObject *stop, PyObject *step)
182 {
183     /* -------------------------------------------------------------
184     Algorithm is equal to that of get_len_of_range(), but it operates
185     on PyObjects (which are assumed to be PyLong objects).
186     ---------------------------------------------------------------*/
187     int cmp_result;
188     PyObject *lo, *hi;
189     PyObject *diff = NULL;
190     PyObject *tmp1 = NULL, *tmp2 = NULL, *result;
191                 /* holds sub-expression evaluations */
192 
193     cmp_result = PyObject_RichCompareBool(step, _PyLong_Zero, Py_GT);
194     if (cmp_result == -1)
195         return NULL;
196 
197     if (cmp_result == 1) {
198         lo = start;
199         hi = stop;
200         Py_INCREF(step);
201     } else {
202         lo = stop;
203         hi = start;
204         step = PyNumber_Negative(step);
205         if (!step)
206             return NULL;
207     }
208 
209     /* if (lo >= hi), return length of 0. */
210     cmp_result = PyObject_RichCompareBool(lo, hi, Py_GE);
211     if (cmp_result != 0) {
212         Py_DECREF(step);
213         if (cmp_result < 0)
214             return NULL;
215         return PyLong_FromLong(0);
216     }
217 
218     if ((tmp1 = PyNumber_Subtract(hi, lo)) == NULL)
219         goto Fail;
220 
221     if ((diff = PyNumber_Subtract(tmp1, _PyLong_One)) == NULL)
222         goto Fail;
223 
224     if ((tmp2 = PyNumber_FloorDivide(diff, step)) == NULL)
225         goto Fail;
226 
227     if ((result = PyNumber_Add(tmp2, _PyLong_One)) == NULL)
228         goto Fail;
229 
230     Py_DECREF(tmp2);
231     Py_DECREF(diff);
232     Py_DECREF(step);
233     Py_DECREF(tmp1);
234     return result;
235 
236   Fail:
237     Py_DECREF(step);
238     Py_XDECREF(tmp2);
239     Py_XDECREF(diff);
240     Py_XDECREF(tmp1);
241     return NULL;
242 }
243 
244 static Py_ssize_t
range_length(rangeobject * r)245 range_length(rangeobject *r)
246 {
247     return PyLong_AsSsize_t(r->length);
248 }
249 
250 static PyObject *
compute_item(rangeobject * r,PyObject * i)251 compute_item(rangeobject *r, PyObject *i)
252 {
253     PyObject *incr, *result;
254     /* PyLong equivalent to:
255      *    return r->start + (i * r->step)
256      */
257     incr = PyNumber_Multiply(i, r->step);
258     if (!incr)
259         return NULL;
260     result = PyNumber_Add(r->start, incr);
261     Py_DECREF(incr);
262     return result;
263 }
264 
265 static PyObject *
compute_range_item(rangeobject * r,PyObject * arg)266 compute_range_item(rangeobject *r, PyObject *arg)
267 {
268     int cmp_result;
269     PyObject *i, *result;
270 
271     /* PyLong equivalent to:
272      *   if (arg < 0) {
273      *     i = r->length + arg
274      *   } else {
275      *     i = arg
276      *   }
277      */
278     cmp_result = PyObject_RichCompareBool(arg, _PyLong_Zero, Py_LT);
279     if (cmp_result == -1) {
280         return NULL;
281     }
282     if (cmp_result == 1) {
283         i = PyNumber_Add(r->length, arg);
284         if (!i) {
285           return NULL;
286         }
287     } else {
288         i = arg;
289         Py_INCREF(i);
290     }
291 
292     /* PyLong equivalent to:
293      *   if (i < 0 || i >= r->length) {
294      *     <report index out of bounds>
295      *   }
296      */
297     cmp_result = PyObject_RichCompareBool(i, _PyLong_Zero, Py_LT);
298     if (cmp_result == 0) {
299         cmp_result = PyObject_RichCompareBool(i, r->length, Py_GE);
300     }
301     if (cmp_result == -1) {
302        Py_DECREF(i);
303        return NULL;
304     }
305     if (cmp_result == 1) {
306         Py_DECREF(i);
307         PyErr_SetString(PyExc_IndexError,
308                         "range object index out of range");
309         return NULL;
310     }
311 
312     result = compute_item(r, i);
313     Py_DECREF(i);
314     return result;
315 }
316 
317 static PyObject *
range_item(rangeobject * r,Py_ssize_t i)318 range_item(rangeobject *r, Py_ssize_t i)
319 {
320     PyObject *res, *arg = PyLong_FromSsize_t(i);
321     if (!arg) {
322         return NULL;
323     }
324     res = compute_range_item(r, arg);
325     Py_DECREF(arg);
326     return res;
327 }
328 
329 static PyObject *
compute_slice(rangeobject * r,PyObject * _slice)330 compute_slice(rangeobject *r, PyObject *_slice)
331 {
332     PySliceObject *slice = (PySliceObject *) _slice;
333     rangeobject *result;
334     PyObject *start = NULL, *stop = NULL, *step = NULL;
335     PyObject *substart = NULL, *substop = NULL, *substep = NULL;
336     int error;
337 
338     error = _PySlice_GetLongIndices(slice, r->length, &start, &stop, &step);
339     if (error == -1)
340         return NULL;
341 
342     substep = PyNumber_Multiply(r->step, step);
343     if (substep == NULL) goto fail;
344     Py_CLEAR(step);
345 
346     substart = compute_item(r, start);
347     if (substart == NULL) goto fail;
348     Py_CLEAR(start);
349 
350     substop = compute_item(r, stop);
351     if (substop == NULL) goto fail;
352     Py_CLEAR(stop);
353 
354     result = make_range_object(Py_TYPE(r), substart, substop, substep);
355     if (result != NULL) {
356         return (PyObject *) result;
357     }
358 fail:
359     Py_XDECREF(start);
360     Py_XDECREF(stop);
361     Py_XDECREF(step);
362     Py_XDECREF(substart);
363     Py_XDECREF(substop);
364     Py_XDECREF(substep);
365     return NULL;
366 }
367 
368 /* Assumes (PyLong_CheckExact(ob) || PyBool_Check(ob)) */
369 static int
range_contains_long(rangeobject * r,PyObject * ob)370 range_contains_long(rangeobject *r, PyObject *ob)
371 {
372     int cmp1, cmp2, cmp3;
373     PyObject *tmp1 = NULL;
374     PyObject *tmp2 = NULL;
375     int result = -1;
376 
377     /* Check if the value can possibly be in the range. */
378 
379     cmp1 = PyObject_RichCompareBool(r->step, _PyLong_Zero, Py_GT);
380     if (cmp1 == -1)
381         goto end;
382     if (cmp1 == 1) { /* positive steps: start <= ob < stop */
383         cmp2 = PyObject_RichCompareBool(r->start, ob, Py_LE);
384         cmp3 = PyObject_RichCompareBool(ob, r->stop, Py_LT);
385     }
386     else { /* negative steps: stop < ob <= start */
387         cmp2 = PyObject_RichCompareBool(ob, r->start, Py_LE);
388         cmp3 = PyObject_RichCompareBool(r->stop, ob, Py_LT);
389     }
390 
391     if (cmp2 == -1 || cmp3 == -1) /* TypeError */
392         goto end;
393     if (cmp2 == 0 || cmp3 == 0) { /* ob outside of range */
394         result = 0;
395         goto end;
396     }
397 
398     /* Check that the stride does not invalidate ob's membership. */
399     tmp1 = PyNumber_Subtract(ob, r->start);
400     if (tmp1 == NULL)
401         goto end;
402     tmp2 = PyNumber_Remainder(tmp1, r->step);
403     if (tmp2 == NULL)
404         goto end;
405     /* result = ((int(ob) - start) % step) == 0 */
406     result = PyObject_RichCompareBool(tmp2, _PyLong_Zero, Py_EQ);
407   end:
408     Py_XDECREF(tmp1);
409     Py_XDECREF(tmp2);
410     return result;
411 }
412 
413 static int
range_contains(rangeobject * r,PyObject * ob)414 range_contains(rangeobject *r, PyObject *ob)
415 {
416     if (PyLong_CheckExact(ob) || PyBool_Check(ob))
417         return range_contains_long(r, ob);
418 
419     return (int)_PySequence_IterSearch((PyObject*)r, ob,
420                                        PY_ITERSEARCH_CONTAINS);
421 }
422 
423 /* Compare two range objects.  Return 1 for equal, 0 for not equal
424    and -1 on error.  The algorithm is roughly the C equivalent of
425 
426    if r0 is r1:
427        return True
428    if len(r0) != len(r1):
429        return False
430    if not len(r0):
431        return True
432    if r0.start != r1.start:
433        return False
434    if len(r0) == 1:
435        return True
436    return r0.step == r1.step
437 */
438 static int
range_equals(rangeobject * r0,rangeobject * r1)439 range_equals(rangeobject *r0, rangeobject *r1)
440 {
441     int cmp_result;
442 
443     if (r0 == r1)
444         return 1;
445     cmp_result = PyObject_RichCompareBool(r0->length, r1->length, Py_EQ);
446     /* Return False or error to the caller. */
447     if (cmp_result != 1)
448         return cmp_result;
449     cmp_result = PyObject_Not(r0->length);
450     /* Return True or error to the caller. */
451     if (cmp_result != 0)
452         return cmp_result;
453     cmp_result = PyObject_RichCompareBool(r0->start, r1->start, Py_EQ);
454     /* Return False or error to the caller. */
455     if (cmp_result != 1)
456         return cmp_result;
457     cmp_result = PyObject_RichCompareBool(r0->length, _PyLong_One, Py_EQ);
458     /* Return True or error to the caller. */
459     if (cmp_result != 0)
460         return cmp_result;
461     return PyObject_RichCompareBool(r0->step, r1->step, Py_EQ);
462 }
463 
464 static PyObject *
range_richcompare(PyObject * self,PyObject * other,int op)465 range_richcompare(PyObject *self, PyObject *other, int op)
466 {
467     int result;
468 
469     if (!PyRange_Check(other))
470         Py_RETURN_NOTIMPLEMENTED;
471     switch (op) {
472     case Py_NE:
473     case Py_EQ:
474         result = range_equals((rangeobject*)self, (rangeobject*)other);
475         if (result == -1)
476             return NULL;
477         if (op == Py_NE)
478             result = !result;
479         if (result)
480             Py_RETURN_TRUE;
481         else
482             Py_RETURN_FALSE;
483     case Py_LE:
484     case Py_GE:
485     case Py_LT:
486     case Py_GT:
487         Py_RETURN_NOTIMPLEMENTED;
488     default:
489         PyErr_BadArgument();
490         return NULL;
491     }
492 }
493 
494 /* Hash function for range objects.  Rough C equivalent of
495 
496    if not len(r):
497        return hash((len(r), None, None))
498    if len(r) == 1:
499        return hash((len(r), r.start, None))
500    return hash((len(r), r.start, r.step))
501 */
502 static Py_hash_t
range_hash(rangeobject * r)503 range_hash(rangeobject *r)
504 {
505     PyObject *t;
506     Py_hash_t result = -1;
507     int cmp_result;
508 
509     t = PyTuple_New(3);
510     if (!t)
511         return -1;
512     Py_INCREF(r->length);
513     PyTuple_SET_ITEM(t, 0, r->length);
514     cmp_result = PyObject_Not(r->length);
515     if (cmp_result == -1)
516         goto end;
517     if (cmp_result == 1) {
518         Py_INCREF(Py_None);
519         Py_INCREF(Py_None);
520         PyTuple_SET_ITEM(t, 1, Py_None);
521         PyTuple_SET_ITEM(t, 2, Py_None);
522     }
523     else {
524         Py_INCREF(r->start);
525         PyTuple_SET_ITEM(t, 1, r->start);
526         cmp_result = PyObject_RichCompareBool(r->length, _PyLong_One, Py_EQ);
527         if (cmp_result == -1)
528             goto end;
529         if (cmp_result == 1) {
530             Py_INCREF(Py_None);
531             PyTuple_SET_ITEM(t, 2, Py_None);
532         }
533         else {
534             Py_INCREF(r->step);
535             PyTuple_SET_ITEM(t, 2, r->step);
536         }
537     }
538     result = PyObject_Hash(t);
539   end:
540     Py_DECREF(t);
541     return result;
542 }
543 
544 static PyObject *
range_count(rangeobject * r,PyObject * ob)545 range_count(rangeobject *r, PyObject *ob)
546 {
547     if (PyLong_CheckExact(ob) || PyBool_Check(ob)) {
548         int result = range_contains_long(r, ob);
549         if (result == -1)
550             return NULL;
551         return PyLong_FromLong(result);
552     } else {
553         Py_ssize_t count;
554         count = _PySequence_IterSearch((PyObject*)r, ob, PY_ITERSEARCH_COUNT);
555         if (count == -1)
556             return NULL;
557         return PyLong_FromSsize_t(count);
558     }
559 }
560 
561 static PyObject *
range_index(rangeobject * r,PyObject * ob)562 range_index(rangeobject *r, PyObject *ob)
563 {
564     int contains;
565 
566     if (!PyLong_CheckExact(ob) && !PyBool_Check(ob)) {
567         Py_ssize_t index;
568         index = _PySequence_IterSearch((PyObject*)r, ob, PY_ITERSEARCH_INDEX);
569         if (index == -1)
570             return NULL;
571         return PyLong_FromSsize_t(index);
572     }
573 
574     contains = range_contains_long(r, ob);
575     if (contains == -1)
576         return NULL;
577 
578     if (contains) {
579         PyObject *idx, *tmp = PyNumber_Subtract(ob, r->start);
580         if (tmp == NULL)
581             return NULL;
582         /* idx = (ob - r.start) // r.step */
583         idx = PyNumber_FloorDivide(tmp, r->step);
584         Py_DECREF(tmp);
585         return idx;
586     }
587 
588     /* object is not in the range */
589     PyErr_Format(PyExc_ValueError, "%R is not in range", ob);
590     return NULL;
591 }
592 
593 static PySequenceMethods range_as_sequence = {
594     (lenfunc)range_length,      /* sq_length */
595     0,                          /* sq_concat */
596     0,                          /* sq_repeat */
597     (ssizeargfunc)range_item,   /* sq_item */
598     0,                          /* sq_slice */
599     0,                          /* sq_ass_item */
600     0,                          /* sq_ass_slice */
601     (objobjproc)range_contains, /* sq_contains */
602 };
603 
604 static PyObject *
range_repr(rangeobject * r)605 range_repr(rangeobject *r)
606 {
607     Py_ssize_t istep;
608 
609     /* Check for special case values for printing.  We don't always
610        need the step value.  We don't care about overflow. */
611     istep = PyNumber_AsSsize_t(r->step, NULL);
612     if (istep == -1 && PyErr_Occurred()) {
613         assert(!PyErr_ExceptionMatches(PyExc_OverflowError));
614         return NULL;
615     }
616 
617     if (istep == 1)
618         return PyUnicode_FromFormat("range(%R, %R)", r->start, r->stop);
619     else
620         return PyUnicode_FromFormat("range(%R, %R, %R)",
621                                     r->start, r->stop, r->step);
622 }
623 
624 /* Pickling support */
625 static PyObject *
range_reduce(rangeobject * r,PyObject * args)626 range_reduce(rangeobject *r, PyObject *args)
627 {
628     return Py_BuildValue("(O(OOO))", Py_TYPE(r),
629                          r->start, r->stop, r->step);
630 }
631 
632 static PyObject *
range_subscript(rangeobject * self,PyObject * item)633 range_subscript(rangeobject* self, PyObject* item)
634 {
635     if (_PyIndex_Check(item)) {
636         PyObject *i, *result;
637         i = PyNumber_Index(item);
638         if (!i)
639             return NULL;
640         result = compute_range_item(self, i);
641         Py_DECREF(i);
642         return result;
643     }
644     if (PySlice_Check(item)) {
645         return compute_slice(self, item);
646     }
647     PyErr_Format(PyExc_TypeError,
648                  "range indices must be integers or slices, not %.200s",
649                  Py_TYPE(item)->tp_name);
650     return NULL;
651 }
652 
653 
654 static PyMappingMethods range_as_mapping = {
655         (lenfunc)range_length,       /* mp_length */
656         (binaryfunc)range_subscript, /* mp_subscript */
657         (objobjargproc)0,            /* mp_ass_subscript */
658 };
659 
660 static int
range_bool(rangeobject * self)661 range_bool(rangeobject* self)
662 {
663     return PyObject_IsTrue(self->length);
664 }
665 
666 static PyNumberMethods range_as_number = {
667     .nb_bool = (inquiry)range_bool,
668 };
669 
670 static PyObject * range_iter(PyObject *seq);
671 static PyObject * range_reverse(PyObject *seq, PyObject *Py_UNUSED(ignored));
672 
673 PyDoc_STRVAR(reverse_doc,
674 "Return a reverse iterator.");
675 
676 PyDoc_STRVAR(count_doc,
677 "rangeobject.count(value) -> integer -- return number of occurrences of value");
678 
679 PyDoc_STRVAR(index_doc,
680 "rangeobject.index(value) -> integer -- return index of value.\n"
681 "Raise ValueError if the value is not present.");
682 
683 static PyMethodDef range_methods[] = {
684     {"__reversed__",    range_reverse,              METH_NOARGS, reverse_doc},
685     {"__reduce__",      (PyCFunction)range_reduce,  METH_VARARGS},
686     {"count",           (PyCFunction)range_count,   METH_O,      count_doc},
687     {"index",           (PyCFunction)range_index,   METH_O,      index_doc},
688     {NULL,              NULL}           /* sentinel */
689 };
690 
691 static PyMemberDef range_members[] = {
692     {"start",   T_OBJECT_EX,    offsetof(rangeobject, start),   READONLY},
693     {"stop",    T_OBJECT_EX,    offsetof(rangeobject, stop),    READONLY},
694     {"step",    T_OBJECT_EX,    offsetof(rangeobject, step),    READONLY},
695     {0}
696 };
697 
698 PyTypeObject PyRange_Type = {
699         PyVarObject_HEAD_INIT(&PyType_Type, 0)
700         "range",                /* Name of this type */
701         sizeof(rangeobject),    /* Basic object size */
702         0,                      /* Item size for varobject */
703         (destructor)range_dealloc, /* tp_dealloc */
704         0,                      /* tp_vectorcall_offset */
705         0,                      /* tp_getattr */
706         0,                      /* tp_setattr */
707         0,                      /* tp_as_async */
708         (reprfunc)range_repr,   /* tp_repr */
709         &range_as_number,       /* tp_as_number */
710         &range_as_sequence,     /* tp_as_sequence */
711         &range_as_mapping,      /* tp_as_mapping */
712         (hashfunc)range_hash,   /* tp_hash */
713         0,                      /* tp_call */
714         0,                      /* tp_str */
715         PyObject_GenericGetAttr,  /* tp_getattro */
716         0,                      /* tp_setattro */
717         0,                      /* tp_as_buffer */
718         Py_TPFLAGS_DEFAULT,     /* tp_flags */
719         range_doc,              /* tp_doc */
720         0,                      /* tp_traverse */
721         0,                      /* tp_clear */
722         range_richcompare,      /* tp_richcompare */
723         0,                      /* tp_weaklistoffset */
724         range_iter,             /* tp_iter */
725         0,                      /* tp_iternext */
726         range_methods,          /* tp_methods */
727         range_members,          /* tp_members */
728         0,                      /* tp_getset */
729         0,                      /* tp_base */
730         0,                      /* tp_dict */
731         0,                      /* tp_descr_get */
732         0,                      /* tp_descr_set */
733         0,                      /* tp_dictoffset */
734         0,                      /* tp_init */
735         0,                      /* tp_alloc */
736         range_new,              /* tp_new */
737         .tp_vectorcall = (vectorcallfunc)range_vectorcall
738 };
739 
740 /*********************** range Iterator **************************/
741 
742 /* There are 2 types of iterators, one for C longs, the other for
743    Python ints (ie, PyObjects).  This should make iteration fast
744    in the normal case, but possible for any numeric value.
745 */
746 
747 typedef struct {
748         PyObject_HEAD
749         long    index;
750         long    start;
751         long    step;
752         long    len;
753 } rangeiterobject;
754 
755 static PyObject *
rangeiter_next(rangeiterobject * r)756 rangeiter_next(rangeiterobject *r)
757 {
758     if (r->index < r->len)
759         /* cast to unsigned to avoid possible signed overflow
760            in intermediate calculations. */
761         return PyLong_FromLong((long)(r->start +
762                                       (unsigned long)(r->index++) * r->step));
763     return NULL;
764 }
765 
766 static PyObject *
rangeiter_len(rangeiterobject * r,PyObject * Py_UNUSED (ignored))767 rangeiter_len(rangeiterobject *r, PyObject *Py_UNUSED(ignored))
768 {
769     return PyLong_FromLong(r->len - r->index);
770 }
771 
772 PyDoc_STRVAR(length_hint_doc,
773              "Private method returning an estimate of len(list(it)).");
774 
775 static PyObject *
rangeiter_reduce(rangeiterobject * r,PyObject * Py_UNUSED (ignored))776 rangeiter_reduce(rangeiterobject *r, PyObject *Py_UNUSED(ignored))
777 {
778     PyObject *start=NULL, *stop=NULL, *step=NULL;
779     PyObject *range;
780 
781     /* create a range object for pickling */
782     start = PyLong_FromLong(r->start);
783     if (start == NULL)
784         goto err;
785     stop = PyLong_FromLong(r->start + r->len * r->step);
786     if (stop == NULL)
787         goto err;
788     step = PyLong_FromLong(r->step);
789     if (step == NULL)
790         goto err;
791     range = (PyObject*)make_range_object(&PyRange_Type,
792                                start, stop, step);
793     if (range == NULL)
794         goto err;
795     /* return the result */
796     return Py_BuildValue("N(N)i", _PyEval_GetBuiltinId(&PyId_iter),
797                          range, r->index);
798 err:
799     Py_XDECREF(start);
800     Py_XDECREF(stop);
801     Py_XDECREF(step);
802     return NULL;
803 }
804 
805 static PyObject *
rangeiter_setstate(rangeiterobject * r,PyObject * state)806 rangeiter_setstate(rangeiterobject *r, PyObject *state)
807 {
808     long index = PyLong_AsLong(state);
809     if (index == -1 && PyErr_Occurred())
810         return NULL;
811     /* silently clip the index value */
812     if (index < 0)
813         index = 0;
814     else if (index > r->len)
815         index = r->len; /* exhausted iterator */
816     r->index = index;
817     Py_RETURN_NONE;
818 }
819 
820 PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
821 PyDoc_STRVAR(setstate_doc, "Set state information for unpickling.");
822 
823 static PyMethodDef rangeiter_methods[] = {
824     {"__length_hint__", (PyCFunction)rangeiter_len, METH_NOARGS,
825         length_hint_doc},
826     {"__reduce__", (PyCFunction)rangeiter_reduce, METH_NOARGS,
827         reduce_doc},
828     {"__setstate__", (PyCFunction)rangeiter_setstate, METH_O,
829         setstate_doc},
830     {NULL,              NULL}           /* sentinel */
831 };
832 
833 PyTypeObject PyRangeIter_Type = {
834         PyVarObject_HEAD_INIT(&PyType_Type, 0)
835         "range_iterator",                        /* tp_name */
836         sizeof(rangeiterobject),                /* tp_basicsize */
837         0,                                      /* tp_itemsize */
838         /* methods */
839         (destructor)PyObject_Del,               /* tp_dealloc */
840         0,                                      /* tp_vectorcall_offset */
841         0,                                      /* tp_getattr */
842         0,                                      /* tp_setattr */
843         0,                                      /* tp_as_async */
844         0,                                      /* tp_repr */
845         0,                                      /* tp_as_number */
846         0,                                      /* tp_as_sequence */
847         0,                                      /* tp_as_mapping */
848         0,                                      /* tp_hash */
849         0,                                      /* tp_call */
850         0,                                      /* tp_str */
851         PyObject_GenericGetAttr,                /* tp_getattro */
852         0,                                      /* tp_setattro */
853         0,                                      /* tp_as_buffer */
854         Py_TPFLAGS_DEFAULT,                     /* tp_flags */
855         0,                                      /* tp_doc */
856         0,                                      /* tp_traverse */
857         0,                                      /* tp_clear */
858         0,                                      /* tp_richcompare */
859         0,                                      /* tp_weaklistoffset */
860         PyObject_SelfIter,                      /* tp_iter */
861         (iternextfunc)rangeiter_next,           /* tp_iternext */
862         rangeiter_methods,                      /* tp_methods */
863         0,                                      /* tp_members */
864 };
865 
866 /* Return number of items in range (lo, hi, step).  step != 0
867  * required.  The result always fits in an unsigned long.
868  */
869 static unsigned long
get_len_of_range(long lo,long hi,long step)870 get_len_of_range(long lo, long hi, long step)
871 {
872     /* -------------------------------------------------------------
873     If step > 0 and lo >= hi, or step < 0 and lo <= hi, the range is empty.
874     Else for step > 0, if n values are in the range, the last one is
875     lo + (n-1)*step, which must be <= hi-1.  Rearranging,
876     n <= (hi - lo - 1)/step + 1, so taking the floor of the RHS gives
877     the proper value.  Since lo < hi in this case, hi-lo-1 >= 0, so
878     the RHS is non-negative and so truncation is the same as the
879     floor.  Letting M be the largest positive long, the worst case
880     for the RHS numerator is hi=M, lo=-M-1, and then
881     hi-lo-1 = M-(-M-1)-1 = 2*M.  Therefore unsigned long has enough
882     precision to compute the RHS exactly.  The analysis for step < 0
883     is similar.
884     ---------------------------------------------------------------*/
885     assert(step != 0);
886     if (step > 0 && lo < hi)
887         return 1UL + (hi - 1UL - lo) / step;
888     else if (step < 0 && lo > hi)
889         return 1UL + (lo - 1UL - hi) / (0UL - step);
890     else
891         return 0UL;
892 }
893 
894 /* Initialize a rangeiter object.  If the length of the rangeiter object
895    is not representable as a C long, OverflowError is raised. */
896 
897 static PyObject *
fast_range_iter(long start,long stop,long step)898 fast_range_iter(long start, long stop, long step)
899 {
900     rangeiterobject *it = PyObject_New(rangeiterobject, &PyRangeIter_Type);
901     unsigned long ulen;
902     if (it == NULL)
903         return NULL;
904     it->start = start;
905     it->step = step;
906     ulen = get_len_of_range(start, stop, step);
907     if (ulen > (unsigned long)LONG_MAX) {
908         Py_DECREF(it);
909         PyErr_SetString(PyExc_OverflowError,
910                         "range too large to represent as a range_iterator");
911         return NULL;
912     }
913     it->len = (long)ulen;
914     it->index = 0;
915     return (PyObject *)it;
916 }
917 
918 typedef struct {
919     PyObject_HEAD
920     PyObject *index;
921     PyObject *start;
922     PyObject *step;
923     PyObject *len;
924 } longrangeiterobject;
925 
926 static PyObject *
longrangeiter_len(longrangeiterobject * r,PyObject * no_args)927 longrangeiter_len(longrangeiterobject *r, PyObject *no_args)
928 {
929     return PyNumber_Subtract(r->len, r->index);
930 }
931 
932 static PyObject *
longrangeiter_reduce(longrangeiterobject * r,PyObject * Py_UNUSED (ignored))933 longrangeiter_reduce(longrangeiterobject *r, PyObject *Py_UNUSED(ignored))
934 {
935     PyObject *product, *stop=NULL;
936     PyObject *range;
937 
938     /* create a range object for pickling.  Must calculate the "stop" value */
939     product = PyNumber_Multiply(r->len, r->step);
940     if (product == NULL)
941         return NULL;
942     stop = PyNumber_Add(r->start, product);
943     Py_DECREF(product);
944     if (stop ==  NULL)
945         return NULL;
946     Py_INCREF(r->start);
947     Py_INCREF(r->step);
948     range =  (PyObject*)make_range_object(&PyRange_Type,
949                                r->start, stop, r->step);
950     if (range == NULL) {
951         Py_DECREF(r->start);
952         Py_DECREF(stop);
953         Py_DECREF(r->step);
954         return NULL;
955     }
956 
957     /* return the result */
958     return Py_BuildValue("N(N)O", _PyEval_GetBuiltinId(&PyId_iter),
959                          range, r->index);
960 }
961 
962 static PyObject *
longrangeiter_setstate(longrangeiterobject * r,PyObject * state)963 longrangeiter_setstate(longrangeiterobject *r, PyObject *state)
964 {
965     int cmp;
966 
967     /* clip the value */
968     cmp = PyObject_RichCompareBool(state, _PyLong_Zero, Py_LT);
969     if (cmp < 0)
970         return NULL;
971     if (cmp > 0) {
972         state = _PyLong_Zero;
973     }
974     else {
975         cmp = PyObject_RichCompareBool(r->len, state, Py_LT);
976         if (cmp < 0)
977             return NULL;
978         if (cmp > 0)
979             state = r->len;
980     }
981     Py_INCREF(state);
982     Py_XSETREF(r->index, state);
983     Py_RETURN_NONE;
984 }
985 
986 static PyMethodDef longrangeiter_methods[] = {
987     {"__length_hint__", (PyCFunction)longrangeiter_len, METH_NOARGS,
988         length_hint_doc},
989     {"__reduce__", (PyCFunction)longrangeiter_reduce, METH_NOARGS,
990         reduce_doc},
991     {"__setstate__", (PyCFunction)longrangeiter_setstate, METH_O,
992         setstate_doc},
993     {NULL,              NULL}           /* sentinel */
994 };
995 
996 static void
longrangeiter_dealloc(longrangeiterobject * r)997 longrangeiter_dealloc(longrangeiterobject *r)
998 {
999     Py_XDECREF(r->index);
1000     Py_XDECREF(r->start);
1001     Py_XDECREF(r->step);
1002     Py_XDECREF(r->len);
1003     PyObject_Del(r);
1004 }
1005 
1006 static PyObject *
longrangeiter_next(longrangeiterobject * r)1007 longrangeiter_next(longrangeiterobject *r)
1008 {
1009     PyObject *product, *new_index, *result;
1010     if (PyObject_RichCompareBool(r->index, r->len, Py_LT) != 1)
1011         return NULL;
1012 
1013     new_index = PyNumber_Add(r->index, _PyLong_One);
1014     if (!new_index)
1015         return NULL;
1016 
1017     product = PyNumber_Multiply(r->index, r->step);
1018     if (!product) {
1019         Py_DECREF(new_index);
1020         return NULL;
1021     }
1022 
1023     result = PyNumber_Add(r->start, product);
1024     Py_DECREF(product);
1025     if (result) {
1026         Py_SETREF(r->index, new_index);
1027     }
1028     else {
1029         Py_DECREF(new_index);
1030     }
1031 
1032     return result;
1033 }
1034 
1035 PyTypeObject PyLongRangeIter_Type = {
1036         PyVarObject_HEAD_INIT(&PyType_Type, 0)
1037         "longrange_iterator",                   /* tp_name */
1038         sizeof(longrangeiterobject),            /* tp_basicsize */
1039         0,                                      /* tp_itemsize */
1040         /* methods */
1041         (destructor)longrangeiter_dealloc,      /* tp_dealloc */
1042         0,                                      /* tp_vectorcall_offset */
1043         0,                                      /* tp_getattr */
1044         0,                                      /* tp_setattr */
1045         0,                                      /* tp_as_async */
1046         0,                                      /* tp_repr */
1047         0,                                      /* tp_as_number */
1048         0,                                      /* tp_as_sequence */
1049         0,                                      /* tp_as_mapping */
1050         0,                                      /* tp_hash */
1051         0,                                      /* tp_call */
1052         0,                                      /* tp_str */
1053         PyObject_GenericGetAttr,                /* tp_getattro */
1054         0,                                      /* tp_setattro */
1055         0,                                      /* tp_as_buffer */
1056         Py_TPFLAGS_DEFAULT,                     /* tp_flags */
1057         0,                                      /* tp_doc */
1058         0,                                      /* tp_traverse */
1059         0,                                      /* tp_clear */
1060         0,                                      /* tp_richcompare */
1061         0,                                      /* tp_weaklistoffset */
1062         PyObject_SelfIter,                      /* tp_iter */
1063         (iternextfunc)longrangeiter_next,       /* tp_iternext */
1064         longrangeiter_methods,                  /* tp_methods */
1065         0,
1066 };
1067 
1068 static PyObject *
range_iter(PyObject * seq)1069 range_iter(PyObject *seq)
1070 {
1071     rangeobject *r = (rangeobject *)seq;
1072     longrangeiterobject *it;
1073     long lstart, lstop, lstep;
1074     PyObject *int_it;
1075 
1076     assert(PyRange_Check(seq));
1077 
1078     /* If all three fields and the length convert to long, use the int
1079      * version */
1080     lstart = PyLong_AsLong(r->start);
1081     if (lstart == -1 && PyErr_Occurred()) {
1082         PyErr_Clear();
1083         goto long_range;
1084     }
1085     lstop = PyLong_AsLong(r->stop);
1086     if (lstop == -1 && PyErr_Occurred()) {
1087         PyErr_Clear();
1088         goto long_range;
1089     }
1090     lstep = PyLong_AsLong(r->step);
1091     if (lstep == -1 && PyErr_Occurred()) {
1092         PyErr_Clear();
1093         goto long_range;
1094     }
1095     int_it = fast_range_iter(lstart, lstop, lstep);
1096     if (int_it == NULL && PyErr_ExceptionMatches(PyExc_OverflowError)) {
1097         PyErr_Clear();
1098         goto long_range;
1099     }
1100     return (PyObject *)int_it;
1101 
1102   long_range:
1103     it = PyObject_New(longrangeiterobject, &PyLongRangeIter_Type);
1104     if (it == NULL)
1105         return NULL;
1106 
1107     it->start = r->start;
1108     it->step = r->step;
1109     it->len = r->length;
1110     it->index = _PyLong_Zero;
1111     Py_INCREF(it->start);
1112     Py_INCREF(it->step);
1113     Py_INCREF(it->len);
1114     Py_INCREF(it->index);
1115     return (PyObject *)it;
1116 }
1117 
1118 static PyObject *
range_reverse(PyObject * seq,PyObject * Py_UNUSED (ignored))1119 range_reverse(PyObject *seq, PyObject *Py_UNUSED(ignored))
1120 {
1121     rangeobject *range = (rangeobject*) seq;
1122     longrangeiterobject *it;
1123     PyObject *sum, *diff, *product;
1124     long lstart, lstop, lstep, new_start, new_stop;
1125     unsigned long ulen;
1126 
1127     assert(PyRange_Check(seq));
1128 
1129     /* reversed(range(start, stop, step)) can be expressed as
1130        range(start+(n-1)*step, start-step, -step), where n is the number of
1131        integers in the range.
1132 
1133        If each of start, stop, step, -step, start-step, and the length
1134        of the iterator is representable as a C long, use the int
1135        version.  This excludes some cases where the reversed range is
1136        representable as a range_iterator, but it's good enough for
1137        common cases and it makes the checks simple. */
1138 
1139     lstart = PyLong_AsLong(range->start);
1140     if (lstart == -1 && PyErr_Occurred()) {
1141         PyErr_Clear();
1142         goto long_range;
1143     }
1144     lstop = PyLong_AsLong(range->stop);
1145     if (lstop == -1 && PyErr_Occurred()) {
1146         PyErr_Clear();
1147         goto long_range;
1148     }
1149     lstep = PyLong_AsLong(range->step);
1150     if (lstep == -1 && PyErr_Occurred()) {
1151         PyErr_Clear();
1152         goto long_range;
1153     }
1154     /* check for possible overflow of -lstep */
1155     if (lstep == LONG_MIN)
1156         goto long_range;
1157 
1158     /* check for overflow of lstart - lstep:
1159 
1160        for lstep > 0, need only check whether lstart - lstep < LONG_MIN.
1161        for lstep < 0, need only check whether lstart - lstep > LONG_MAX
1162 
1163        Rearrange these inequalities as:
1164 
1165            lstart - LONG_MIN < lstep  (lstep > 0)
1166            LONG_MAX - lstart < -lstep  (lstep < 0)
1167 
1168        and compute both sides as unsigned longs, to avoid the
1169        possibility of undefined behaviour due to signed overflow. */
1170 
1171     if (lstep > 0) {
1172          if ((unsigned long)lstart - LONG_MIN < (unsigned long)lstep)
1173             goto long_range;
1174     }
1175     else {
1176         if (LONG_MAX - (unsigned long)lstart < 0UL - lstep)
1177             goto long_range;
1178     }
1179 
1180     ulen = get_len_of_range(lstart, lstop, lstep);
1181     if (ulen > (unsigned long)LONG_MAX)
1182         goto long_range;
1183 
1184     new_stop = lstart - lstep;
1185     new_start = (long)(new_stop + ulen * lstep);
1186     return fast_range_iter(new_start, new_stop, -lstep);
1187 
1188 long_range:
1189     it = PyObject_New(longrangeiterobject, &PyLongRangeIter_Type);
1190     if (it == NULL)
1191         return NULL;
1192     it->index = it->start = it->step = NULL;
1193 
1194     /* start + (len - 1) * step */
1195     it->len = range->length;
1196     Py_INCREF(it->len);
1197 
1198     diff = PyNumber_Subtract(it->len, _PyLong_One);
1199     if (!diff)
1200         goto create_failure;
1201 
1202     product = PyNumber_Multiply(diff, range->step);
1203     Py_DECREF(diff);
1204     if (!product)
1205         goto create_failure;
1206 
1207     sum = PyNumber_Add(range->start, product);
1208     Py_DECREF(product);
1209     it->start = sum;
1210     if (!it->start)
1211         goto create_failure;
1212 
1213     it->step = PyNumber_Negative(range->step);
1214     if (!it->step)
1215         goto create_failure;
1216 
1217     it->index = _PyLong_Zero;
1218     Py_INCREF(it->index);
1219     return (PyObject *)it;
1220 
1221 create_failure:
1222     Py_DECREF(it);
1223     return NULL;
1224 }
1225