[case testBoolToAndFromInt] from mypy_extensions import i64 def bool_to_int(b: bool) -> int: return b def int_to_bool(n: int) -> bool: return bool(n) def bool_to_i64(b: bool) -> i64: return b def i64_to_bool(n: i64) -> bool: return bool(n) def bit_to_int(n1: i64, n2: i64) -> int: return bool(n1 == n2) def bit_to_i64(n1: i64, n2: i64) -> i64: return bool(n1 == n2) [out] def bool_to_int(b): b, r0 :: bool r1 :: int L0: r0 = b << 1 r1 = extend r0: builtins.bool to builtins.int return r1 def int_to_bool(n): n :: int r0 :: bit L0: r0 = n != 0 return r0 def bool_to_i64(b): b :: bool r0 :: i64 L0: r0 = extend b: builtins.bool to i64 return r0 def i64_to_bool(n): n :: i64 r0 :: bit L0: r0 = n != 0 return r0 def bit_to_int(n1, n2): n1, n2 :: i64 r0 :: bit r1 :: bool r2 :: int L0: r0 = n1 == n2 r1 = r0 << 1 r2 = extend r1: builtins.bool to builtins.int return r2 def bit_to_i64(n1, n2): n1, n2 :: i64 r0 :: bit r1 :: i64 L0: r0 = n1 == n2 r1 = extend r0: bit to i64 return r1 [case testConversionToBool] from typing import List, Optional class C: pass class D: def __bool__(self) -> bool: return True def list_to_bool(l: List[str]) -> bool: return bool(l) def always_truthy_instance_to_bool(o: C) -> bool: return bool(o) def instance_to_bool(o: D) -> bool: return bool(o) def optional_truthy_to_bool(o: Optional[C]) -> bool: return bool(o) def optional_maybe_falsey_to_bool(o: Optional[D]) -> bool: return bool(o) [out] def D.__bool__(self): self :: __main__.D L0: return 1 def list_to_bool(l): l :: list r0 :: native_int r1 :: short_int r2 :: bit L0: r0 = var_object_size l r1 = r0 << 1 r2 = int_ne r1, 0 return r2 def always_truthy_instance_to_bool(o): o :: __main__.C r0 :: i32 r1 :: bit r2 :: bool L0: r0 = PyObject_IsTrue(o) r1 = r0 >= 0 :: signed r2 = truncate r0: i32 to builtins.bool return r2 def instance_to_bool(o): o :: __main__.D r0 :: bool L0: r0 = o.__bool__() return r0 def optional_truthy_to_bool(o): o :: union[__main__.C, None] r0 :: object r1 :: bit L0: r0 = load_address _Py_NoneStruct r1 = o != r0 return r1 def optional_maybe_falsey_to_bool(o): o :: union[__main__.D, None] r0 :: object r1 :: bit r2 :: __main__.D r3 :: bool r4 :: bit L0: r0 = load_address _Py_NoneStruct r1 = o != r0 if r1 goto L1 else goto L2 :: bool L1: r2 = cast(__main__.D, o) r3 = r2.__bool__() r4 = r3 goto L3 L2: r4 = 0 L3: return r4 [case testBoolComparisons] def eq(x: bool, y: bool) -> bool: return x == y def neq(x: bool, y: bool) -> bool: return x != y def lt(x: bool, y: bool) -> bool: return x < y def le(x: bool, y: bool) -> bool: return x <= y def gt(x: bool, y: bool) -> bool: return x > y def ge(x: bool, y: bool) -> bool: return x >= y [out] def eq(x, y): x, y :: bool r0 :: bit L0: r0 = x == y return r0 def neq(x, y): x, y :: bool r0 :: bit L0: r0 = x != y return r0 def lt(x, y): x, y :: bool r0 :: bit L0: r0 = x < y :: signed return r0 def le(x, y): x, y :: bool r0 :: bit L0: r0 = x <= y :: signed return r0 def gt(x, y): x, y :: bool r0 :: bit L0: r0 = x > y :: signed return r0 def ge(x, y): x, y :: bool r0 :: bit L0: r0 = x >= y :: signed return r0 [case testBoolMixedComparisons1] from mypy_extensions import i64 def eq1(x: int, y: bool) -> bool: return x == y def eq2(x: bool, y: int) -> bool: return x == y def neq1(x: i64, y: bool) -> bool: return x != y def neq2(x: bool, y: i64) -> bool: return x != y [out] def eq1(x, y): x :: int y, r0 :: bool r1 :: int r2 :: bit L0: r0 = y << 1 r1 = extend r0: builtins.bool to builtins.int r2 = int_eq x, r1 return r2 def eq2(x, y): x :: bool y :: int r0 :: bool r1 :: int r2 :: bit L0: r0 = x << 1 r1 = extend r0: builtins.bool to builtins.int r2 = int_eq r1, y return r2 def neq1(x, y): x :: i64 y :: bool r0 :: i64 r1 :: bit L0: r0 = extend y: builtins.bool to i64 r1 = x != r0 return r1 def neq2(x, y): x :: bool y, r0 :: i64 r1 :: bit L0: r0 = extend x: builtins.bool to i64 r1 = r0 != y return r1 [case testBoolMixedComparisons2] from mypy_extensions import i64 def lt1(x: bool, y: int) -> bool: return x < y def lt2(x: int, y: bool) -> bool: return x < y def gt1(x: bool, y: i64) -> bool: return x < y def gt2(x: i64, y: bool) -> bool: return x < y [out] def lt1(x, y): x :: bool y :: int r0 :: bool r1 :: int r2 :: bit L0: r0 = x << 1 r1 = extend r0: builtins.bool to builtins.int r2 = int_lt r1, y return r2 def lt2(x, y): x :: int y, r0 :: bool r1 :: int r2 :: bit L0: r0 = y << 1 r1 = extend r0: builtins.bool to builtins.int r2 = int_lt x, r1 return r2 def gt1(x, y): x :: bool y, r0 :: i64 r1 :: bit L0: r0 = extend x: builtins.bool to i64 r1 = r0 < y :: signed return r1 def gt2(x, y): x :: i64 y :: bool r0 :: i64 r1 :: bit L0: r0 = extend y: builtins.bool to i64 r1 = x < r0 :: signed return r1 [case testBoolBitwise] from mypy_extensions import i64 def bitand(x: bool, y: bool) -> bool: b = x & y return b def bitor(x: bool, y: bool) -> bool: b = x | y return b def bitxor(x: bool, y: bool) -> bool: b = x ^ y return b def invert(x: bool) -> int: return ~x def mixed_bitand(x: i64, y: bool) -> i64: return x & y [out] def bitand(x, y): x, y, r0, b :: bool L0: r0 = x & y b = r0 return b def bitor(x, y): x, y, r0, b :: bool L0: r0 = x | y b = r0 return b def bitxor(x, y): x, y, r0, b :: bool L0: r0 = x ^ y b = r0 return b def invert(x): x, r0 :: bool r1, r2 :: int L0: r0 = x << 1 r1 = extend r0: builtins.bool to builtins.int r2 = CPyTagged_Invert(r1) return r2 def mixed_bitand(x, y): x :: i64 y :: bool r0, r1 :: i64 L0: r0 = extend y: builtins.bool to i64 r1 = x & r0 return r1 [case testBoolArithmetic] def add(x: bool, y: bool) -> int: z = x + y return z def mixed(b: bool, n: int) -> int: z = b + n z -= b z = z * b return z def negate(b: bool) -> int: return -b def unary_plus(b: bool) -> int: x = +b return x [out] def add(x, y): x, y, r0 :: bool r1 :: int r2 :: bool r3, r4, z :: int L0: r0 = x << 1 r1 = extend r0: builtins.bool to builtins.int r2 = y << 1 r3 = extend r2: builtins.bool to builtins.int r4 = CPyTagged_Add(r1, r3) z = r4 return z def mixed(b, n): b :: bool n :: int r0 :: bool r1, r2, z :: int r3 :: bool r4, r5 :: int r6 :: bool r7, r8 :: int L0: r0 = b << 1 r1 = extend r0: builtins.bool to builtins.int r2 = CPyTagged_Add(r1, n) z = r2 r3 = b << 1 r4 = extend r3: builtins.bool to builtins.int r5 = CPyTagged_Subtract(z, r4) z = r5 r6 = b << 1 r7 = extend r6: builtins.bool to builtins.int r8 = CPyTagged_Multiply(z, r7) z = r8 return z def negate(b): b, r0 :: bool r1, r2 :: int L0: r0 = b << 1 r1 = extend r0: builtins.bool to builtins.int r2 = CPyTagged_Negate(r1) return r2 def unary_plus(b): b, r0 :: bool r1, x :: int L0: r0 = b << 1 r1 = extend r0: builtins.bool to builtins.int x = r1 return x [case testBitToBoolPromotion] def bitand(x: float, y: float, z: float) -> bool: b = (x == y) & (x == z) return b def bitor(x: float, y: float, z: float) -> bool: b = (x == y) | (x == z) return b def bitxor(x: float, y: float, z: float) -> bool: b = (x == y) ^ (x == z) return b def invert(x: float, y: float) -> bool: return not(x == y) [out] def bitand(x, y, z): x, y, z :: float r0, r1 :: bit r2, b :: bool L0: r0 = x == y r1 = x == z r2 = r0 & r1 b = r2 return b def bitor(x, y, z): x, y, z :: float r0, r1 :: bit r2, b :: bool L0: r0 = x == y r1 = x == z r2 = r0 | r1 b = r2 return b def bitxor(x, y, z): x, y, z :: float r0, r1 :: bit r2, b :: bool L0: r0 = x == y r1 = x == z r2 = r0 ^ r1 b = r2 return b def invert(x, y): x, y :: float r0, r1 :: bit L0: r0 = x == y r1 = r0 ^ 1 return r1 [case testUnaryNotWithPrimitiveTypes] def not_obj(x: object) -> bool: return not x def not_int(x: int) -> bool: return not x def not_str(x: str) -> bool: return not x def not_list(x: list[int]) -> bool: return not x def not_tuple(x: tuple[int, ...]) -> bool: return not x def not_dict(x: dict[str, int]) -> bool: return not x [out] def not_obj(x): x :: object r0 :: i32 r1 :: bit r2 :: bool L0: r0 = PyObject_Not(x) r1 = r0 >= 0 :: signed r2 = truncate r0: i32 to builtins.bool return r2 def not_int(x): x :: int r0 :: bit L0: r0 = int_eq x, 0 return r0 def not_str(x): x :: str r0, r1 :: bit L0: r0 = CPyStr_IsTrue(x) r1 = r0 ^ 1 return r1 def not_list(x): x :: list r0 :: native_int r1 :: short_int r2, r3 :: bit L0: r0 = var_object_size x r1 = r0 << 1 r2 = int_ne r1, 0 r3 = r2 ^ 1 return r3 def not_tuple(x): x :: tuple r0 :: native_int r1 :: short_int r2, r3 :: bit L0: r0 = var_object_size x r1 = r0 << 1 r2 = int_ne r1, 0 r3 = r2 ^ 1 return r3 def not_dict(x): x :: dict r0 :: native_int r1 :: short_int r2, r3 :: bit L0: r0 = PyDict_Size(x) r1 = r0 << 1 r2 = int_ne r1, 0 r3 = r2 ^ 1 return r3 [case testUnaryNotWithNativeClass] from __future__ import annotations class C: def __bool__(self) -> bool: return True def not_c(x: C) -> bool: return not x def not_c_opt(x: C | None) -> bool: return not x [out] def C.__bool__(self): self :: __main__.C L0: return 1 def not_c(x): x :: __main__.C r0, r1 :: bool L0: r0 = x.__bool__() r1 = r0 ^ 1 return r1 def not_c_opt(x): x :: union[__main__.C, None] r0 :: object r1, r2 :: bit r3 :: __main__.C r4, r5 :: bool L0: r0 = load_address _Py_NoneStruct r1 = x == r0 if r1 goto L1 else goto L2 :: bool L1: r2 = 1 goto L3 L2: r3 = unchecked borrow cast(__main__.C, x) r4 = r3.__bool__() r5 = r4 ^ 1 r2 = r5 L3: keep_alive x return r2 [case testUnaryNotWithOptionalPrimitiveTypes] from __future__ import annotations def not_str(x: str | None) -> bool: return not x def not_list(x: list[int] | None) -> bool: return not x [out] def not_str(x): x :: union[str, None] r0 :: object r1, r2 :: bit r3 :: str r4, r5 :: bit L0: r0 = load_address _Py_NoneStruct r1 = x == r0 if r1 goto L1 else goto L2 :: bool L1: r2 = 1 goto L3 L2: r3 = unchecked borrow cast(str, x) r4 = CPyStr_IsTrue(r3) r5 = r4 ^ 1 r2 = r5 L3: keep_alive x return r2 def not_list(x): x :: union[list, None] r0 :: object r1, r2 :: bit r3 :: list r4 :: native_int r5 :: short_int r6, r7 :: bit L0: r0 = load_address _Py_NoneStruct r1 = x == r0 if r1 goto L1 else goto L2 :: bool L1: r2 = 1 goto L3 L2: r3 = unchecked borrow cast(list, x) r4 = var_object_size r3 r5 = r4 << 1 r6 = int_ne r5, 0 r7 = r6 ^ 1 r2 = r7 L3: keep_alive x return r2