Coverage Report

Created: 2025-07-04 06:49

/src/cpython/Objects/rangeobject.c
Line
Count
Source (jump to first uncovered line)
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
5.50M
{
34
    /* No step specified, use a step of 1. */
35
5.50M
    if (!step)
36
2.23M
        return PyLong_FromLong(1);
37
38
3.27M
    step = PyNumber_Index(step);
39
3.27M
    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
3.27M
    return step;
46
5.50M
}
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
6.74M
{
55
6.74M
    PyObject *length;
56
6.74M
    length = compute_range_length(start, stop, step);
57
6.74M
    if (length == NULL) {
58
0
        return NULL;
59
0
    }
60
6.74M
    rangeobject *obj = _Py_FREELIST_POP(rangeobject, ranges);
61
6.74M
    if (obj == NULL) {
62
27
        obj = PyObject_New(rangeobject, type);
63
27
        if (obj == NULL) {
64
0
            Py_DECREF(length);
65
0
            return NULL;
66
0
        }
67
27
    }
68
6.74M
    obj->start = start;
69
6.74M
    obj->stop = stop;
70
6.74M
    obj->step = step;
71
6.74M
    obj->length = length;
72
6.74M
    return obj;
73
6.74M
}
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
6.74M
{
83
6.74M
    rangeobject *obj;
84
6.74M
    PyObject *start = NULL, *stop = NULL, *step = NULL;
85
86
6.74M
    switch (num_args) {
87
3.27M
        case 3:
88
3.27M
            step = args[2];
89
3.27M
            _Py_FALLTHROUGH;
90
5.50M
        case 2:
91
            /* Convert borrowed refs to owned refs */
92
5.50M
            start = PyNumber_Index(args[0]);
93
5.50M
            if (!start) {
94
0
                return NULL;
95
0
            }
96
5.50M
            stop = PyNumber_Index(args[1]);
97
5.50M
            if (!stop) {
98
0
                Py_DECREF(start);
99
0
                return NULL;
100
0
            }
101
5.50M
            step = validate_step(step);  /* Caution, this can clear exceptions */
102
5.50M
            if (!step) {
103
0
                Py_DECREF(start);
104
0
                Py_DECREF(stop);
105
0
                return NULL;
106
0
            }
107
5.50M
            break;
108
5.50M
        case 1:
109
1.24M
            stop = PyNumber_Index(args[0]);
110
1.24M
            if (!stop) {
111
0
                return NULL;
112
0
            }
113
1.24M
            start = _PyLong_GetZero();
114
1.24M
            step = _PyLong_GetOne();
115
1.24M
            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
6.74M
    }
126
6.74M
    obj = make_range_object(type, start, stop, step);
127
6.74M
    if (obj != NULL) {
128
6.74M
        return (PyObject *) obj;
129
6.74M
    }
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
6.74M
}
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
6.74M
{
152
6.74M
    Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
153
6.74M
    if (!_PyArg_NoKwnames("range", kwnames)) {
154
0
        return NULL;
155
0
    }
156
6.74M
    return range_from_array((PyTypeObject *)rangetype, args, nargs);
157
6.74M
}
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
6.74M
{
172
6.74M
    rangeobject *r = (rangeobject*)op;
173
6.74M
    Py_DECREF(r->start);
174
6.74M
    Py_DECREF(r->stop);
175
6.74M
    Py_DECREF(r->step);
176
6.74M
    Py_DECREF(r->length);
177
6.74M
    _Py_FREELIST_FREE(ranges, r, PyObject_Free);
178
6.74M
}
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
6.74M
                PyObject *stop, PyObject *step) {
189
6.74M
    int overflow = 0;
190
191
6.74M
    long long_start = PyLong_AsLongAndOverflow(start, &overflow);
192
6.74M
    if (overflow) {
193
0
        return -2;
194
0
    }
195
6.74M
    if (long_start == -1 && PyErr_Occurred()) {
196
0
        return -1;
197
0
    }
198
6.74M
    long long_stop = PyLong_AsLongAndOverflow(stop, &overflow);
199
6.74M
    if (overflow) {
200
16
        return -2;
201
16
    }
202
6.74M
    if (long_stop == -1 && PyErr_Occurred()) {
203
0
        return -1;
204
0
    }
205
6.74M
    long long_step = PyLong_AsLongAndOverflow(step, &overflow);
206
6.74M
    if (overflow) {
207
0
        return -2;
208
0
    }
209
6.74M
    if (long_step == -1 && PyErr_Occurred()) {
210
0
        return -1;
211
0
    }
212
213
6.74M
    unsigned long ulen = get_len_of_range(long_start, long_stop, long_step);
214
6.74M
    if (ulen > (unsigned long)LONG_MAX) {
215
        /* length too large for a long */
216
0
        return -2;
217
0
    }
218
6.74M
    else {
219
6.74M
        return (long)ulen;
220
6.74M
    }
221
6.74M
}
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
6.74M
{
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
6.74M
    int cmp_result;
235
6.74M
    PyObject *lo, *hi;
236
6.74M
    PyObject *diff = NULL;
237
6.74M
    PyObject *tmp1 = NULL, *tmp2 = NULL, *result;
238
                /* holds sub-expression evaluations */
239
240
6.74M
    PyObject *zero = _PyLong_GetZero();  // borrowed reference
241
6.74M
    PyObject *one = _PyLong_GetOne();  // borrowed reference
242
243
6.74M
    assert(PyLong_Check(start));
244
6.74M
    assert(PyLong_Check(stop));
245
6.74M
    assert(PyLong_Check(step));
246
247
    /* fast path when all arguments fit into a long integer */
248
6.74M
    long len = compute_range_length_long(start, stop, step);
249
6.74M
    if (len >= 0) {
250
6.74M
        return PyLong_FromLong(len);
251
6.74M
    }
252
16
    else if (len == -1) {
253
        /* unexpected error from compute_range_length_long, we propagate to the caller */
254
0
        return NULL;
255
0
    }
256
16
    assert(len == -2);
257
258
16
    cmp_result = PyObject_RichCompareBool(step, zero, Py_GT);
259
16
    if (cmp_result == -1)
260
0
        return NULL;
261
262
16
    if (cmp_result == 1) {
263
16
        lo = start;
264
16
        hi = stop;
265
16
        Py_INCREF(step);
266
16
    } 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
16
    cmp_result = PyObject_RichCompareBool(lo, hi, Py_GE);
276
16
    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
16
    if ((tmp1 = PyNumber_Subtract(hi, lo)) == NULL)
285
0
        goto Fail;
286
287
16
    if ((diff = PyNumber_Subtract(tmp1, one)) == NULL)
288
0
        goto Fail;
289
290
16
    if ((tmp2 = PyNumber_FloorDivide(diff, step)) == NULL)
291
0
        goto Fail;
292
293
16
    if ((result = PyNumber_Add(tmp2, one)) == NULL)
294
0
        goto Fail;
295
296
16
    Py_DECREF(tmp2);
297
16
    Py_DECREF(diff);
298
16
    Py_DECREF(step);
299
16
    Py_DECREF(tmp1);
300
16
    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
16
}
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
982
{
320
982
    PyObject *incr, *result;
321
    /* PyLong equivalent to:
322
     *    return r->start + (i * r->step)
323
     */
324
982
    if (r->step == _PyLong_GetOne()) {
325
982
        result = PyNumber_Add(r->start, i);
326
982
    }
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
982
    return result;
336
982
}
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
491
{
406
491
    PySliceObject *slice = (PySliceObject *) _slice;
407
491
    rangeobject *result;
408
491
    PyObject *start = NULL, *stop = NULL, *step = NULL;
409
491
    PyObject *substart = NULL, *substop = NULL, *substep = NULL;
410
491
    int error;
411
412
491
    error = _PySlice_GetLongIndices(slice, r->length, &start, &stop, &step);
413
491
    if (error == -1)
414
0
        return NULL;
415
416
491
    substep = PyNumber_Multiply(r->step, step);
417
491
    if (substep == NULL) goto fail;
418
491
    Py_CLEAR(step);
419
420
491
    substart = compute_item(r, start);
421
491
    if (substart == NULL) goto fail;
422
491
    Py_CLEAR(start);
423
424
491
    substop = compute_item(r, stop);
425
491
    if (substop == NULL) goto fail;
426
491
    Py_CLEAR(stop);
427
428
491
    result = make_range_object(Py_TYPE(r), substart, substop, substep);
429
491
    if (result != NULL) {
430
491
        return (PyObject *) result;
431
491
    }
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
491
}
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
491
{
716
491
    rangeobject *self = (rangeobject*)op;
717
491
    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
491
    if (PySlice_Check(item)) {
727
491
        return compute_slice(self, item);
728
491
    }
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
491
}
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
751k
{
745
751k
    rangeobject *self = (rangeobject*)op;
746
751k
    return PyObject_IsTrue(self->length);
747
751k
}
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
425
{
833
425
    _PyRangeIterObject *r = (_PyRangeIterObject*)op;
834
425
    if (r->len > 0) {
835
386
        long result = r->start;
836
386
        r->start = result + r->step;
837
386
        r->len--;
838
386
        return PyLong_FromLong(result);
839
386
    }
840
39
    return NULL;
841
425
}
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
6.74M
{
904
6.74M
    _Py_FREELIST_FREE(range_iters, (_PyRangeIterObject *)self, PyObject_Free);
905
6.74M
}
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
13.4M
{
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
13.4M
    assert(step != 0);
970
13.4M
    if (step > 0 && lo < hi)
971
6.81M
        return 1UL + (hi - 1UL - lo) / step;
972
6.67M
    else if (step < 0 && lo > hi)
973
2.10M
        return 1UL + (lo - 1UL - hi) / (0UL - step);
974
4.56M
    else
975
4.56M
        return 0UL;
976
13.4M
}
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
6.74M
{
984
6.74M
    _PyRangeIterObject *it = _Py_FREELIST_POP(_PyRangeIterObject, range_iters);
985
6.74M
    if (it == NULL) {
986
18
        it = PyObject_New(_PyRangeIterObject, &PyRangeIter_Type);
987
18
        if (it == NULL) {
988
0
            return NULL;
989
0
        }
990
18
    }
991
6.74M
    assert(Py_IS_TYPE(it, &PyRangeIter_Type));
992
6.74M
    it->start = start;
993
6.74M
    it->step = step;
994
6.74M
    it->len = len;
995
6.74M
    return (PyObject *)it;
996
6.74M
}
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
    longrangeiterobject *r = (longrangeiterobject*)op;
