summaryrefslogtreecommitdiff
path: root/Lib/test/test_int.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/test/test_int.py')
-rw-r--r--Lib/test/test_int.py165
1 files changed, 122 insertions, 43 deletions
diff --git a/Lib/test/test_int.py b/Lib/test/test_int.py
index 671b20a584..c489510537 100644
--- a/Lib/test/test_int.py
+++ b/Lib/test/test_int.py
@@ -2,7 +2,6 @@ import sys
import unittest
from test import support
-from test.support import run_unittest
L = [
('0', 0),
@@ -74,14 +73,6 @@ class IntTestCases(unittest.TestCase):
x = -1-sys.maxsize
self.assertEqual(x >> 1, x//2)
- self.assertRaises(ValueError, int, '123\0')
- self.assertRaises(ValueError, int, '53', 40)
-
- # SF bug 1545497: embedded NULs were not detected with
- # explicit base
- self.assertRaises(ValueError, int, '123\0', 10)
- self.assertRaises(ValueError, int, '123\x00 245', 20)
-
x = int('1' * 600)
self.assertIsInstance(x, int)
@@ -226,6 +217,9 @@ class IntTestCases(unittest.TestCase):
self.assertIs(int(b'10'), 10)
self.assertIs(int(b'-1'), -1)
+ def test_no_args(self):
+ self.assertEqual(int(), 0)
+
def test_keyword_args(self):
# Test invoking int() using keyword arguments.
self.assertEqual(int(x=1.2), 1)
@@ -234,6 +228,27 @@ class IntTestCases(unittest.TestCase):
self.assertRaises(TypeError, int, base=10)
self.assertRaises(TypeError, int, base=0)
+ def test_non_numeric_input_types(self):
+ # Test possible non-numeric types for the argument x, including
+ # subclasses of the explicitly documented accepted types.
+ class CustomStr(str): pass
+ class CustomBytes(bytes): pass
+ class CustomByteArray(bytearray): pass
+
+ values = [b'100',
+ bytearray(b'100'),
+ CustomStr('100'),
+ CustomBytes(b'100'),
+ CustomByteArray(b'100')]
+
+ for x in values:
+ msg = 'x has type %s' % type(x).__name__
+ self.assertEqual(int(x), 100, msg=msg)
+ self.assertEqual(int(x, 2), 4, msg=msg)
+
+ def test_string_float(self):
+ self.assertRaises(ValueError, int, '1.2')
+
def test_intconversion(self):
# Test __int__()
class ClassicMissingMethods:
@@ -248,32 +263,7 @@ class IntTestCases(unittest.TestCase):
def __int__(self):
return 42
- class Foo1(object):
- def __int__(self):
- return 42
-
- class Foo2(int):
- def __int__(self):
- return 42
-
- class Foo3(int):
- def __int__(self):
- return self
-
- class Foo4(int):
- def __int__(self):
- return 42
-
- class Foo5(int):
- def __int__(self):
- return 42.
-
self.assertEqual(int(Foo0()), 42)
- self.assertEqual(int(Foo1()), 42)
- self.assertEqual(int(Foo2()), 42)
- self.assertEqual(int(Foo3()), 0)
- self.assertEqual(int(Foo4()), 42)
- self.assertRaises(TypeError, int, Foo5())
class Classic:
pass
@@ -290,6 +280,12 @@ class IntTestCases(unittest.TestCase):
return 42
self.assertEqual(int(JustTrunc()), 42)
+ class ExceptionalTrunc(base):
+ def __trunc__(self):
+ 1 / 0
+ with self.assertRaises(ZeroDivisionError):
+ int(ExceptionalTrunc())
+
for trunc_result_base in (object, Classic):
class Integral(trunc_result_base):
def __int__(self):
@@ -318,18 +314,101 @@ class IntTestCases(unittest.TestCase):
self.fail("Failed to raise TypeError with %s" %
((base, trunc_result_base),))
+ # Regression test for bugs.python.org/issue16060.
+ class BadInt(trunc_result_base):
+ def __int__(self):
+ return 42.0
+
+ class TruncReturnsBadInt(base):
+ def __trunc__(self):
+ return BadInt()
+
+ with self.assertRaises(TypeError):
+ int(TruncReturnsBadInt())
+
+ def test_int_subclass_with_int(self):
+ class MyInt(int):
+ def __int__(self):
+ return 42
+
+ class BadInt(int):
+ def __int__(self):
+ return 42.0
+
+ my_int = MyInt(7)
+ self.assertEqual(my_int, 7)
+ self.assertEqual(int(my_int), 42)
+
+ self.assertRaises(TypeError, int, BadInt())
+
+ def test_int_returns_int_subclass(self):
+ class BadInt:
+ def __int__(self):
+ return True
+
+ class BadInt2(int):
+ def __int__(self):
+ return True
+
+ class TruncReturnsBadInt:
+ def __trunc__(self):
+ return BadInt()
+
+ class TruncReturnsIntSubclass:
+ def __trunc__(self):
+ return True
+
+ bad_int = BadInt()
+ n = int(bad_int)
+ self.assertEqual(n, 1)
+
+ bad_int = BadInt2()
+ n = int(bad_int)
+ self.assertEqual(n, 1)
+
+ bad_int = TruncReturnsBadInt()
+ n = int(bad_int)
+ self.assertEqual(n, 1)
+
+ good_int = TruncReturnsIntSubclass()
+ n = int(good_int)
+ self.assertEqual(n, 1)
+
def test_error_message(self):
- testlist = ('\xbd', '123\xbd', ' 123 456 ')
- for s in testlist:
- try:
- int(s)
- except ValueError as e:
- self.assertIn(s.strip(), e.args[0])
- else:
- self.fail("Expected int(%r) to raise a ValueError", s)
+ def check(s, base=None):
+ with self.assertRaises(ValueError,
+ msg="int(%r, %r)" % (s, base)) as cm:
+ if base is None:
+ int(s)
+ else:
+ int(s, base)
+ self.assertEqual(cm.exception.args[0],
+ "invalid literal for int() with base %d: %r" %
+ (10 if base is None else base, s))
+
+ check('\xbd')
+ check('123\xbd')
+ check(' 123 456 ')
+
+ check('123\x00')
+ # SF bug 1545497: embedded NULs were not detected with explicit base
+ check('123\x00', 10)
+ check('123\x00 245', 20)
+ check('123\x00 245', 16)
+ check('123\x00245', 20)
+ check('123\x00245', 16)
+ # byte string with embedded NUL
+ check(b'123\x00')
+ check(b'123\x00', 10)
+ # non-UTF-8 byte string
+ check(b'123\xbd')
+ check(b'123\xbd', 10)
+ # lone surrogate in Unicode string
+ check('123\ud800')
+ check('123\ud800', 10)
def test_main():
- run_unittest(IntTestCases)
+ support.run_unittest(IntTestCases)
if __name__ == "__main__":
test_main()