Skip to content

Commit eb36d31

Browse files
committed
Issue python#6334: Fix buggy internal length calculation in builtin range function
1 parent eeb575f commit eb36d31

2 files changed

Lines changed: 20 additions & 9 deletions

File tree

Lib/test/test_builtin.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -924,6 +924,24 @@ def test_range(self):
924924
self.assertEqual(list(range(1, 10, 3)), [1, 4, 7])
925925
#self.assertEqual(list(range(5, -5, -3)), [5, 2, -1, -4])
926926

927+
#issue 6334: the internal stored range length was being
928+
#computed incorrectly in some cases involving large arguments.
929+
x = range(10**20, 10**20+10, 3)
930+
self.assertEqual(len(x), 4)
931+
self.assertEqual(len(list(x)), 4)
932+
933+
x = range(10**20+10, 10**20, 3)
934+
self.assertEqual(len(x), 0)
935+
self.assertEqual(len(list(x)), 0)
936+
937+
x = range(10**20, 10**20+10, -3)
938+
self.assertEqual(len(x), 0)
939+
self.assertEqual(len(list(x)), 0)
940+
941+
x = range(10**20+10, 10**20, -3)
942+
self.assertEqual(len(x), 4)
943+
self.assertEqual(len(list(x)), 4)
944+
927945
""" XXX(nnorwitz):
928946
# Now test range() with longs
929947
self.assertEqual(list(range(-2**100)), [])

Objects/rangeobject.c

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -581,7 +581,6 @@ range_iter(PyObject *seq)
581581
{
582582
rangeobject *r = (rangeobject *)seq;
583583
longrangeiterobject *it;
584-
PyObject *tmp, *len;
585584
long lstart, lstop, lstep;
586585

587586
assert(PyRange_Check(seq));
@@ -612,15 +611,9 @@ range_iter(PyObject *seq)
612611

613612
it->len = it->index = NULL;
614613

615-
/* Calculate length: (r->stop - r->start) / r->step */
616-
tmp = PyNumber_Subtract(r->stop, r->start);
617-
if (!tmp)
614+
it->len = range_length_obj(r);
615+
if (!it->len)
618616
goto create_failure;
619-
len = PyNumber_FloorDivide(tmp, r->step);
620-
Py_DECREF(tmp);
621-
if (!len)
622-
goto create_failure;
623-
it->len = len;
624617
it->index = PyLong_FromLong(0);
625618
if (!it->index)
626619
goto create_failure;

0 commit comments

Comments
 (0)