1046
0
    PyObject *zero = _PyLong_GetZero();  // borrowed reference
1047
0
    int cmp;
1048
1049
    /* clip the value */
1050
0
    cmp = PyObject_RichCompareBool(state, zero, Py_LT);
1051
0
    if (cmp < 0)
1052
0
        return NULL;
1053
0
    if (cmp > 0) {
1054
0
        state = zero;
1055
0
    }
1056
0
    else {
1057
0
        cmp = PyObject_RichCompareBool(r->len, state, Py_LT);
1058
0
        if (cmp < 0)
1059
0
            return NULL;
1060
0
        if (cmp > 0)
1061
0
            state = r->len;
1062
0
    }
1063
0
    PyObject *product = PyNumber_Multiply(state, r->step);
1064
0
    if (product == NULL)
1065
0
        return NULL;
1066
0
    PyObject *new_start = PyNumber_Add(r->start, product);
1067
0
    Py_DECREF(product);
1068
0
    if (new_start == NULL)
1069
0
        return NULL;
1070
0
    PyObject *new_len = PyNumber_Subtract(r->len, state);
1071
0
    if (new_len == NULL) {
1072
0
        Py_DECREF(new_start);
1073
0
        return NULL;
1074
0
    }
1075
0
    PyObject *tmp = r->start;
