| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516 |
- # Test cases for floats (compile and run)
- [case testFloatOps]
- from __future__ import annotations
- from typing import Any, cast
- from typing_extensions import Final
- from testutil import assertRaises, float_vals, FLOAT_MAGIC
- import math
- def test_arithmetic() -> None:
- zero = float(0.0)
- one = zero + 1.0
- x = one + one / 2.0
- assert x == 1.5
- assert x - one == 0.5
- assert x * x == 2.25
- assert x / 2.0 == 0.75
- assert x * (-0.5) == -0.75
- assert -x == -1.5
- for x in float_vals:
- assert repr(-x) == repr(getattr(x, "__neg__")())
- for y in float_vals:
- assert repr(x + y) == repr(getattr(x, "__add__")(y))
- assert repr(x - y) == repr(getattr(x, "__sub__")(y))
- assert repr(x * y) == repr(getattr(x, "__mul__")(y))
- if y != 0:
- assert repr(x / y) == repr(getattr(x, "__truediv__")(y))
- def test_mod() -> None:
- zero = float(0.0)
- one = zero + 1.0
- x = one + one / 2.0
- assert x % 0.4 == 0.29999999999999993
- assert (-x) % 0.4 == 0.10000000000000009
- assert x % -0.4 == -0.10000000000000009
- assert (-x) % -0.4 == -0.29999999999999993
- for x in float_vals:
- for y in float_vals:
- if y != 0:
- assert repr(x % y) == repr(getattr(x, "__mod__")(y))
- def test_floor_div() -> None:
- for x in float_vals:
- for y in float_vals:
- if y != 0:
- assert repr(x // y) == repr(getattr(x, "__floordiv__")(y))
- else:
- with assertRaises(ZeroDivisionError, "float floor division by zero"):
- x // y
- def test_mixed_arithmetic() -> None:
- zf = float(0.0)
- zn = int()
- assert (zf + 5.5) + (zn + 1) == 6.5
- assert (zn - 2) - (zf - 5.5) == 3.5
- x = zf + 3.4
- x += zn + 2
- assert x == 5.4
- def test_arithmetic_errors() -> None:
- zero = float(0.0)
- one = zero + 1.0
- with assertRaises(ZeroDivisionError, "float division by zero"):
- print(one / zero)
- with assertRaises(ZeroDivisionError, "float modulo"):
- print(one % zero)
- def test_comparisons() -> None:
- zero = float(0.0)
- one = zero + 1.0
- x = one + one / 2.0
- assert x < (1.51 + zero)
- assert not (x < (1.49 + zero))
- assert x > (1.49 + zero)
- assert not (x > (1.51 + zero))
- assert x <= (1.5 + zero)
- assert not (x <= (1.49 + zero))
- assert x >= (1.5 + zero)
- assert not (x >= (1.51 + zero))
- for x in float_vals:
- for y in float_vals:
- assert (x <= y) == getattr(x, "__le__")(y)
- assert (x < y) == getattr(x, "__lt__")(y)
- assert (x >= y) == getattr(x, "__ge__")(y)
- assert (x > y) == getattr(x, "__gt__")(y)
- assert (x == y) == getattr(x, "__eq__")(y)
- assert (x != y) == getattr(x, "__ne__")(y)
- def test_mixed_comparisons() -> None:
- zf = float(0.0)
- zn = int()
- if (zf + 1.0) == (zn + 1):
- assert True
- else:
- assert False
- if (zf + 1.1) == (zn + 1):
- assert False
- else:
- assert True
- assert (zf + 1.1) != (zn + 1)
- assert (zf + 1.1) > (zn + 1)
- assert not (zf + 0.9) > (zn + 1)
- assert (zn + 1) < (zf + 1.1)
- def test_boxing_and_unboxing() -> None:
- x = 1.5
- boxed: Any = x
- assert repr(boxed) == "1.5"
- assert type(boxed) is float
- y: float = boxed
- assert y == x
- boxed_int: Any = 5
- assert [type(boxed_int)] == [int] # Avoid mypy type narrowing
- z: float = boxed_int
- assert z == 5.0
- for xx in float_vals:
- bb: Any = xx
- yy: float = bb
- assert repr(xx) == repr(bb)
- assert repr(xx) == repr(yy)
- for b in True, False:
- boxed_bool: Any = b
- assert type(boxed_bool) is bool
- zz: float = boxed_bool
- assert zz == int(b)
- def test_unboxing_failure() -> None:
- boxed: Any = '1.5'
- with assertRaises(TypeError):
- x: float = boxed
- def identity(x: float) -> float:
- return x
- def test_coerce_from_int_literal() -> None:
- assert identity(34) == 34.0
- assert identity(-1) == -1.0
- def test_coerce_from_short_tagged_int() -> None:
- n = int() - 17
- assert identity(n) == -17.0
- for i in range(-300, 300):
- assert identity(i) == float(i)
- def test_coerce_from_long_tagged_int() -> None:
- n = int() + 2**100
- x = identity(n)
- assert repr(x) == '1.2676506002282294e+30'
- n = int() - 2**100
- y = identity(n)
- assert repr(y) == '-1.2676506002282294e+30'
- def test_coerce_from_very_long_tagged_int() -> None:
- n = int() + 10**1000
- with assertRaises(OverflowError, "int too large to convert to float"):
- identity(n)
- with assertRaises(OverflowError, "int too large to convert to float"):
- identity(int(n))
- n = int() - 10**1000
- with assertRaises(OverflowError, "int too large to convert to float"):
- identity(n)
- with assertRaises(OverflowError, "int too large to convert to float"):
- identity(int(n))
- def test_explicit_conversion_from_int() -> None:
- float_any: Any = float
- a = [0, 1, 2, 3, -1, -2, 13257, -928745]
- for n in range(1, 100):
- for delta in -1, 0, 1, 2342345:
- a.append(2**n + delta)
- a.append(-2**n + delta)
- for x in a:
- assert repr(float(x)) == repr(float_any(x))
- def test_explicit_conversion_to_int() -> None:
- int_any: Any = int
- for x in float_vals:
- if math.isinf(x):
- with assertRaises(OverflowError, "cannot convert float infinity to integer"):
- int(x)
- elif math.isnan(x):
- with assertRaises(ValueError, "cannot convert float NaN to integer"):
- int(x)
- else:
- assert repr(int(x)) == repr(int_any(x))
- # Test some edge cases
- assert 2**30 == int(2.0**30 + int())
- assert 2**30 - 1 == int(1073741823.9999999 + int()) # math.nextafter(2.0**30, 0))
- assert -2**30 - 1 == int(-2.0**30 - 1 + int())
- assert -2**30 == int(-1073741824.9999998 + int()) # math.nextafter(-2.0**30 - 1, 0)
- assert 2**62 == int(2.0**62 + int())
- assert 2**62 == int(2.0**62 - 1 + int())
- assert -2**62 == int(-2.0**62 + int())
- assert -2**62 == int(-2.0**62 - 1 + int())
- def str_to_float(x: str) -> float:
- return float(x)
- def test_str_to_float() -> None:
- assert str_to_float("1") == 1.0
- assert str_to_float("1.234567") == 1.234567
- assert str_to_float("44324") == 44324.0
- assert str_to_float("23.4") == 23.4
- assert str_to_float("-43.44e-4") == -43.44e-4
- assert str_to_float("-43.44e-4") == -43.44e-4
- assert math.isinf(str_to_float("inf"))
- assert math.isinf(str_to_float("-inf"))
- assert str_to_float("inf") > 0.0
- assert str_to_float("-inf") < 0.0
- assert math.isnan(str_to_float("nan"))
- assert math.isnan(str_to_float("NaN"))
- assert repr(str_to_float("-0.0")) == "-0.0"
- def test_abs() -> None:
- assert abs(0.0) == 0.0
- assert abs(-1.234567) == 1.234567
- assert abs(44324.732) == 44324.732
- assert abs(-23.4) == 23.4
- assert abs(-43.44e-4) == 43.44e-4
- abs_any: Any = abs
- for x in float_vals:
- assert repr(abs(x)) == repr(abs_any(x))
- def test_float_min_max() -> None:
- for x in float_vals:
- for y in float_vals:
- min_any: Any = min
- assert repr(min(x, y)) == repr(min_any(x, y))
- max_any: Any = max
- assert repr(max(x, y)) == repr(max_any(x, y))
- def default(x: float = 2) -> float:
- return x + 1
- def test_float_default_value() -> None:
- assert default(1.2) == 2.2
- for i in range(-200, 200):
- assert default(float(i)) == i + 1
- assert default() == 3.0
- def test_float_default_value_wrapper() -> None:
- f: Any = default
- assert f(1.2) == 2.2
- for i in range(-200, 200):
- assert f(float(i)) == i + 1
- assert f() == 3.0
- class C:
- def __init__(self, x: float) -> None:
- self.x = x
- def test_float_attr() -> None:
- for i in range(-200, 200):
- f = float(i)
- c = C(f)
- assert c.x == f
- a: Any = c
- assert a.x == f
- c.x = FLOAT_MAGIC
- assert c.x == FLOAT_MAGIC
- assert a.x == FLOAT_MAGIC
- a.x = 1.0
- assert a.x == 1.0
- a.x = FLOAT_MAGIC
- assert a.x == FLOAT_MAGIC
- class D:
- def __init__(self, x: float) -> None:
- if x:
- self.x = x
- def test_float_attr_maybe_undefned() -> None:
- for i in range(-200, 200):
- if i == 0:
- d = D(0.0)
- with assertRaises(AttributeError):
- d.x
- a: Any = d
- with assertRaises(AttributeError):
- a.x
- d.x = FLOAT_MAGIC
- assert d.x == FLOAT_MAGIC
- assert a.x == FLOAT_MAGIC
- d.x = 0.0
- assert d.x == 0.0
- assert a.x == 0.0
- a.x = FLOAT_MAGIC
- assert a.x == FLOAT_MAGIC
- d = D(0.0)
- a = cast(Any, d)
- a.x = FLOAT_MAGIC
- assert d.x == FLOAT_MAGIC
- else:
- f = float(i)
- d = D(f)
- assert d.x == f
- a2: Any = d
- assert a2.x == f
- def f(x: float) -> float:
- return x + 1
- def test_return_values() -> None:
- a: Any = f
- for i in range(-200, 200):
- x = float(i)
- assert f(x) == x + 1
- assert a(x) == x + 1
- for x in float_vals:
- if not math.isnan(x):
- assert f(x) == x + 1
- else:
- assert math.isnan(f(x))
- def exc() -> float:
- raise IndexError('x')
- def test_exception() -> None:
- with assertRaises(IndexError):
- exc()
- a: Any = exc
- with assertRaises(IndexError):
- a()
- def test_undefined_local_var() -> None:
- if not int():
- x = -113.0
- assert x == -113.0
- if int():
- y = -113.0
- with assertRaises(UnboundLocalError, 'local variable "y" referenced before assignment'):
- print(y)
- if not int():
- x2 = -1.0
- assert x2 == -1.0
- if int():
- y2 = -1.0
- with assertRaises(UnboundLocalError, 'local variable "y2" referenced before assignment'):
- print(y2)
- def test_tuples() -> None:
- t1: tuple[float, float] = (1.5, 2.5)
- assert t1 == tuple([1.5, 2.5])
- n = int() + 5
- t2: tuple[float, float, float, float] = (n, 1.5, -7, -113)
- assert t2 == tuple([5.0, 1.5, -7.0, -113.0])
- [case testFloatGlueMethodsAndInheritance]
- from typing import Any
- from typing_extensions import Final
- from mypy_extensions import trait
- from testutil import assertRaises
- MAGIC: Final = -113.0
- class Base:
- def foo(self) -> float:
- return 5.0
- def bar(self, x: float = 2.0) -> float:
- return x + 1
- def hoho(self, x: float) -> float:
- return x - 1
- class Derived(Base):
- def foo(self, x: float = 5.0) -> float:
- return x + 10
- def bar(self, x: float = 3, y: float = 20) -> float:
- return x + y + 2
- def hoho(self, x: float = 7) -> float:
- return x - 2
- def test_derived_adds_bitmap() -> None:
- b: Base = Derived()
- assert b.foo() == 15
- def test_derived_adds_another_default_arg() -> None:
- b: Base = Derived()
- assert b.bar() == 25
- assert b.bar(1) == 23
- assert b.bar(MAGIC) == MAGIC + 22
- def test_derived_switches_arg_to_have_default() -> None:
- b: Base = Derived()
- assert b.hoho(5) == 3
- assert b.hoho(MAGIC) == MAGIC - 2
- @trait
- class T:
- @property
- def x(self) -> float: ...
- @property
- def y(self) -> float: ...
- class C(T):
- x: float = 1.0
- y: float = 4
- def test_read_only_property_in_trait_implemented_as_attribute() -> None:
- c = C()
- c.x = 5.5
- assert c.x == 5.5
- c.x = MAGIC
- assert c.x == MAGIC
- assert c.y == 4
- c.y = 6.5
- assert c.y == 6.5
- t: T = C()
- assert t.y == 4
- t = c
- assert t.x == MAGIC
- c.x = 55.5
- assert t.x == 55.5
- assert t.y == 6.5
- a: Any = c
- assert a.x == 55.5
- assert a.y == 6.5
- a.x = 7.0
- a.y = 8.0
- assert a.x == 7
- assert a.y == 8
- class D(T):
- xx: float
- @property
- def x(self) -> float:
- return self.xx
- @property
- def y(self) -> float:
- raise TypeError
- def test_read_only_property_in_trait_implemented_as_property() -> None:
- d = D()
- d.xx = 5.0
- assert d.x == 5
- d.xx = MAGIC
- assert d.x == MAGIC
- with assertRaises(TypeError):
- d.y
- t: T = d
- assert t.x == MAGIC
- d.xx = 6.0
- assert t.x == 6
- with assertRaises(TypeError):
- t.y
- @trait
- class T2:
- x: float
- y: float
- class C2(T2):
- pass
- def test_inherit_trait_attribute() -> None:
- c = C2()
- c.x = 5.0
- assert c.x == 5
- c.x = MAGIC
- assert c.x == MAGIC
- with assertRaises(AttributeError):
- c.y
- c.y = 6.0
- assert c.y == 6.0
- t: T2 = C2()
- with assertRaises(AttributeError):
- t.y
- t = c
- assert t.x == MAGIC
- c.x = 55.0
- assert t.x == 55
- assert t.y == 6
- a: Any = c
- assert a.x == 55
- assert a.y == 6
- a.x = 7.0
- a.y = 8.0
- assert a.x == 7
- assert a.y == 8
- class D2(T2):
- x: float
- y: float = 4
- def test_implement_trait_attribute() -> None:
- d = D2()
- d.x = 5.0
- assert d.x == 5
- d.x = MAGIC
- assert d.x == MAGIC
- assert d.y == 4
- d.y = 6.0
- assert d.y == 6
- t: T2 = D2()
- assert t.y == 4
- t = d
- assert t.x == MAGIC
- d.x = 55.0
- assert t.x == 55
- assert t.y == 6
- a: Any = d
- assert a.x == 55
- assert a.y == 6
- a.x = 7.0
- a.y = 8.0
- assert a.x == 7
- assert a.y == 8
|