1097 lines
38 KiB
Python
1097 lines
38 KiB
Python
"""
|
|
int tests from Py3.3
|
|
"""
|
|
|
|
from __future__ import (absolute_import, division,
|
|
print_function, unicode_literals)
|
|
from future.builtins import *
|
|
from future.tests.base import unittest, expectedFailurePY2
|
|
from future.utils import PY26, PY2, raise_from
|
|
|
|
import sys
|
|
import random
|
|
import array
|
|
|
|
try:
|
|
import numpy as np
|
|
except ImportError:
|
|
np = None
|
|
|
|
try:
|
|
from future.standard_library.test import support
|
|
except ImportError:
|
|
def cpython_only(f):
|
|
return f
|
|
else:
|
|
cpython_only = support.cpython_only
|
|
|
|
|
|
L = [
|
|
('0', 0),
|
|
('1', 1),
|
|
('9', 9),
|
|
('10', 10),
|
|
('99', 99),
|
|
('100', 100),
|
|
('314', 314),
|
|
(' 314', 314),
|
|
('314 ', 314),
|
|
(' \t\t 314 \t\t ', 314),
|
|
(repr(sys.maxsize), sys.maxsize),
|
|
(' 1x', ValueError),
|
|
(' 1 ', 1),
|
|
(' 1\02 ', ValueError),
|
|
('', ValueError),
|
|
(' ', ValueError),
|
|
(' \t\t ', ValueError),
|
|
("\u0200", ValueError)
|
|
]
|
|
|
|
class IntTestCases(unittest.TestCase):
|
|
|
|
def setUp(self):
|
|
self.longMessage = True
|
|
|
|
def test_isinstance_int_subclass(self):
|
|
"""
|
|
Issue #89
|
|
"""
|
|
value = int(10)
|
|
class Magic(int):
|
|
pass
|
|
self.assertTrue(isinstance(value, int))
|
|
self.assertFalse(isinstance(value, Magic))
|
|
|
|
def test_basic(self):
|
|
self.assertEqual(int(314), 314)
|
|
self.assertEqual(int(3.14), 3)
|
|
# Check that conversion from float truncates towards zero
|
|
self.assertEqual(int(-3.14), -3)
|
|
self.assertEqual(int(3.9), 3)
|
|
self.assertEqual(int(-3.9), -3)
|
|
self.assertEqual(int(3.5), 3)
|
|
self.assertEqual(int(-3.5), -3)
|
|
self.assertEqual(int("-3"), -3)
|
|
self.assertEqual(int(" -3 "), -3)
|
|
self.assertEqual(int("\N{EM SPACE}-3\N{EN SPACE}"), -3)
|
|
# Different base:
|
|
self.assertEqual(int("10",16), 16)
|
|
# Test conversion from strings and various anomalies
|
|
for s, v in L:
|
|
for sign in "", "+", "-":
|
|
for prefix in "", " ", "\t", " \t\t ":
|
|
ss = prefix + sign + s
|
|
vv = v
|
|
if sign == "-" and v is not ValueError:
|
|
vv = -v
|
|
try:
|
|
self.assertEqual(int(ss), vv)
|
|
except ValueError:
|
|
pass
|
|
|
|
s = repr(-1-sys.maxsize)
|
|
x = int(s)
|
|
self.assertEqual(x+1, -sys.maxsize)
|
|
self.assertIsInstance(x, int)
|
|
# should return int
|
|
self.assertEqual(int(s[1:]), sys.maxsize+1)
|
|
|
|
# should return int
|
|
x = int(1e100)
|
|
self.assertIsInstance(x, int)
|
|
x = int(-1e100)
|
|
self.assertIsInstance(x, int)
|
|
|
|
|
|
# SF bug 434186: 0x80000000/2 != 0x80000000>>1.
|
|
# Worked by accident in Windows release build, but failed in debug build.
|
|
# Failed in all Linux builds.
|
|
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)
|
|
|
|
|
|
self.assertRaises(TypeError, int, 1, 12)
|
|
|
|
self.assertEqual(int('0o123', 0), 83)
|
|
self.assertEqual(int('0x123', 16), 291)
|
|
|
|
# Bug 1679: "0x" is not a valid hex literal
|
|
self.assertRaises(ValueError, int, "0x", 16)
|
|
self.assertRaises(ValueError, int, "0x", 0)
|
|
|
|
self.assertRaises(ValueError, int, "0o", 8)
|
|
self.assertRaises(ValueError, int, "0o", 0)
|
|
|
|
self.assertRaises(ValueError, int, "0b", 2)
|
|
self.assertRaises(ValueError, int, "0b", 0)
|
|
|
|
# SF bug 1334662: int(string, base) wrong answers
|
|
# Various representations of 2**32 evaluated to 0
|
|
# rather than 2**32 in previous versions
|
|
|
|
self.assertEqual(int('100000000000000000000000000000000', 2), 4294967296)
|
|
self.assertEqual(int('102002022201221111211', 3), 4294967296)
|
|
self.assertEqual(int('10000000000000000', 4), 4294967296)
|
|
self.assertEqual(int('32244002423141', 5), 4294967296)
|
|
self.assertEqual(int('1550104015504', 6), 4294967296)
|
|
self.assertEqual(int('211301422354', 7), 4294967296)
|
|
self.assertEqual(int('40000000000', 8), 4294967296)
|
|
self.assertEqual(int('12068657454', 9), 4294967296)
|
|
self.assertEqual(int('4294967296', 10), 4294967296)
|
|
self.assertEqual(int('1904440554', 11), 4294967296)
|
|
self.assertEqual(int('9ba461594', 12), 4294967296)
|
|
self.assertEqual(int('535a79889', 13), 4294967296)
|
|
self.assertEqual(int('2ca5b7464', 14), 4294967296)
|
|
self.assertEqual(int('1a20dcd81', 15), 4294967296)
|
|
self.assertEqual(int('100000000', 16), 4294967296)
|
|
self.assertEqual(int('a7ffda91', 17), 4294967296)
|
|
self.assertEqual(int('704he7g4', 18), 4294967296)
|
|
self.assertEqual(int('4f5aff66', 19), 4294967296)
|
|
self.assertEqual(int('3723ai4g', 20), 4294967296)
|
|
self.assertEqual(int('281d55i4', 21), 4294967296)
|
|
self.assertEqual(int('1fj8b184', 22), 4294967296)
|
|
self.assertEqual(int('1606k7ic', 23), 4294967296)
|
|
self.assertEqual(int('mb994ag', 24), 4294967296)
|
|
self.assertEqual(int('hek2mgl', 25), 4294967296)
|
|
self.assertEqual(int('dnchbnm', 26), 4294967296)
|
|
self.assertEqual(int('b28jpdm', 27), 4294967296)
|
|
self.assertEqual(int('8pfgih4', 28), 4294967296)
|
|
self.assertEqual(int('76beigg', 29), 4294967296)
|
|
self.assertEqual(int('5qmcpqg', 30), 4294967296)
|
|
self.assertEqual(int('4q0jto4', 31), 4294967296)
|
|
self.assertEqual(int('4000000', 32), 4294967296)
|
|
self.assertEqual(int('3aokq94', 33), 4294967296)
|
|
self.assertEqual(int('2qhxjli', 34), 4294967296)
|
|
self.assertEqual(int('2br45qb', 35), 4294967296)
|
|
self.assertEqual(int('1z141z4', 36), 4294967296)
|
|
|
|
# tests with base 0
|
|
# this fails on 3.0, but in 2.x the old octal syntax is allowed
|
|
self.assertEqual(int(' 0o123 ', 0), 83)
|
|
self.assertEqual(int(' 0o123 ', 0), 83)
|
|
self.assertEqual(int('000', 0), 0)
|
|
self.assertEqual(int('0o123', 0), 83)
|
|
self.assertEqual(int('0x123', 0), 291)
|
|
self.assertEqual(int('0b100', 0), 4)
|
|
self.assertEqual(int(' 0O123 ', 0), 83)
|
|
self.assertEqual(int(' 0X123 ', 0), 291)
|
|
self.assertEqual(int(' 0B100 ', 0), 4)
|
|
|
|
# without base still base 10
|
|
self.assertEqual(int('0123'), 123)
|
|
self.assertEqual(int('0123', 10), 123)
|
|
|
|
# tests with prefix and base != 0
|
|
self.assertEqual(int('0x123', 16), 291)
|
|
self.assertEqual(int('0o123', 8), 83)
|
|
self.assertEqual(int('0b100', 2), 4)
|
|
self.assertEqual(int('0X123', 16), 291)
|
|
self.assertEqual(int('0O123', 8), 83)
|
|
self.assertEqual(int('0B100', 2), 4)
|
|
|
|
# the code has special checks for the first character after the
|
|
# type prefix
|
|
self.assertRaises(ValueError, int, '0b2', 2)
|
|
self.assertRaises(ValueError, int, '0b02', 2)
|
|
self.assertRaises(ValueError, int, '0B2', 2)
|
|
self.assertRaises(ValueError, int, '0B02', 2)
|
|
self.assertRaises(ValueError, int, '0o8', 8)
|
|
self.assertRaises(ValueError, int, '0o08', 8)
|
|
self.assertRaises(ValueError, int, '0O8', 8)
|
|
self.assertRaises(ValueError, int, '0O08', 8)
|
|
self.assertRaises(ValueError, int, '0xg', 16)
|
|
self.assertRaises(ValueError, int, '0x0g', 16)
|
|
self.assertRaises(ValueError, int, '0Xg', 16)
|
|
self.assertRaises(ValueError, int, '0X0g', 16)
|
|
|
|
# SF bug 1334662: int(string, base) wrong answers
|
|
# Checks for proper evaluation of 2**32 + 1
|
|
self.assertEqual(int('100000000000000000000000000000001', 2), 4294967297)
|
|
self.assertEqual(int('102002022201221111212', 3), 4294967297)
|
|
self.assertEqual(int('10000000000000001', 4), 4294967297)
|
|
self.assertEqual(int('32244002423142', 5), 4294967297)
|
|
self.assertEqual(int('1550104015505', 6), 4294967297)
|
|
self.assertEqual(int('211301422355', 7), 4294967297)
|
|
self.assertEqual(int('40000000001', 8), 4294967297)
|
|
self.assertEqual(int('12068657455', 9), 4294967297)
|
|
self.assertEqual(int('4294967297', 10), 4294967297)
|
|
self.assertEqual(int('1904440555', 11), 4294967297)
|
|
self.assertEqual(int('9ba461595', 12), 4294967297)
|
|
self.assertEqual(int('535a7988a', 13), 4294967297)
|
|
self.assertEqual(int('2ca5b7465', 14), 4294967297)
|
|
self.assertEqual(int('1a20dcd82', 15), 4294967297)
|
|
self.assertEqual(int('100000001', 16), 4294967297)
|
|
self.assertEqual(int('a7ffda92', 17), 4294967297)
|
|
self.assertEqual(int('704he7g5', 18), 4294967297)
|
|
self.assertEqual(int('4f5aff67', 19), 4294967297)
|
|
self.assertEqual(int('3723ai4h', 20), 4294967297)
|
|
self.assertEqual(int('281d55i5', 21), 4294967297)
|
|
self.assertEqual(int('1fj8b185', 22), 4294967297)
|
|
self.assertEqual(int('1606k7id', 23), 4294967297)
|
|
self.assertEqual(int('mb994ah', 24), 4294967297)
|
|
self.assertEqual(int('hek2mgm', 25), 4294967297)
|
|
self.assertEqual(int('dnchbnn', 26), 4294967297)
|
|
self.assertEqual(int('b28jpdn', 27), 4294967297)
|
|
self.assertEqual(int('8pfgih5', 28), 4294967297)
|
|
self.assertEqual(int('76beigh', 29), 4294967297)
|
|
self.assertEqual(int('5qmcpqh', 30), 4294967297)
|
|
self.assertEqual(int('4q0jto5', 31), 4294967297)
|
|
self.assertEqual(int('4000001', 32), 4294967297)
|
|
self.assertEqual(int('3aokq95', 33), 4294967297)
|
|
self.assertEqual(int('2qhxjlj', 34), 4294967297)
|
|
self.assertEqual(int('2br45qc', 35), 4294967297)
|
|
self.assertEqual(int('1z141z5', 36), 4294967297)
|
|
|
|
@expectedFailurePY2 # fails on Py2
|
|
@cpython_only
|
|
def test_small_ints(self):
|
|
# Bug #3236: Return small longs from PyLong_FromString
|
|
self.assertIs(int('10'), 10)
|
|
self.assertIs(int('-1'), -1)
|
|
self.assertIs(int(b'10'), 10)
|
|
self.assertIs(int(b'-1'), -1)
|
|
|
|
def test_no_args(self):
|
|
self.assertEqual(int(), 0)
|
|
|
|
@unittest.skipIf(sys.version_info >= (3, 7),
|
|
"The first parameter must be positional with Python >= 3.7"
|
|
)
|
|
def test_x_keyword_arg(self):
|
|
# Test invoking int() using keyword arguments.
|
|
self.assertEqual(int(x=1.2), 1)
|
|
self.assertEqual(int(x='100', base=2), 4)
|
|
|
|
def text_base_keyword_arg(self):
|
|
self.assertEqual(int('100', base=2), 4)
|
|
|
|
def test_newint_plus_float(self):
|
|
minutes = int(100)
|
|
second = 0.0
|
|
seconds = minutes*60 + second
|
|
self.assertEqual(seconds, 6000)
|
|
self.assertTrue(isinstance(seconds, float))
|
|
|
|
@expectedFailurePY2
|
|
def test_keyword_args_2(self):
|
|
# newint causes these to fail:
|
|
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_newint_of_newstr(self):
|
|
a = str(u'123')
|
|
b = int(a)
|
|
self.assertEqual(b, 123)
|
|
self.assertTrue(isinstance(b, int))
|
|
|
|
def test_string_float(self):
|
|
self.assertRaises(ValueError, int, '1.2')
|
|
|
|
def test_intconversion(self):
|
|
# Test __int__()
|
|
class ClassicMissingMethods:
|
|
pass
|
|
# The following raises an AttributeError (for '__trunc__') on Py2
|
|
# but a TypeError on Py3 (which uses new-style classes).
|
|
# Perhaps nothing is to be done but avoiding old-style classes!
|
|
# ...
|
|
# self.assertRaises(TypeError, int, ClassicMissingMethods())
|
|
|
|
class MissingMethods(object):
|
|
pass
|
|
self.assertRaises(TypeError, int, MissingMethods())
|
|
|
|
class Foo0:
|
|
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.real
|
|
|
|
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
|
|
for base in (object, Classic):
|
|
class IntOverridesTrunc(base):
|
|
def __int__(self):
|
|
return 42
|
|
def __trunc__(self):
|
|
return -12
|
|
self.assertEqual(int(IntOverridesTrunc()), 42)
|
|
|
|
class JustTrunc(base):
|
|
def __trunc__(self):
|
|
return 42
|
|
# This fails on Python 2.x:
|
|
# if not PY26:
|
|
# self.assertEqual(int(JustTrunc()), 42)
|
|
|
|
for trunc_result_base in (object, Classic):
|
|
class Integral(trunc_result_base):
|
|
def __int__(self):
|
|
return 42
|
|
|
|
class TruncReturnsNonInt(base):
|
|
def __trunc__(self):
|
|
return Integral()
|
|
# Fails on Python 2.6:
|
|
# self.assertEqual(int(TruncReturnsNonInt()), 42)
|
|
|
|
class NonIntegral(trunc_result_base):
|
|
def __trunc__(self):
|
|
# Check that we avoid infinite recursion.
|
|
return NonIntegral()
|
|
|
|
class TruncReturnsNonIntegral(base):
|
|
def __trunc__(self):
|
|
return NonIntegral()
|
|
try:
|
|
int(TruncReturnsNonIntegral())
|
|
except TypeError as e:
|
|
# self.assertEqual(str(e),
|
|
# "__trunc__ returned non-Integral"
|
|
# " (type NonIntegral)")
|
|
pass
|
|
else:
|
|
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())
|
|
|
|
####################################################################
|
|
# future-specific tests are below:
|
|
####################################################################
|
|
|
|
# Exception messages in Py2 are 8-bit strings. The following fails,
|
|
# even if the testlist strings are wrapped in str() calls...
|
|
@expectedFailurePY2
|
|
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 test_bytes_mul(self):
|
|
self.assertEqual(b'\x00' * int(5), b'\x00' * 5)
|
|
self.assertEqual(bytes(b'\x00') * int(5), bytes(b'\x00') * 5)
|
|
|
|
def test_str_mul(self):
|
|
self.assertEqual(u'\x00' * int(5), u'\x00' * 5)
|
|
self.assertEqual(str(u'\x00') * int(5), str(u'\x00') * 5)
|
|
|
|
def test_int_bytes(self):
|
|
self.assertEqual(int(b'a\r\n', 16), 10)
|
|
self.assertEqual(int(bytes(b'a\r\n'), 16), 10)
|
|
|
|
def test_divmod(self):
|
|
"""
|
|
Test int.__divmod__
|
|
"""
|
|
vals = [10**i for i in range(0, 20)]
|
|
for i in range(200):
|
|
x = random.choice(vals)
|
|
y = random.choice(vals)
|
|
assert divmod(int(x), int(y)) == divmod(x, y)
|
|
assert divmod(int(-x), int(y)) == divmod(-x, y)
|
|
assert divmod(int(x), int(-y)) == divmod(x, -y)
|
|
assert divmod(int(-x), int(-y)) == divmod(-x, -y)
|
|
|
|
assert divmod(int(x), float(y)) == divmod(x, float(y))
|
|
assert divmod(int(-x), float(y)) == divmod(-x, float(y))
|
|
assert divmod(int(x), float(-y)) == divmod(x, float(-y))
|
|
assert divmod(int(-x), float(-y)) == divmod(-x, float(-y))
|
|
|
|
def _frange(x, y, step):
|
|
_x = x ; i = 0
|
|
while _x < y:
|
|
yield _x
|
|
i += 1 ; _x = x + i * step
|
|
|
|
for i in range(20):
|
|
for d in _frange(0.005, 5.0, 0.005):
|
|
self.assertEqual(divmod(int(i), d), divmod(i, d), msg='i={0}; d={1}'.format(i, d))
|
|
self.assertEqual(divmod(int(-i), d), divmod(-i, d), msg='i={0}; d={1}'.format(i, d))
|
|
self.assertEqual(divmod(int(i), -d), divmod(i, -d), msg='i={0}; d={1}'.format(i, d))
|
|
self.assertEqual(divmod(int(-i), -d), divmod(-i, -d), msg='i={0}; d={1}'.format(i, d))
|
|
|
|
def test_div(self):
|
|
"""
|
|
Issue #38
|
|
"""
|
|
a = int(3)
|
|
self.assertEqual(a / 5., 0.6)
|
|
self.assertEqual(a / 5, 0.6) # the __future__.division import is in
|
|
# effect
|
|
|
|
def test_truediv(self):
|
|
"""
|
|
Test int.__truediv__ and friends (rtruediv, itruediv)
|
|
"""
|
|
a = int(3)
|
|
self.assertEqual(a / 2, 1.5) # since "from __future__ import division"
|
|
# is in effect
|
|
self.assertEqual(type(a / 2), float)
|
|
|
|
b = int(2)
|
|
self.assertEqual(a / b, 1.5) # since "from __future__ import division"
|
|
# is in effect
|
|
self.assertEqual(type(a / b), float)
|
|
|
|
c = int(3) / b
|
|
self.assertEqual(c, 1.5)
|
|
self.assertTrue(isinstance(c, float))
|
|
|
|
d = int(5)
|
|
d /= 5
|
|
self.assertEqual(d, 1.0)
|
|
self.assertTrue(isinstance(d, float))
|
|
|
|
e = int(10)
|
|
f = int(20)
|
|
e /= f
|
|
self.assertEqual(e, 0.5)
|
|
self.assertTrue(isinstance(e, float))
|
|
|
|
|
|
def test_idiv(self):
|
|
a = int(3)
|
|
a /= 2
|
|
self.assertEqual(a, 1.5)
|
|
self.assertTrue(isinstance(a, float))
|
|
b = int(10)
|
|
b /= 2
|
|
self.assertEqual(b, 5.0)
|
|
self.assertTrue(isinstance(b, float))
|
|
c = int(-3)
|
|
c /= 2.0
|
|
self.assertEqual(c, -1.5)
|
|
self.assertTrue(isinstance(c, float))
|
|
|
|
def test_floordiv(self):
|
|
a = int(3)
|
|
self.assertEqual(a // 2, 1)
|
|
self.assertEqual(type(a // 2), int) # i.e. another newint
|
|
self.assertTrue(isinstance(a // 2, int))
|
|
|
|
b = int(2)
|
|
self.assertEqual(a // b, 1)
|
|
self.assertEqual(type(a // b), int) # i.e. another newint
|
|
self.assertTrue(isinstance(a // b, int))
|
|
|
|
c = 3 // b
|
|
self.assertEqual(c, 1)
|
|
self.assertEqual(type(c), int) # i.e. another newint
|
|
self.assertTrue(isinstance(c, int))
|
|
|
|
d = int(5)
|
|
d //= 5
|
|
self.assertEqual(d, 1)
|
|
self.assertEqual(type(d), int) # i.e. another newint
|
|
self.assertTrue(isinstance(d, int))
|
|
|
|
e = int(10)
|
|
f = int(20)
|
|
e //= f
|
|
self.assertEqual(e, 0)
|
|
self.assertEqual(type(e), int) # i.e. another newint
|
|
self.assertTrue(isinstance(e, int))
|
|
|
|
|
|
def test_div(self):
|
|
"""
|
|
Issue #38
|
|
"""
|
|
a = int(3)
|
|
self.assertEqual(a / 5., 0.6)
|
|
self.assertEqual(a / 5, 0.6) # the __future__.division import is in
|
|
# effect
|
|
|
|
def test_truediv(self):
|
|
"""
|
|
Test int.__truediv__ and friends (rtruediv, itruediv)
|
|
"""
|
|
a = int(3)
|
|
self.assertEqual(a / 2, 1.5) # since "from __future__ import division"
|
|
# is in effect
|
|
self.assertEqual(type(a / 2), float)
|
|
|
|
b = int(2)
|
|
self.assertEqual(a / b, 1.5) # since "from __future__ import division"
|
|
# is in effect
|
|
self.assertEqual(type(a / b), float)
|
|
|
|
c = int(3) / b
|
|
self.assertEqual(c, 1.5)
|
|
self.assertTrue(isinstance(c, float))
|
|
|
|
d = int(5)
|
|
d /= 5
|
|
self.assertEqual(d, 1.0)
|
|
self.assertTrue(isinstance(d, float))
|
|
|
|
e = int(10)
|
|
f = int(20)
|
|
e /= f
|
|
self.assertEqual(e, 0.5)
|
|
self.assertTrue(isinstance(e, float))
|
|
|
|
|
|
def test_idiv(self):
|
|
a = int(3)
|
|
a /= 2
|
|
self.assertEqual(a, 1.5)
|
|
self.assertTrue(isinstance(a, float))
|
|
b = int(10)
|
|
b /= 2
|
|
self.assertEqual(b, 5.0)
|
|
self.assertTrue(isinstance(b, float))
|
|
c = int(-3)
|
|
c /= 2.0
|
|
self.assertEqual(c, -1.5)
|
|
self.assertTrue(isinstance(c, float))
|
|
|
|
|
|
def test_floordiv(self):
|
|
a = int(3)
|
|
self.assertEqual(a // 2, 1)
|
|
self.assertEqual(type(a // 2), int) # i.e. another newint
|
|
self.assertTrue(isinstance(a // 2, int))
|
|
|
|
b = int(2)
|
|
self.assertEqual(a // b, 1)
|
|
self.assertEqual(type(a // b), int) # i.e. another newint
|
|
self.assertTrue(isinstance(a // b, int))
|
|
|
|
c = 3 // b
|
|
self.assertEqual(c, 1)
|
|
self.assertEqual(type(c), int) # i.e. another newint
|
|
self.assertTrue(isinstance(c, int))
|
|
|
|
d = int(5)
|
|
d //= 5
|
|
self.assertEqual(d, 1)
|
|
self.assertEqual(type(d), int) # i.e. another newint
|
|
self.assertTrue(isinstance(d, int))
|
|
|
|
e = int(10)
|
|
f = int(20)
|
|
e //= f
|
|
self.assertEqual(e, 0)
|
|
self.assertEqual(type(e), int) # i.e. another newint
|
|
self.assertTrue(isinstance(e, int))
|
|
|
|
@unittest.skipIf(np is None, "test requires NumPy")
|
|
@unittest.expectedFailure
|
|
def test_numpy_cast_as_long_and_newint(self):
|
|
"""
|
|
NumPy currently doesn't like subclasses of ``long``. This should be fixed.
|
|
"""
|
|
class longsubclass(long):
|
|
pass
|
|
|
|
a = np.arange(10**3, dtype=np.float64).reshape(10, 100)
|
|
b = a.astype(longsubclass)
|
|
c = a.astype(int)
|
|
print(b.dtype)
|
|
assert b.dtype == np.int64 == c.dtype
|
|
|
|
def test_upcasting_to_floats(self):
|
|
"""
|
|
Integers should automatically be upcasted to floats for arithmetic
|
|
operations.
|
|
"""
|
|
a = int(3)
|
|
|
|
# Addition with floats.
|
|
self.assertEqual(a + 0.5, 3.5)
|
|
self.assertEqual(0.5 + a, 3.5)
|
|
self.assertTrue(isinstance(a + 0.5, float))
|
|
self.assertTrue(isinstance(0.5 + a, float))
|
|
|
|
# Subtraction with floats.
|
|
self.assertEqual(a - 0.5, 2.5)
|
|
self.assertEqual(0.5 - a, -2.5)
|
|
self.assertTrue(isinstance(a - 0.5, float))
|
|
self.assertTrue(isinstance(0.5 - a, float))
|
|
|
|
# Multiplication with floats.
|
|
self.assertEqual(a * 0.5, 1.5)
|
|
self.assertEqual(0.5 * a, 1.5)
|
|
self.assertTrue(isinstance(a * 0.5, float))
|
|
self.assertTrue(isinstance(0.5 * a, float))
|
|
|
|
# Division with floats.
|
|
self.assertEqual(a / 0.5, 6.0)
|
|
self.assertEqual(0.5 / a, 0.5 / 3.0)
|
|
self.assertTrue(isinstance(a / 0.5, float))
|
|
self.assertTrue(isinstance(0.5 / a, float))
|
|
|
|
# Modulo with floats.
|
|
self.assertEqual(a % 0.5, 0.0)
|
|
self.assertEqual(0.5 % a, 0.5)
|
|
self.assertTrue(isinstance(a % 0.5, float))
|
|
self.assertTrue(isinstance(0.5 % a, float))
|
|
|
|
# Power with floats.
|
|
self.assertEqual(1.0 ** a, 1.0)
|
|
self.assertTrue(isinstance(1.0 ** a, float))
|
|
|
|
self.assertEqual(a ** 1.0, a)
|
|
self.assertTrue(isinstance(a ** 1.0, float))
|
|
|
|
def test_upcasting_to_complex(self):
|
|
"""
|
|
Integers should automatically be upcasted to complex numbers for
|
|
arithmetic operations.
|
|
|
|
Python 3 cannot mod complex numbers so this does not have to be
|
|
supported here.
|
|
"""
|
|
a = int(3)
|
|
|
|
# Addition with complex.
|
|
self.assertEqual(a + 0.5j, 3.0 + 0.5j)
|
|
self.assertEqual(0.5j + a, 3.0 + 0.5j)
|
|
self.assertTrue(isinstance(a + 0.5j, complex))
|
|
self.assertTrue(isinstance(0.5j + a, complex))
|
|
|
|
# Subtraction with complex.
|
|
self.assertEqual(a - 0.5j, 3.0 - 0.5j)
|
|
self.assertEqual(0.5j - a, -3.0 + 0.5j)
|
|
self.assertTrue(isinstance(a - 0.5j, complex))
|
|
self.assertTrue(isinstance(0.5j - a, complex))
|
|
|
|
# Multiplication with complex.
|
|
self.assertEqual(a * 0.5j, 1.5j)
|
|
self.assertEqual(0.5j * a, 1.5j)
|
|
self.assertTrue(isinstance(a * 0.5j, complex))
|
|
self.assertTrue(isinstance(0.5j * a, complex))
|
|
|
|
# Division with complex.
|
|
self.assertEqual(a / 0.5j, -6.0j)
|
|
self.assertEqual(0.5j / a, (0.5 / 3.0) * 1j)
|
|
self.assertTrue(isinstance(a / 0.5j, complex))
|
|
self.assertTrue(isinstance(0.5j / a, complex))
|
|
|
|
# Power with floats.
|
|
self.assertEqual(5.0j ** int(1), 5.0j)
|
|
self.assertTrue(isinstance(5.0j ** int(1), complex))
|
|
|
|
self.assertEqual(a ** 1.0j, 3.0 ** 1.0j)
|
|
self.assertTrue(isinstance(a ** 1.0j, complex))
|
|
|
|
def test_more_arithmetics(self):
|
|
"""
|
|
More arithmetic tests to improve test coverage.
|
|
"""
|
|
a = int(3)
|
|
b = int(5)
|
|
c = int(-5)
|
|
|
|
self.assertEqual(b - a, 2)
|
|
self.assertTrue(isinstance(b - a, int))
|
|
|
|
self.assertEqual(a * b, 15)
|
|
self.assertTrue(isinstance(a * b, int))
|
|
|
|
self.assertEqual(b % a, 2)
|
|
self.assertTrue(isinstance(b % a, int))
|
|
|
|
self.assertEqual(a ** b, 243)
|
|
self.assertTrue(isinstance(a ** b, int))
|
|
|
|
self.assertEqual(abs(c), 5)
|
|
self.assertEqual(abs(c), b)
|
|
self.assertTrue(isinstance(abs(c), int))
|
|
|
|
def test_bitwise_operations(self):
|
|
"""
|
|
Tests bitwise operations.
|
|
"""
|
|
a = int(3)
|
|
b = int(1)
|
|
|
|
self.assertEqual(a >> b, 1)
|
|
self.assertEqual(a >> 1, 1)
|
|
self.assertTrue(isinstance(a >> b, int))
|
|
self.assertTrue(isinstance(a >> 1, int))
|
|
|
|
self.assertEqual(a << b, 6)
|
|
self.assertEqual(a << 1, 6)
|
|
self.assertTrue(isinstance(a << b, int))
|
|
self.assertTrue(isinstance(a << 1, int))
|
|
|
|
self.assertEqual(a & b, 1)
|
|
self.assertEqual(a & 1, 1)
|
|
self.assertTrue(isinstance(a & b, int))
|
|
self.assertTrue(isinstance(a & 1, int))
|
|
|
|
self.assertEqual(a | b, 3)
|
|
self.assertEqual(a | 1, 3)
|
|
self.assertTrue(isinstance(a | b, int))
|
|
self.assertTrue(isinstance(a | 1, int))
|
|
|
|
self.assertEqual(a ^ b, 2)
|
|
self.assertEqual(a ^ 1, 2)
|
|
self.assertTrue(isinstance(a ^ b, int))
|
|
self.assertTrue(isinstance(a ^ 1, int))
|
|
|
|
self.assertEqual(~a, -4)
|
|
self.assertTrue(isinstance(~a, int))
|
|
|
|
def test_unary_operators(self):
|
|
a = int(3)
|
|
b = int(-3)
|
|
|
|
self.assertEqual(+a, a)
|
|
self.assertEqual(+a, 3)
|
|
self.assertEqual(+b, b)
|
|
self.assertEqual(+b, -3)
|
|
self.assertTrue(isinstance(+a, int))
|
|
|
|
self.assertEqual(-a, b)
|
|
self.assertEqual(-a, -3)
|
|
self.assertEqual(-b, a)
|
|
self.assertEqual(-b, 3)
|
|
self.assertTrue(isinstance(-a, int))
|
|
|
|
def test_to_bytes(self):
|
|
def check(tests, byteorder, signed=False):
|
|
for test, expected in tests.items():
|
|
try:
|
|
self.assertEqual(
|
|
int(test).to_bytes(len(expected), byteorder, signed=signed),
|
|
expected)
|
|
except Exception as err:
|
|
raise_from(AssertionError(
|
|
"failed to convert {0} with byteorder={1} and signed={2}"
|
|
.format(test, byteorder, signed)), err)
|
|
|
|
# Convert integers to signed big-endian byte arrays.
|
|
tests1 = {
|
|
0: bytes(b'\x00'),
|
|
1: bytes(b'\x01'),
|
|
-1: bytes(b'\xff'),
|
|
-127: bytes(b'\x81'),
|
|
-128: bytes(b'\x80'),
|
|
-129: bytes(b'\xff\x7f'),
|
|
127: bytes(b'\x7f'),
|
|
129: bytes(b'\x00\x81'),
|
|
-255: bytes(b'\xff\x01'),
|
|
-256: bytes(b'\xff\x00'),
|
|
255: bytes(b'\x00\xff'),
|
|
256: bytes(b'\x01\x00'),
|
|
32767: bytes(b'\x7f\xff'),
|
|
-32768: bytes(b'\xff\x80\x00'),
|
|
65535: bytes(b'\x00\xff\xff'),
|
|
-65536: bytes(b'\xff\x00\x00'),
|
|
-8388608: bytes(b'\x80\x00\x00')
|
|
}
|
|
check(tests1, 'big', signed=True)
|
|
|
|
# Convert integers to signed little-endian byte arrays.
|
|
tests2 = {
|
|
0: bytes(b'\x00'),
|
|
1: bytes(b'\x01'),
|
|
-1: bytes(b'\xff'),
|
|
-127: bytes(b'\x81'),
|
|
-128: bytes(b'\x80'),
|
|
-129: bytes(b'\x7f\xff'),
|
|
127: bytes(b'\x7f'),
|
|
129: bytes(b'\x81\x00'),
|
|
-255: bytes(b'\x01\xff'),
|
|
-256: bytes(b'\x00\xff'),
|
|
255: bytes(b'\xff\x00'),
|
|
256: bytes(b'\x00\x01'),
|
|
32767: bytes(b'\xff\x7f'),
|
|
-32768: bytes(b'\x00\x80'),
|
|
65535: bytes(b'\xff\xff\x00'),
|
|
-65536: bytes(b'\x00\x00\xff'),
|
|
-8388608: bytes(b'\x00\x00\x80')
|
|
}
|
|
check(tests2, 'little', signed=True)
|
|
|
|
# Convert integers to unsigned big-endian byte arrays.
|
|
tests3 = {
|
|
0: bytes(b'\x00'),
|
|
1: bytes(b'\x01'),
|
|
127: bytes(b'\x7f'),
|
|
128: bytes(b'\x80'),
|
|
255: bytes(b'\xff'),
|
|
256: bytes(b'\x01\x00'),
|
|
32767: bytes(b'\x7f\xff'),
|
|
32768: bytes(b'\x80\x00'),
|
|
65535: bytes(b'\xff\xff'),
|
|
65536: bytes(b'\x01\x00\x00')
|
|
}
|
|
check(tests3, 'big', signed=False)
|
|
|
|
# Convert integers to unsigned little-endian byte arrays.
|
|
tests4 = {
|
|
0: bytes(b'\x00'),
|
|
1: bytes(b'\x01'),
|
|
127: bytes(b'\x7f'),
|
|
128: bytes(b'\x80'),
|
|
255: bytes(b'\xff'),
|
|
256: bytes(b'\x00\x01'),
|
|
32767: bytes(b'\xff\x7f'),
|
|
32768: bytes(b'\x00\x80'),
|
|
65535: bytes(b'\xff\xff'),
|
|
65536: bytes(b'\x00\x00\x01')
|
|
}
|
|
check(tests4, 'little', signed=False)
|
|
|
|
self.assertRaises(OverflowError, int(256).to_bytes, 1, 'big', signed=False)
|
|
self.assertRaises(OverflowError, int(256).to_bytes, 1, 'big', signed=True)
|
|
self.assertRaises(OverflowError, int(256).to_bytes, 1, 'little', signed=False)
|
|
self.assertRaises(OverflowError, int(256).to_bytes, 1, 'little', signed=True)
|
|
self.assertRaises(OverflowError, int(-1).to_bytes, 2, 'big', signed=False),
|
|
self.assertRaises(OverflowError, int(-1).to_bytes, 2, 'little', signed=False)
|
|
self.assertEqual(int(0).to_bytes(0, 'big'), b'')
|
|
self.assertEqual(int(1).to_bytes(5, 'big'), b'\x00\x00\x00\x00\x01')
|
|
self.assertEqual(int(0).to_bytes(5, 'big'), b'\x00\x00\x00\x00\x00')
|
|
self.assertEqual(int(-1).to_bytes(5, 'big', signed=True),
|
|
bytes(b'\xff\xff\xff\xff\xff'))
|
|
self.assertRaises(OverflowError, int(1).to_bytes, 0, 'big')
|
|
|
|
def test_from_bytes(self):
|
|
def check(tests, byteorder, signed=False):
|
|
for test, expected in tests.items():
|
|
try:
|
|
self.assertEqual(
|
|
int.from_bytes(test, byteorder, signed=signed),
|
|
int(expected))
|
|
except Exception as err:
|
|
raise_from(AssertionError(
|
|
"failed to convert {0} with byteorder={1!r} and signed={2}"
|
|
.format(test, byteorder, signed)), err)
|
|
|
|
# Convert signed big-endian byte arrays to integers.
|
|
tests1 = {
|
|
bytes(b''): 0,
|
|
bytes(b'\x00'): 0,
|
|
bytes(b'\x00\x00'): 0,
|
|
bytes(b'\x01'): 1,
|
|
bytes(b'\x00\x01'): 1,
|
|
bytes(b'\xff'): -1,
|
|
bytes(b'\xff\xff'): -1,
|
|
bytes(b'\x81'): -127,
|
|
bytes(b'\x80'): -128,
|
|
bytes(b'\xff\x7f'): -129,
|
|
bytes(b'\x7f'): 127,
|
|
bytes(b'\x00\x81'): 129,
|
|
bytes(b'\xff\x01'): -255,
|
|
bytes(b'\xff\x00'): -256,
|
|
bytes(b'\x00\xff'): 255,
|
|
bytes(b'\x01\x00'): 256,
|
|
bytes(b'\x7f\xff'): 32767,
|
|
bytes(b'\x80\x00'): -32768,
|
|
bytes(b'\x00\xff\xff'): 65535,
|
|
bytes(b'\xff\x00\x00'): -65536,
|
|
bytes(b'\x80\x00\x00'): -8388608
|
|
}
|
|
# check(tests1, 'big', signed=True)
|
|
|
|
# Convert signed little-endian byte arrays to integers.
|
|
tests2 = {
|
|
bytes(b''): 0,
|
|
bytes(b'\x00'): 0,
|
|
bytes(b'\x00\x00'): 0,
|
|
bytes(b'\x01'): 1,
|
|
bytes(b'\x00\x01'): 256,
|
|
bytes(b'\xff'): -1,
|
|
bytes(b'\xff\xff'): -1,
|
|
bytes(b'\x81'): -127,
|
|
bytes(b'\x80'): -128,
|
|
bytes(b'\x7f\xff'): -129,
|
|
bytes(b'\x7f'): 127,
|
|
bytes(b'\x81\x00'): 129,
|
|
bytes(b'\x01\xff'): -255,
|
|
bytes(b'\x00\xff'): -256,
|
|
bytes(b'\xff\x00'): 255,
|
|
bytes(b'\x00\x01'): 256,
|
|
bytes(b'\xff\x7f'): 32767,
|
|
bytes(b'\x00\x80'): -32768,
|
|
bytes(b'\xff\xff\x00'): 65535,
|
|
bytes(b'\x00\x00\xff'): -65536,
|
|
bytes(b'\x00\x00\x80'): -8388608
|
|
}
|
|
# check(tests2, 'little', signed=True)
|
|
|
|
# Convert unsigned big-endian byte arrays to integers.
|
|
tests3 = {
|
|
bytes(b''): 0,
|
|
bytes(b'\x00'): 0,
|
|
bytes(b'\x01'): 1,
|
|
bytes(b'\x7f'): 127,
|
|
bytes(b'\x80'): 128,
|
|
bytes(b'\xff'): 255,
|
|
bytes(b'\x01\x00'): 256,
|
|
bytes(b'\x7f\xff'): 32767,
|
|
bytes(b'\x80\x00'): 32768,
|
|
bytes(b'\xff\xff'): 65535,
|
|
bytes(b'\x01\x00\x00'): 65536,
|
|
}
|
|
check(tests3, 'big', signed=False)
|
|
|
|
# Convert integers to unsigned little-endian byte arrays.
|
|
tests4 = {
|
|
bytes(b''): 0,
|
|
bytes(b'\x00'): 0,
|
|
bytes(b'\x01'): 1,
|
|
bytes(b'\x7f'): 127,
|
|
bytes(b'\x80'): 128,
|
|
bytes(b'\xff'): 255,
|
|
bytes(b'\x00\x01'): 256,
|
|
bytes(b'\xff\x7f'): 32767,
|
|
bytes(b'\x00\x80'): 32768,
|
|
bytes(b'\xff\xff'): 65535,
|
|
bytes(b'\x00\x00\x01'): 65536,
|
|
}
|
|
check(tests4, 'little', signed=False)
|
|
|
|
class myint(int):
|
|
pass
|
|
|
|
if PY2:
|
|
import __builtin__
|
|
oldbytes = __builtin__.bytes
|
|
types = (bytes, oldbytes)
|
|
else:
|
|
types = (bytes,)
|
|
for mytype in types:
|
|
self.assertIs(type(myint.from_bytes(mytype(b'\x00'), 'big')), myint)
|
|
self.assertEqual(myint.from_bytes(mytype(b'\x01'), 'big'), 1)
|
|
self.assertIs(
|
|
type(myint.from_bytes(mytype(b'\x00'), 'big', signed=False)), myint)
|
|
self.assertEqual(myint.from_bytes(mytype(b'\x01'), 'big', signed=False), 1)
|
|
self.assertIs(type(myint.from_bytes(mytype(b'\x00'), 'little')), myint)
|
|
self.assertEqual(myint.from_bytes(mytype(b'\x01'), 'little'), 1)
|
|
self.assertIs(type(myint.from_bytes(
|
|
mytype(b'\x00'), 'little', signed=False)), myint)
|
|
self.assertEqual(myint.from_bytes(mytype(b'\x01'), 'little', signed=False), 1)
|
|
# self.assertEqual(
|
|
# int.from_bytes([255, 0, 0], 'big', signed=True), -65536)
|
|
# self.assertEqual(
|
|
# int.from_bytes((255, 0, 0), 'big', signed=True), -65536)
|
|
# self.assertEqual(int.from_bytes(
|
|
# bytearray(mytype(b'\xff\x00\x00')), 'big', signed=True), -65536)
|
|
# self.assertEqual(int.from_bytes(
|
|
# bytearray(mytype(b'\xff\x00\x00')), 'big', signed=True), -65536)
|
|
# self.assertEqual(int.from_bytes(
|
|
# array.array('B', mytype(b'\xff\x00\x00')), 'big', signed=True), -65536)
|
|
# self.assertEqual(int.from_bytes(
|
|
# memoryview(mytype(b'\xff\x00\x00')), 'big', signed=True), -65536)
|
|
|
|
self.assertRaises(TypeError, int.from_bytes, u"", 'big')
|
|
self.assertRaises(TypeError, int.from_bytes, u"\x00", 'big')
|
|
self.assertRaises(TypeError, myint.from_bytes, u"", 'big')
|
|
self.assertRaises(TypeError, myint.from_bytes, u"\x00", 'big')
|
|
|
|
types = (int, lambda x: x) if PY2 else (lambda x: x,)
|
|
for mytype in types:
|
|
self.assertRaises(ValueError, int.from_bytes, [mytype(256)], 'big')
|
|
self.assertRaises(ValueError, int.from_bytes, [mytype(0)], 'big\x00')
|
|
self.assertRaises(ValueError, int.from_bytes, [mytype(0)], 'little\x00')
|
|
self.assertRaises(TypeError, int.from_bytes, mytype(0), 'big')
|
|
# self.assertRaises(TypeError, int.from_bytes, mytype(0), 'big', True)
|
|
self.assertRaises(TypeError, myint.from_bytes, mytype(0), 'big')
|
|
# self.assertRaises(TypeError, int.from_bytes, mytype(0), 'big', True)
|
|
|
|
@expectedFailurePY2
|
|
def test_multiple_inheritance(self):
|
|
"""
|
|
Issue #96 (for newint instead of newobject)
|
|
"""
|
|
import collections.abc
|
|
|
|
class Base(int):
|
|
pass
|
|
|
|
class Foo(Base, collections.abc.Container):
|
|
def __add__(self, other):
|
|
return 0
|
|
|
|
@expectedFailurePY2
|
|
def test_with_metaclass_and_int(self):
|
|
"""
|
|
Issue #91 (for newint instead of newobject)
|
|
"""
|
|
from future.utils import with_metaclass
|
|
|
|
class MetaClass(type):
|
|
pass
|
|
|
|
class TestClass(with_metaclass(MetaClass, int)):
|
|
pass
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|