# Test cases for integers (compile and run) [case testInc] def inc(x: int) -> int: return x + 1 [file driver.py] from native import inc print(inc(3)) print(inc(-5)) print(inc(10**20)) [out] 4 -4 100000000000000000001 [case testCount] def count(n: int) -> int: i = 1 while i <= n: i = i + 1 return i [file driver.py] from native import count print(count(0)) print(count(1)) print(count(5)) [out] 1 2 6 [case testIntMathOps] # This tests integer math things that are either easier to test in Python than # in our C tests or are tested here because (for annoying reasons) we don't run # the C unit tests in our 32-bit CI. def multiply(x: int, y: int) -> int: return x * y # these stringify their outputs because that will catch if exceptions are mishandled def floor_div(x: int, y: int) -> str: return str(x // y) def remainder(x: int, y: int) -> str: return str(x % y) [file driver.py] from native import multiply, floor_div, remainder def test_multiply(x, y): assert multiply(x, y) == x * y def test_floor_div(x, y): assert floor_div(x, y) == str(x // y) def test_remainder(x, y): assert remainder(x, y) == str(x % y) test_multiply(10**6, 10**6) test_multiply(2**15, 2**15-1) test_multiply(2**14, 2**14) test_multiply(10**12, 10**12) test_multiply(2**30, 2**30-1) test_multiply(2**29, 2**29) test_floor_div(-2**62, -1) test_floor_div(-2**30, -1) try: floor_div(10, 0) except ZeroDivisionError: pass else: assert False, "Expected ZeroDivisionError" test_remainder(-2**62, -1) test_remainder(-2**30, -1) try: remainder(10, 0) except ZeroDivisionError: pass else: assert False, "Expected ZeroDivisionError" [case testBigIntLiteral] def big_int() -> None: a_62_bit = 4611686018427387902 max_62_bit = 4611686018427387903 b_63_bit = 4611686018427387904 c_63_bit = 9223372036854775806 max_63_bit = 9223372036854775807 d_64_bit = 9223372036854775808 max_32_bit = 2147483647 max_32_bit_plus1 = 2147483648 max_31_bit = 1073741823 max_31_bit_plus1 = 1073741824 neg = -1234567 min_signed_63_bit = -4611686018427387904 underflow = -4611686018427387905 min_signed_64_bit = -9223372036854775808 min_signed_31_bit = -1073741824 min_signed_31_bit_plus1 = -1073741823 min_signed_31_bit_minus1 = -1073741825 min_signed_32_bit = -2147483648 print(a_62_bit) print(max_62_bit) print(b_63_bit) print(c_63_bit) print(max_63_bit) print(d_64_bit) print('==') print(max_32_bit) print(max_32_bit_plus1) print(max_31_bit) print(max_31_bit_plus1) print(neg) print(min_signed_63_bit) print(underflow) print(min_signed_64_bit) print(min_signed_31_bit) print(min_signed_31_bit_plus1) print(min_signed_31_bit_minus1) print(min_signed_32_bit) [file driver.py] from native import big_int big_int() [out] 4611686018427387902 4611686018427387903 4611686018427387904 9223372036854775806 9223372036854775807 9223372036854775808 == 2147483647 2147483648 1073741823 1073741824 -1234567 -4611686018427387904 -4611686018427387905 -9223372036854775808 -1073741824 -1073741823 -1073741825 -2147483648 [case testNeg] def neg(x: int) -> int: return -x [file driver.py] from native import neg assert neg(5) == -5 assert neg(-5) == 5 assert neg(1073741823) == -1073741823 assert neg(-1073741823) == 1073741823 assert neg(1073741824) == -1073741824 assert neg(-1073741824) == 1073741824 assert neg(2147483647) == -2147483647 assert neg(-2147483647) == 2147483647 assert neg(2147483648) == -2147483648 assert neg(-2147483648) == 2147483648 assert neg(4611686018427387904) == -4611686018427387904 assert neg(-4611686018427387904) == 4611686018427387904 assert neg(9223372036854775807) == -9223372036854775807 assert neg(-9223372036854775807) == 9223372036854775807 assert neg(9223372036854775808) == -9223372036854775808 assert neg(-9223372036854775808) == 9223372036854775808 [case testIsinstanceIntAndNotBool] def test_isinstance_int_and_not_bool(value: object) -> bool: return isinstance(value, int) and not isinstance(value, bool) [file driver.py] from native import test_isinstance_int_and_not_bool assert test_isinstance_int_and_not_bool(True) == False assert test_isinstance_int_and_not_bool(1) == True [case testIntOps] from typing import Any def check_and(x: int, y: int) -> None: # eval() can be trusted to calculate expected result expected = eval('{} & {}'.format(x, y)) actual = x & y assert actual == expected, '{} & {}: got {}, expected {}'.format(x, y, actual, expected) def check_or(x: int, y: int) -> None: # eval() can be trusted to calculate expected result expected = eval('{} | {}'.format(x, y)) actual = x | y assert actual == expected, '{} | {}: got {}, expected {}'.format(x, y, actual, expected) def check_xor(x: int, y: int) -> None: # eval() can be trusted to calculate expected result expected = eval('{} ^ {}'.format(x, y)) actual = x ^ y assert actual == expected, '{} ^ {}: got {}, expected {}'.format(x, y, actual, expected) def check_bitwise(x: int, y: int) -> None: for l, r in (x, y), (y, x): for ll, rr in (l, r), (-l, r), (l, -r), (-l, -r): check_and(ll, rr) check_or(ll, rr) check_xor(ll, rr) SHIFT = 30 DIGIT0a = 615729753 DIGIT0b = 832796681 DIGIT1a = 744342356 << SHIFT DIGIT1b = 321006080 << SHIFT DIGIT2a = 643582106 << (SHIFT * 2) DIGIT2b = 656420725 << (SHIFT * 2) DIGIT50 = 315723472 << (SHIFT * 50) DIGIT100a = 1020652627 << (SHIFT * 100) DIGIT100b = 923752451 << (SHIFT * 100) BIG_SHORT = 3491190729721336556 MAX_SHORT = (1 << 62) - 1 MIN_SHORT = -(1 << 62) MAX_SHORT_32 = (1 << 30) - 1 MIN_SHORT_32 = -(1 << 30) def test_and_or_xor() -> None: check_bitwise(0, 0) check_bitwise(0, 1) check_bitwise(1, 1) check_bitwise(DIGIT0a, DIGIT0b) check_bitwise(DIGIT1a, DIGIT1b) check_bitwise(DIGIT2a, DIGIT2b) check_bitwise(DIGIT100a, DIGIT100b) check_bitwise(DIGIT0a, DIGIT0b + DIGIT2a) check_bitwise(DIGIT0a, DIGIT0b + DIGIT50) check_bitwise(DIGIT50 + DIGIT1a, DIGIT100a + DIGIT2b) check_bitwise(BIG_SHORT, DIGIT0a) check_bitwise(BIG_SHORT, DIGIT0a + DIGIT1a) check_bitwise(BIG_SHORT, DIGIT0a + DIGIT1a + DIGIT2a) check_bitwise(BIG_SHORT, DIGIT0a + DIGIT1a + DIGIT2a + DIGIT50) for x in range(-25, 25): for y in range(-25, 25): check_bitwise(x, y) def test_bitwise_inplace() -> None: # Basic sanity checks; these should use the same code as the non-in-place variants for x, y in (DIGIT0a, DIGIT1a), (DIGIT2a, DIGIT0a + DIGIT2b): n = x n &= y assert n == x & y n = x n |= y assert n == x | y n = x n ^= y assert n == x ^ y def check_invert(x: int) -> None: # Use eval() as the source of truth assert ~x == eval('~{}'.format(x)) assert ~(-x) == eval('~({})'.format(-x)) def test_invert() -> None: check_invert(0) check_invert(1) check_invert(DIGIT0a) check_invert(DIGIT0a + DIGIT1a) check_invert(DIGIT0a + DIGIT1a + DIGIT2a) check_invert(DIGIT0a + DIGIT1a + DIGIT2a + DIGIT50) check_invert(BIG_SHORT) for delta in -1, 0, 1: check_invert(MAX_SHORT + delta) check_invert(MIN_SHORT + delta) check_invert(MAX_SHORT_32 + delta) check_invert(MIN_SHORT_32 + delta) def check_right_shift(x: int, n: int) -> None: if n < 0: try: x >> n except ValueError: return assert False, "no exception raised" # Use eval() as the source of truth expected = eval('{} >> {}'.format(x, n)) actual = x >> n assert actual == expected, "{} >> {}: got {}, expected {}".format(x, n, actual, expected) def test_right_shift() -> None: for x in 0, 1, 1235, DIGIT0a, DIGIT0a + DIGIT1a, DIGIT0a + DIGIT50: for n in 0, 1, 2, 3, 4, 10, 40, 10000, DIGIT1a, -1, -1334444, -DIGIT1a: check_right_shift(x, n) check_right_shift(-x, n) x = DIGIT0a x >>= 1 assert x == DIGIT0a >> 1 x = DIGIT50 x >>= 5 assert x == DIGIT50 >> 5 for i in range(256): check_right_shift(1, i) check_right_shift(137, i) check_right_shift(MAX_SHORT, i) check_right_shift(MAX_SHORT_32, i) check_right_shift(MAX_SHORT + 1, i) check_right_shift(MAX_SHORT_32 + 1, i) for x in 1, DIGIT50: try: # It's okay if this raises an exception assert x >> DIGIT2a == 0 except Exception: pass try: x >> -DIGIT2a assert False except Exception: pass def check_left_shift(x: int, n: int) -> None: if n < 0: try: x << n except ValueError: return assert False, "no exception raised" # Use eval() as the source of truth expected = eval('{} << {}'.format(x, n)) actual = x << n assert actual == expected, "{} << {}: got {}, expected {}".format(x, n, actual, expected) def test_left_shift() -> None: for x in 0, 1, 1235, DIGIT0a, DIGIT0a + DIGIT1a, DIGIT0a + DIGIT50: for n in 0, 1, 2, 10, 40, 10000, -1, -1334444: check_left_shift(x, n) check_left_shift(-x, n) x = DIGIT0a x <<= 1 assert x == DIGIT0a << 1 x = DIGIT50 x <<= 5 assert x == DIGIT50 << 5 for shift in range(256): check_left_shift(1, shift) check_left_shift(137, shift) for x in 1, DIGIT50: try: x << DIGIT50 assert False except Exception: pass try: x << -DIGIT50 assert False except Exception: pass def is_true(x: int) -> bool: if x: return True else: return False def is_false(x: int) -> bool: if not x: return True else: return False def test_int_as_bool() -> None: assert not is_true(0) assert is_false(0) for x in 1, 55, -1, -7, 1 << 50, 1 << 101, -(1 << 50), -(1 << 101): assert is_true(x) assert not is_false(x) def test_divide() -> None: for x in range(-100, 100): for y in range(-100, 100): if y != 0: assert x // y == getattr(x, "__floordiv__")(y) def test_mod() -> None: for x in range(-100, 100): for y in range(-100, 100): if y != 0: assert x % y == getattr(x, "__mod__")(y) def test_constant_fold() -> None: assert str(-5 + 3) == "-2" assert str(15 - 3) == "12" assert str(1000 * 1000) == "1000000" assert str(12325 // 12 ) == "1027" assert str(87645 % 321) == "12" assert str(674253 | 76544) == "748493" assert str(765 ^ 82) == "687" assert str(6546 << 3) == "52368" assert str(6546 >> 7) == "51" assert str(3**5) == "243" assert str(~76) == "-77" try: 2 / 0 except ZeroDivisionError: pass else: assert False, "no exception raised" x = int() y = int() - 1 assert x == -1 or y != -3 assert -1 <= x assert -1 == y # Use int() to avoid constant propagation i30 = (1 << 30) + int() assert i30 == 1 << 30 i31 = (1 << 31) + int() assert i31 == 1 << 31 i32 = (1 << 32) + int() assert i32 == 1 << 32 i62 = (1 << 62) + int() assert i62 == 1 << 62 i63 = (1 << 63) + int() assert i63 == 1 << 63 i64 = (1 << 64) + int() assert i64 == 1 << 64 n30 = -(1 << 30) + int() assert n30 == -(1 << 30) n31 = -(1 << 31) + int() assert n31 == -(1 << 31) n32 = -(1 << 32) + int() assert n32 == -(1 << 32) n62 = -(1 << 62) + int() assert n62 == -(1 << 62) n63 = -(1 << 63) + int() assert n63 == -(1 << 63) n64 = -(1 << 64) + int() assert n64 == -(1 << 64) def div_by_2(x: int) -> int: return x // 2 def div_by_3(x: int) -> int: return x // 3 def div_by_4(x: int) -> int: return x // 4 def test_floor_divide_by_literal() -> None: for i in range(-100, 100): i_boxed: Any = i assert div_by_2(i) == i_boxed // int('2') assert div_by_3(i) == i_boxed // int('3') assert div_by_4(i) == i_boxed // int('4') [case testIntMinMax] def test_int_min_max() -> None: x: int = 200 y: int = 30 assert min(x, y) == 30 assert max(x, y) == 200 assert min(y, x) == 30 assert max(y, x) == 200 def test_int_hybrid_min_max() -> None: from typing import Any x: object = 30 y: Any = 20.0 assert min(x, y) == 20.0 assert max(x, y) == 30 u: object = 20 v: float = 30.0 assert min(u, v) == 20 assert max(u, v) == 30.0 def test_int_incompatible_min_max() -> None: x: int = 2 y: str = 'aaa' try: print(min(x, y)) except TypeError as e: assert str(e) == "'<' not supported between instances of 'str' and 'int'" try: print(max(x, y)) except TypeError as e: assert str(e) == "'>' not supported between instances of 'str' and 'int'" def test_int_bool_min_max() -> None: x: int = 2 y: bool = False z: bool = True assert min(x, y) == False assert min(x, z) == True assert max(x, y) == 2 assert max(x, z) == 2 u: int = -10 assert min(u, y) == -10 assert min(u, z) == -10 assert max(u, y) == False assert max(u, z) == True