Issue #1533: fix inconsistency in range function argument processing:
any non-float non-integer argument is now converted to an integer (if
possible) using its __int__ method. Previously, only small arguments
were treated this way; larger arguments (those whose __int__ was
outside the range of a C long) would produce a TypeError.
Patch by Alexander Belopolsky (with minor modifications).
diff --git a/Lib/test/test_builtin.py b/Lib/test/test_builtin.py
index 013731c..c03769d 100644
--- a/Lib/test/test_builtin.py
+++ b/Lib/test/test_builtin.py
@@ -1080,6 +1080,56 @@
self.assertRaises(OverflowError, range, -sys.maxint, sys.maxint)
self.assertRaises(OverflowError, range, 0, 2*sys.maxint)
+ bignum = 2*sys.maxint
+ smallnum = 42
+ # Old-style user-defined class with __int__ method
+ class I0:
+ def __init__(self, n):
+ self.n = int(n)
+ def __int__(self):
+ return self.n
+ self.assertEqual(range(I0(bignum), I0(bignum + 1)), [bignum])
+ self.assertEqual(range(I0(smallnum), I0(smallnum + 1)), [smallnum])
+
+ # New-style user-defined class with __int__ method
+ class I1(object):
+ def __init__(self, n):
+ self.n = int(n)
+ def __int__(self):
+ return self.n
+ self.assertEqual(range(I1(bignum), I1(bignum + 1)), [bignum])
+ self.assertEqual(range(I1(smallnum), I1(smallnum + 1)), [smallnum])
+
+ # New-style user-defined class with failing __int__ method
+ class IX(object):
+ def __int__(self):
+ raise RuntimeError
+ self.assertRaises(RuntimeError, range, IX())
+
+ # New-style user-defined class with invalid __int__ method
+ class IN(object):
+ def __int__(self):
+ return "not a number"
+ self.assertRaises(TypeError, range, IN())
+
+ # Exercise various combinations of bad arguments, to check
+ # refcounting logic
+ self.assertRaises(TypeError, range, 0.0)
+
+ self.assertRaises(TypeError, range, 0, 0.0)
+ self.assertRaises(TypeError, range, 0.0, 0)
+ self.assertRaises(TypeError, range, 0.0, 0.0)
+
+ self.assertRaises(TypeError, range, 0, 0, 1.0)
+ self.assertRaises(TypeError, range, 0, 0.0, 1)
+ self.assertRaises(TypeError, range, 0, 0.0, 1.0)
+ self.assertRaises(TypeError, range, 0.0, 0, 1)
+ self.assertRaises(TypeError, range, 0.0, 0, 1.0)
+ self.assertRaises(TypeError, range, 0.0, 0.0, 1)
+ self.assertRaises(TypeError, range, 0.0, 0.0, 1.0)
+
+
+
def test_input_and_raw_input(self):
self.write_testfile()
fp = open(TESTFN, 'r')