1076
0
    r->start = new_start;
1077
0
    Py_SETREF(r->len, new_len);
1078
0
    Py_DECREF(tmp);
1079
0
    Py_RETURN_NONE;
1080
0
}
1081
1082
static PyMethodDef longrangeiter_methods[] = {
1083
    {"__length_hint__", longrangeiter_len, METH_NOARGS, length_hint_doc},
1084
    {"__reduce__", longrangeiter_reduce, METH_NOARGS, reduce_doc},
1085
    {"__setstate__", longrangeiter_setstate, METH_O, setstate_doc},
1086
    {NULL,              NULL}           /* sentinel */
1087
};
1088
1089
static void
1090
longrangeiter_dealloc(PyObject *op)
1091
16
{
1092
16
    longrangeiterobject *r = (longrangeiterobject*)op;
1093
16
    Py_XDECREF(r->start);
1094
16
    Py_XDECREF(r->step);
1095
16
    Py_XDECREF(r->len);
1096
16
    PyObject_Free(r);
1097
16
}
1098
1099
static PyObject *
1100
longrangeiter_next(PyObject *op)
1101
0
{
1102
0
    longrangeiterobject *r = (longrangeiterobject*)op;
1103
0
    if (PyObject_RichCompareBool(r->len, _PyLong_GetZero(), Py_GT) != 1)
1104
0
        return NULL;
1105
1106
0
    PyObject *new_start = PyNumber_Add(r->start, r->step);
1107
0
    if (new_start == NULL) {
1108
0
        return NULL;
1109
0
    }
1110
0
    PyObject *new_len = PyNumber_Subtract(r->len, _PyLong_GetOne());
1111
0
    if (new_len == NULL) {
1112
0
        Py_DECREF(new_start);
1113
0
        return NULL;
1114
0
    }
1115
0
    PyObject *result = r->start;
1116
0
    r->start = new_start;
1117
0
    Py_SETREF(r->len, new_len);
1118
0
    return result;
1119
0
}
1120
1121
PyTypeObject PyLongRangeIter_Type = {
1122
        PyVarObject_HEAD_INIT(&PyType_Type, 0)
1123
        "longrange_iterator",                   /* tp_name */
1124
        sizeof(longrangeiterobject),            /* tp_basicsize */
1125
        0,                                      /* tp_itemsize */
1126
        /* methods */
1127
        longrangeiter_dealloc,                  /* tp_dealloc */
1128
        0,                                      /* tp_vectorcall_offset */
1129
        0,                                      /* tp_getattr */
1130
        0,                                      /* tp_setattr */
1131
        0,                                      /* tp_as_async */
1132
        0,                                      /* tp_repr */
1133
        0,                                      /* tp_as_number */
1134
        0,                                      /* tp_as_sequence */
1135
        0,                                      /* tp_as_mapping */
1136
        0,                                      /* tp_hash */
1137
        0,                                      /* tp_call */
1138
        0,                                      /* tp_str */
1139
        PyObject_GenericGetAttr,                /* tp_getattro */
1140
        0,                                      /* tp_setattro */
1141
        0,                                      /* tp_as_buffer */
1142
        Py_TPFLAGS_DEFAULT,                     /* tp_flags */
1143
        0,                                      /* tp_doc */
1144
        0,                                      /* tp_traverse */
1145
        0,                                      /* tp_clear */
1146
        0,                                      /* tp_richcompare */
1147
        0,                                      /* tp_weaklistoffset */
1148
        PyObject_SelfIter,                      /* tp_iter */
1149
        longrangeiter_next,                     /* tp_iternext */
1150
        longrangeiter_methods,                  /* tp_methods */
1151
        0,
1152
};
1153
1154
static PyObject *
1155
range_iter(PyObject *seq)
1156
6.74M
{
1157
6.74M
    rangeobject *r = (rangeobject *)seq;
1158
6.74M
    longrangeiterobject *it;
1159
6.74M
    long lstart, lstop, lstep;
1160
6.74M
    unsigned long ulen;
1161
1162
6.74M
    assert(PyRange_Check(seq));
1163
1164
    /* If all three fields and the length convert to long, use the int
1165
     * version */
1166
6.74M
    lstart = PyLong_AsLong(r->start);
1167
6.74M
    if (lstart == -1 && PyErr_Occurred()) {
1168
0
        PyErr_Clear();
1169
0
        goto long_range;
1170
0
    }
1171
6.74M
    lstop = PyLong_AsLong(r->stop);
1172
6.74M
    if (lstop == -1 && PyErr_Occurred()) {
1173
16
        PyErr_Clear();
1174
16
        goto long_range;
1175
16
    }
1176
6.74M
    lstep = PyLong_AsLong(r->step);
1177
6.74M
    if (lstep == -1 && PyErr_Occurred()) {
1178
0
        PyErr_Clear();
1179
0
        goto long_range;
1180
0
    }
1181
6.74M
    ulen = get_len_of_range(lstart, lstop, lstep);
1182
6.74M
    if (ulen > (unsigned long)LONG_MAX) {
1183
0
        goto long_range;
1184
0
    }
1185
    /* check for potential overflow of lstart + ulen * lstep */
1186
6.74M
    if (ulen) {
1187
4.45M
        if (lstep > 0) {
1188
3.40M
            if (lstop > LONG_MAX - (lstep - 1))
1189
0
                goto long_range;
1190
3.40M
        }
1191
1.05M
        else {
1192
1.05M
            if (lstop < LONG_MIN + (-1 - lstep))
1193
0
                goto long_range;
1194
1.05M
        }
1195
4.45M
    }
1196
6.74M
    return fast_range_iter(lstart, lstop, lstep, (long)ulen);
1197
1198
16
  long_range:
1199
16
    it = PyObject_New(longrangeiterobject, &PyLongRangeIter_Type);
1200
16
    if (it == NULL)
1201
0
        return NULL;
1202
1203
16
    it->start = Py_NewRef(r->start);
1204
16
    it->step = Py_NewRef(r->step);
1205
16
    it->len = Py_NewRef(r->length);
1206
16
    return (PyObject *)it;
1207
16
}
1208
1209
static PyObject *
1210
range_reverse(PyObject *seq, PyObject *Py_UNUSED(ignored))
1211
0
{
1212
0
    rangeobject *range = (rangeobject*) seq;
1213
0
    longrangeiterobject *it;
1214
0
    PyObject *sum, *diff, *product;
1215
0
    long lstart, lstop, lstep, new_start, new_stop;
1216
0
    unsigned long ulen;
1217
1218
0
    assert(PyRange_Check(seq));
1219
1220
    /* reversed(range(start, stop, step)) can be expressed as
1221
       range(start+(n-1)*step, start-step, -step), where n is the number of
1222
       integers in the range.
1223
1224
       If each of start, stop, step, -step, start-step, and the length
1225
       of the iterator is representable as a C long, use the int
1226
       version.  This excludes some cases where the reversed range is
1227
       representable as a range_iterator, but it's good enough for
1228
       common cases and it makes the checks simple. */
1229
1230
0
    lstart = PyLong_AsLong(range->start);
1231
0
    if (lstart == -1 && PyErr_Occurred()) {
1232
0
        PyErr_Clear();
1233
0
        goto long_range;
1234
0
    }
1235
0
    lstop = PyLong_AsLong(range->stop);
1236
0
    if (lstop == -1 && PyErr_Occurred()) {
1237
0
        PyErr_Clear();
1238
0
        goto long_range;
1239
0
    }
1240
0
    lstep = PyLong_AsLong(range->step);
1241
0
    if (lstep == -1 && PyErr_Occurred()) {
1242
0
        PyErr_Clear();
1243
0
        goto long_range;
1244
0
    }
1245
    /* check for possible overflow of -lstep */
1246
0
    if (lstep == LONG_MIN)
1247
0
        goto long_range;
1248
1249
    /* check for overflow of lstart - lstep:
1250
1251
       for lstep > 0, need only check whether lstart - lstep < LONG_MIN.
1252
       for lstep < 0, need only check whether lstart - lstep > LONG_MAX
1253
1254
       Rearrange these inequalities as:
1255
1256
           lstart - LONG_MIN < lstep  (lstep > 0)
1257
           LONG_MAX - lstart < -lstep  (lstep < 0)
1258
1259
       and compute both sides as unsigned longs, to avoid the
1260
       possibility of undefined behaviour due to signed overflow. */
1261
1262
0
    if (lstep > 0) {
1263
0
         if ((unsigned long)lstart - LONG_MIN < (unsigned long)lstep)
1264
0
            goto long_range;
1265
0
    }
1266
0
    else {
1267
0
        if (LONG_MAX - (unsigned long)lstart < 0UL - lstep)
1268
0
            goto long_range;
1269
0
    }
1270
1271
0
    ulen = get_len_of_range(lstart, lstop, lstep);
1272
0
    if (ulen > (unsigned long)LONG_MAX)
1273
0
        goto long_range;
1274
1275
0
    new_stop = lstart - lstep;
1276
0
    new_start = (long)(new_stop + ulen * lstep);
1277
0
    return fast_range_iter(new_start, new_stop, -lstep, (long)ulen);
1278
1279
0
long_range:
1280
0
    it = PyObject_New(longrangeiterobject, &PyLongRangeIter_Type);
1281
0
    if (it == NULL)
1282
0
        return NULL;
1283
0
    it->start = it->step = NULL;
1284
1285
    /* start + (len - 1) * step */
1286
0
    it->len = Py_NewRef(range->length);
1287
1288
0
    diff = PyNumber_Subtract(it->len, _PyLong_GetOne());
1289
0
    if (!diff)
1290
0
        goto create_failure;
1291
1292
0
    product = PyNumber_Multiply(diff, range->step);
1293
0
    Py_DECREF(diff);
1294
0
    if (!product)
1295
0
        goto create_failure;
1296
1297
0
    sum = PyNumber_Add(range->start, product);
1298
0
    Py_DECREF(product);
1299
0
    it->start = sum;
1300
0
    if (!it->start)
1301
0
        goto create_failure;
1302
1303
0
    it->step = PyNumber_Negative(range->step);
1304
0
    if (!it->step)
1305
0
        goto create_failure;
1306
1307
0
    return (PyObject *)it;
1308
1309
0
create_failure:
1310
0
    Py_DECREF(it);
1311
0
    return NULL;
1312
0
}