]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-28876: bool of large range raises OverflowError (#699) (#734)
authorSerhiy Storchaka <storchaka@gmail.com>
Mon, 20 Mar 2017 07:13:47 +0000 (09:13 +0200)
committerGitHub <noreply@github.com>
Mon, 20 Mar 2017 07:13:47 +0000 (09:13 +0200)
(cherry picked from commit e46fb8611867fa3b407a813f53137929b7cb4a10)

Lib/test/test_range.py
Misc/NEWS
Objects/rangeobject.c

index 9e11e518f61e1f59363a30ac03e01ae170d7fdd2..679759ec6d676a5083cd7950fd120ce295be16ff 100644 (file)
@@ -99,20 +99,24 @@ class RangeTest(unittest.TestCase):
         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)
@@ -153,6 +157,7 @@ class RangeTest(unittest.TestCase):
                 step = x[1] - x[0]
                 length = 1 + ((x[-1] - x[0]) // step)
             return length
+
         a = -sys.maxsize
         b = sys.maxsize
         expected_len = b - a
@@ -160,6 +165,7 @@ class RangeTest(unittest.TestCase):
         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
@@ -177,6 +183,7 @@ class RangeTest(unittest.TestCase):
         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
@@ -195,6 +202,7 @@ class RangeTest(unittest.TestCase):
         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
@@ -213,6 +221,7 @@ class RangeTest(unittest.TestCase):
         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
index 310e982d78f03ab4c02580b47e9a331f90b9e383..7e87a28145780beb3ee13b064784c6d2ebfe6dda 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -39,6 +39,9 @@ Core and Builtins
 - bpo-28893: Set correct __cause__ for errors about invalid awaitables
   returned from __aiter__ and __anext__.
 
+- bpo-28876: ``bool(range)`` works even if ``len(range)``
+  raises :exc:`OverflowError`.
+
 - bpo-29683: Fixes to memory allocation in _PyCode_SetExtra.  Patch by
   Brian Coleman.
 
index 8449fc7a24d39442c6fedffeb2c70f90bbd48bd7..8f5fc434bd49550b65393ada5d377c1af71d87ea 100644 (file)
@@ -668,6 +668,16 @@ 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 = {
+    .nb_bool = (inquiry)range_bool,
+};
+
 static PyObject * range_iter(PyObject *seq);
 static PyObject * range_reverse(PyObject *seq);
 
@@ -707,7 +717,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 */