Merged revisions 80758 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk
........
r80758 | mark.dickinson | 2010-05-04 17:18:25 +0100 (Tue, 04 May 2010) | 9 lines
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 04c2216..d1d2bd0 100644
--- a/Lib/test/test_builtin.py
+++ b/Lib/test/test_builtin.py
@@ -3,7 +3,7 @@
import platform
import test.test_support, unittest
from test.test_support import fcmp, have_unicode, TESTFN, unlink, \
- run_unittest, run_with_locale
+ run_unittest, run_with_locale, check_warnings
from operator import neg
import sys, warnings, cStringIO, random, fractions, UserDict
@@ -1074,6 +1074,10 @@
# Reject floats when it would require PyLongs to represent.
# (smaller floats still accepted, but deprecated)
self.assertRaises(TypeError, range, 1e100, 1e101, 1e101)
+ with check_warnings() as w:
+ warnings.simplefilter("always")
+ self.assertEqual(range(1.0), [0])
+ self.assertEqual(w.category, DeprecationWarning)
self.assertRaises(TypeError, range, 0, "spam")
self.assertRaises(TypeError, range, 0, 42, "spam")
@@ -1081,6 +1085,54 @@
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, 1e100)
+
+ self.assertRaises(TypeError, range, 0, 1e100)
+ self.assertRaises(TypeError, range, 1e100, 0)
+ self.assertRaises(TypeError, range, 1e100, 1e100)
+
+ self.assertRaises(TypeError, range, 0, 0, 1e100)
+ self.assertRaises(TypeError, range, 0, 1e100, 1)
+ self.assertRaises(TypeError, range, 0, 1e100, 1e100)
+ self.assertRaises(TypeError, range, 1e100, 0, 1)
+ self.assertRaises(TypeError, range, 1e100, 0, 1e100)
+ self.assertRaises(TypeError, range, 1e100, 1e100, 1)
+ self.assertRaises(TypeError, range, 1e100, 1e100, 1e100)
+
def test_input_and_raw_input(self):
self.write_testfile()
fp = open(TESTFN, 'r')