[case testFloatAdd] def f(x: float, y: float) -> float: return x + y def g(x: float) -> float: z = x - 1.5 return 2.5 * z [out] def f(x, y): x, y, r0 :: float L0: r0 = x + y return r0 def g(x): x, r0, z, r1 :: float L0: r0 = x - 1.5 z = r0 r1 = 2.5 * z return r1 [case testFloatBoxAndUnbox] from typing import Any def f(x: float) -> object: return x def g(x: Any) -> float: return x [out] def f(x): x :: float r0 :: object L0: r0 = box(float, x) return r0 def g(x): x :: object r0 :: float L0: r0 = unbox(float, x) return r0 [case testFloatNegAndPos] def f(x: float) -> float: y = +x * -0.5 return -y [out] def f(x): x, r0, y, r1 :: float L0: r0 = x * -0.5 y = r0 r1 = -y return r1 [case testFloatCoerceFromInt] def from_int(x: int) -> float: return x def from_literal() -> float: return 5 def from_literal_neg() -> float: return -2 [out] def from_int(x): x :: int r0 :: float L0: r0 = CPyFloat_FromTagged(x) return r0 def from_literal(): L0: return 5.0 def from_literal_neg(): L0: return -2.0 [case testConvertBetweenFloatAndInt] def to_int(x: float) -> int: return int(x) def from_int(x: int) -> float: return float(x) [out] def to_int(x): x :: float r0 :: int L0: r0 = CPyTagged_FromFloat(x) return r0 def from_int(x): x :: int r0 :: float L0: r0 = CPyFloat_FromTagged(x) return r0 [case testFloatOperatorAssignment] def f(x: float, y: float) -> float: x += y x -= 5.0 return x [out] def f(x, y): x, y, r0, r1 :: float L0: r0 = x + y x = r0 r1 = x - 5.0 x = r1 return x [case testFloatOperatorAssignmentWithInt] def f(x: float, y: int) -> None: x += y x -= 5 [out] def f(x, y): x :: float y :: int r0, r1, r2 :: float L0: r0 = CPyFloat_FromTagged(y) r1 = x + r0 x = r1 r2 = x - 5.0 x = r2 return 1 [case testFloatComparison] def lt(x: float, y: float) -> bool: return x < y def eq(x: float, y: float) -> bool: return x == y [out] def lt(x, y): x, y :: float r0 :: bit L0: r0 = x < y return r0 def eq(x, y): x, y :: float r0 :: bit L0: r0 = x == y return r0 [case testFloatOpWithLiteralInt] def f(x: float) -> None: y = x * 2 z = 1 - y b = z < 3 c = 0 == z [out] def f(x): x, r0, y, r1, z :: float r2 :: bit b :: bool r3 :: bit c :: bool L0: r0 = x * 2.0 y = r0 r1 = 1.0 - y z = r1 r2 = z < 3.0 b = r2 r3 = 0.0 == z c = r3 return 1 [case testFloatCallFunctionWithLiteralInt] def f(x: float) -> None: pass def g() -> None: f(3) f(-2) [out] def f(x): x :: float L0: return 1 def g(): r0, r1 :: None L0: r0 = f(3.0) r1 = f(-2.0) return 1 [case testFloatAsBool] def f(x: float) -> int: if x: return 2 else: return 5 [out] def f(x): x :: float r0 :: bit L0: r0 = x != 0.0 if r0 goto L1 else goto L2 :: bool L1: return 4 L2: return 10 L3: unreachable [case testCallSqrtViaMathModule] import math def f(x: float) -> float: return math.sqrt(x) [out] def f(x): x, r0 :: float L0: r0 = CPyFloat_Sqrt(x) return r0 [case testFloatFinalConstant] from typing_extensions import Final X: Final = 123.0 Y: Final = -1.0 def f() -> float: a = X return a + Y [out] def f(): a, r0 :: float L0: a = 123.0 r0 = a + -1.0 return r0 [case testFloatDefaultArg] def f(x: float = 1.5) -> float: return x [out] def f(x, __bitmap): x :: float __bitmap, r0 :: u32 r1 :: bit L0: r0 = __bitmap & 1 r1 = r0 == 0 if r1 goto L1 else goto L2 :: bool L1: x = 1.5 L2: return x [case testFloatMixedOperations] def f(x: float, y: int) -> None: if x < y: z = x + y x -= y z = y + z if y == x: x -= 1 [out] def f(x, y): x :: float y :: int r0 :: float r1 :: bit r2, r3, z, r4, r5, r6, r7, r8 :: float r9 :: bit r10 :: float L0: r0 = CPyFloat_FromTagged(y) r1 = x < r0 if r1 goto L1 else goto L2 :: bool L1: r2 = CPyFloat_FromTagged(y) r3 = x + r2 z = r3 r4 = CPyFloat_FromTagged(y) r5 = x - r4 x = r5 r6 = CPyFloat_FromTagged(y) r7 = r6 + z z = r7 L2: r8 = CPyFloat_FromTagged(y) r9 = r8 == x if r9 goto L3 else goto L4 :: bool L3: r10 = x - 1.0 x = r10 L4: return 1 [case testFloatDivideSimple] def f(x: float, y: float) -> float: z = x / y z = z / 2.0 return z / 3 [out] def f(x, y): x, y :: float r0 :: bit r1 :: bool r2, z, r3, r4 :: float L0: r0 = y == 0.0 if r0 goto L1 else goto L2 :: bool L1: r1 = raise ZeroDivisionError('float division by zero') unreachable L2: r2 = x / y z = r2 r3 = z / 2.0 z = r3 r4 = z / 3.0 return r4 [case testFloatDivideIntOperand] def f(n: int, m: int) -> float: return n / m [out] def f(n, m): n, m :: int r0 :: float L0: r0 = CPyTagged_TrueDivide(n, m) return r0 [case testFloatResultOfIntDivide] def f(f: float, n: int) -> float: x = f / n return n / x [out] def f(f, n): f :: float n :: int r0 :: float r1 :: bit r2 :: bool r3, x, r4 :: float r5 :: bit r6 :: bool r7 :: float L0: r0 = CPyFloat_FromTagged(n) r1 = r0 == 0.0 if r1 goto L1 else goto L2 :: bool L1: r2 = raise ZeroDivisionError('float division by zero') unreachable L2: r3 = f / r0 x = r3 r4 = CPyFloat_FromTagged(n) r5 = x == 0.0 if r5 goto L3 else goto L4 :: bool L3: r6 = raise ZeroDivisionError('float division by zero') unreachable L4: r7 = r4 / x return r7 [case testFloatExplicitConversions] def f(f: float, n: int) -> int: x = float(n) y = float(x) # no-op return int(y) [out] def f(f, n): f :: float n :: int r0, x, y :: float r1 :: int L0: r0 = CPyFloat_FromTagged(n) x = r0 y = x r1 = CPyTagged_FromFloat(y) return r1 [case testFloatModulo] def f(x: float, y: float) -> float: return x % y [out] def f(x, y): x, y :: float r0 :: bit r1 :: bool r2, r3 :: float r4, r5, r6, r7 :: bit r8, r9 :: float L0: r0 = y == 0.0 if r0 goto L1 else goto L2 :: bool L1: r1 = raise ZeroDivisionError('float modulo') unreachable L2: r2 = x % y r3 = r2 r4 = r3 == 0.0 if r4 goto L5 else goto L3 :: bool L3: r5 = x < 0.0 r6 = y < 0.0 r7 = r5 == r6 if r7 goto L6 else goto L4 :: bool L4: r8 = r3 + y r3 = r8 goto L6 L5: r9 = copysign(0.0, y) r3 = r9 L6: return r3 [case testFloatFloorDivide] def f(x: float, y: float) -> float: return x // y def g(x: float, y: int) -> float: return x // y [out] def f(x, y): x, y, r0 :: float L0: r0 = CPyFloat_FloorDivide(x, y) return r0 def g(x, y): x :: float y :: int r0, r1 :: float L0: r0 = CPyFloat_FromTagged(y) r1 = CPyFloat_FloorDivide(x, r0) return r1 [case testFloatNarrowToIntDisallowed] class C: x: float def narrow_local(x: float, n: int) -> int: x = n # E: Incompatible value representations in assignment (expression has type "int", variable has type "float") return x def narrow_tuple_lvalue(x: float, y: float, n: int) -> int: x, y = 1.0, n # E: Incompatible value representations in assignment (expression has type "int", variable has type "float") return y def narrow_multiple_lvalues(x: float, y: float, n: int) -> int: x = a = n # E: Incompatible value representations in assignment (expression has type "int", variable has type "float") a = y = n # E: Incompatible value representations in assignment (expression has type "int", variable has type "float") return x + y def narrow_attribute(c: C, n: int) -> int: c.x = n # E: Incompatible value representations in assignment (expression has type "int", variable has type "float") return c.x def narrow_using_int_literal(x: float) -> int: x = 1 # E: Incompatible value representations in assignment (expression has type "int", variable has type "float") return x def narrow_using_declaration(n: int) -> int: x: float x = n # E: Incompatible value representations in assignment (expression has type "int", variable has type "float") return x [case testFloatInitializeFromInt] def init(n: int) -> None: # These are strictly speaking safe, since these don't narrow, but for consistency with # narrowing assignments, generate errors here x: float = n # E: Incompatible value representations in assignment (expression has type "int", variable has type "float") y: float = 5 # E: Incompatible value representations in assignment (expression has type "int", variable has type "float") [case testFloatCoerceTupleFromIntValues] from __future__ import annotations def f(x: int) -> None: t: tuple[float, float, float] = (x, 2.5, -7) [out] def f(x): x :: int r0 :: tuple[int, float, int] r1 :: int r2 :: float r3, t :: tuple[float, float, float] L0: r0 = (x, 2.5, -14) r1 = r0[0] r2 = CPyFloat_FromTagged(r1) r3 = (r2, 2.5, -7.0) t = r3 return 1