Skip to content

Commit 4276068

Browse files
bpo-28876: bool of large range raises OverflowError (#699) (#735)
(cherry picked from commit e46fb86)
1 parent 7cc071c commit 4276068

File tree

3 files changed

+36
-5
lines changed

3 files changed

+36
-5
lines changed

Lib/test/test_range.py

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -98,20 +98,24 @@ def test_large_operands(self):
9898
x = range(10**20+10, 10**20, 3)
9999
self.assertEqual(len(x), 0)
100100
self.assertEqual(len(list(x)), 0)
101+
self.assertFalse(x)
101102

102103
x = range(10**20, 10**20+10, -3)
103104
self.assertEqual(len(x), 0)
104105
self.assertEqual(len(list(x)), 0)
106+
self.assertFalse(x)
105107

106108
x = range(10**20+10, 10**20, -3)
107109
self.assertEqual(len(x), 4)
108110
self.assertEqual(len(list(x)), 4)
111+
self.assertTrue(x)
109112

110113
# Now test range() with longs
111-
self.assertEqual(list(range(-2**100)), [])
112-
self.assertEqual(list(range(0, -2**100)), [])
113-
self.assertEqual(list(range(0, 2**100, -1)), [])
114-
self.assertEqual(list(range(0, 2**100, -1)), [])
114+
for x in [range(-2**100),
115+
range(0, -2**100),
116+
range(0, 2**100, -1)]:
117+
self.assertEqual(list(x), [])
118+
self.assertFalse(x)
115119

116120
a = int(10 * sys.maxsize)
117121
b = int(100 * sys.maxsize)
@@ -152,13 +156,15 @@ def _range_len(x):
152156
step = x[1] - x[0]
153157
length = 1 + ((x[-1] - x[0]) // step)
154158
return length
159+
155160
a = -sys.maxsize
156161
b = sys.maxsize
157162
expected_len = b - a
158163
x = range(a, b)
159164
self.assertIn(a, x)
160165
self.assertNotIn(b, x)
161166
self.assertRaises(OverflowError, len, x)
167+
self.assertTrue(x)
162168
self.assertEqual(_range_len(x), expected_len)
163169
self.assertEqual(x[0], a)
164170
idx = sys.maxsize+1
@@ -176,6 +182,7 @@ def _range_len(x):
176182
self.assertIn(a, x)
177183
self.assertNotIn(b, x)
178184
self.assertRaises(OverflowError, len, x)
185+
self.assertTrue(x)
179186
self.assertEqual(_range_len(x), expected_len)
180187
self.assertEqual(x[0], a)
181188
idx = sys.maxsize+1
@@ -194,6 +201,7 @@ def _range_len(x):
194201
self.assertIn(a, x)
195202
self.assertNotIn(b, x)
196203
self.assertRaises(OverflowError, len, x)
204+
self.assertTrue(x)
197205
self.assertEqual(_range_len(x), expected_len)
198206
self.assertEqual(x[0], a)
199207
idx = sys.maxsize+1
@@ -212,6 +220,7 @@ def _range_len(x):
212220
self.assertIn(a, x)
213221
self.assertNotIn(b, x)
214222
self.assertRaises(OverflowError, len, x)
223+
self.assertTrue(x)
215224
self.assertEqual(_range_len(x), expected_len)
216225
self.assertEqual(x[0], a)
217226
idx = sys.maxsize+1

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ Release date: XXXX-XX-XX
1010
Core and Builtins
1111
-----------------
1212

13+
- bpo-28876: ``bool(range)`` works even if ``len(range)``
14+
raises :exc:`OverflowError`.
15+
1316
- bpo-29600: Fix wrapping coroutine return values in StopIteration.
1417

1518
- Issue #29537: Restore runtime compatibility with bytecode files generated by

Objects/rangeobject.c

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -675,6 +675,25 @@ static PyMappingMethods range_as_mapping = {
675675
(objobjargproc)0, /* mp_ass_subscript */
676676
};
677677

678+
static int
679+
range_bool(rangeobject* self)
680+
{
681+
return PyObject_IsTrue(self->length);
682+
}
683+
684+
static PyNumberMethods range_as_number = {
685+
0, /* nb_add */
686+
0, /* nb_subtract */
687+
0, /* nb_multiply */
688+
0, /* nb_remainder */
689+
0, /* nb_divmod */
690+
0, /* nb_power */
691+
0, /* nb_negative */
692+
0, /* nb_positive */
693+
0, /* nb_absolute */
694+
(inquiry)range_bool, /* nb_bool */
695+
};
696+
678697
static PyObject * range_iter(PyObject *seq);
679698
static PyObject * range_reverse(PyObject *seq);
680699

@@ -714,7 +733,7 @@ PyTypeObject PyRange_Type = {
714733
0, /* tp_setattr */
715734
0, /* tp_reserved */
716735
(reprfunc)range_repr, /* tp_repr */
717-
0, /* tp_as_number */
736+
&range_as_number, /* tp_as_number */
718737
&range_as_sequence, /* tp_as_sequence */
719738
&range_as_mapping, /* tp_as_mapping */
720739
(hashfunc)range_hash, /* tp_hash */

0 commit comments

Comments
 (0)