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