Coverage Report

Created: 2025-11-24 06:11

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