Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 13 additions & 4 deletions Lib/test/test_range.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,20 +98,24 @@ def test_large_operands(self):
x = range(10**20+10, 10**20, 3)
self.assertEqual(len(x), 0)
self.assertEqual(len(list(x)), 0)
self.assertFalse(x)

x = range(10**20, 10**20+10, -3)
self.assertEqual(len(x), 0)
self.assertEqual(len(list(x)), 0)
self.assertFalse(x)

x = range(10**20+10, 10**20, -3)
self.assertEqual(len(x), 4)
self.assertEqual(len(list(x)), 4)
self.assertTrue(x)

# Now test range() with longs
self.assertEqual(list(range(-2**100)), [])
self.assertEqual(list(range(0, -2**100)), [])
self.assertEqual(list(range(0, 2**100, -1)), [])
self.assertEqual(list(range(0, 2**100, -1)), [])
for x in [range(-2**100),
range(0, -2**100),
range(0, 2**100, -1)]:
self.assertEqual(list(x), [])
self.assertFalse(x)

a = int(10 * sys.maxsize)
b = int(100 * sys.maxsize)
Expand Down Expand Up @@ -152,13 +156,15 @@ def _range_len(x):
step = x[1] - x[0]
length = 1 + ((x[-1] - x[0]) // step)
return length

a = -sys.maxsize
b = sys.maxsize
expected_len = b - a
x = range(a, b)
self.assertIn(a, x)
self.assertNotIn(b, x)
self.assertRaises(OverflowError, len, x)
self.assertTrue(x)
self.assertEqual(_range_len(x), expected_len)
self.assertEqual(x[0], a)
idx = sys.maxsize+1
Expand All @@ -176,6 +182,7 @@ def _range_len(x):
self.assertIn(a, x)
self.assertNotIn(b, x)
self.assertRaises(OverflowError, len, x)
self.assertTrue(x)
self.assertEqual(_range_len(x), expected_len)
self.assertEqual(x[0], a)
idx = sys.maxsize+1
Expand All @@ -194,6 +201,7 @@ def _range_len(x):
self.assertIn(a, x)
self.assertNotIn(b, x)
self.assertRaises(OverflowError, len, x)
self.assertTrue(x)
self.assertEqual(_range_len(x), expected_len)
self.assertEqual(x[0], a)
idx = sys.maxsize+1
Expand All @@ -212,6 +220,7 @@ def _range_len(x):
self.assertIn(a, x)
self.assertNotIn(b, x)
self.assertRaises(OverflowError, len, x)
self.assertTrue(x)
self.assertEqual(_range_len(x), expected_len)
self.assertEqual(x[0], a)
idx = sys.maxsize+1
Expand Down
3 changes: 3 additions & 0 deletions Misc/NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ Release date: XXXX-XX-XX
Core and Builtins
-----------------

- bpo-28876: ``bool(range)`` works even if ``len(range)``
raises :exc:`OverflowError`.

- bpo-29600: Fix wrapping coroutine return values in StopIteration.

- Issue #29537: Restore runtime compatibility with bytecode files generated by
Expand Down
21 changes: 20 additions & 1 deletion Objects/rangeobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -675,6 +675,25 @@ static PyMappingMethods range_as_mapping = {
(objobjargproc)0, /* mp_ass_subscript */
};

static int
range_bool(rangeobject* self)
{
return PyObject_IsTrue(self->length);
}

static PyNumberMethods range_as_number = {
0, /* nb_add */
0, /* nb_subtract */
0, /* nb_multiply */
0, /* nb_remainder */
0, /* nb_divmod */
0, /* nb_power */
0, /* nb_negative */
0, /* nb_positive */
0, /* nb_absolute */
(inquiry)range_bool, /* nb_bool */
};

static PyObject * range_iter(PyObject *seq);
static PyObject * range_reverse(PyObject *seq);

Expand Down Expand Up @@ -714,7 +733,7 @@ PyTypeObject PyRange_Type = {
0, /* tp_setattr */
0, /* tp_reserved */
(reprfunc)range_repr, /* tp_repr */
0, /* tp_as_number */
&range_as_number, /* tp_as_number */
&range_as_sequence, /* tp_as_sequence */
&range_as_mapping, /* tp_as_mapping */
(hashfunc)range_hash, /* tp_hash */
Expand Down