run-floats.test 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516
  1. # Test cases for floats (compile and run)
  2. [case testFloatOps]
  3. from __future__ import annotations
  4. from typing import Any, cast
  5. from typing_extensions import Final
  6. from testutil import assertRaises, float_vals, FLOAT_MAGIC
  7. import math
  8. def test_arithmetic() -> None:
  9. zero = float(0.0)
  10. one = zero + 1.0
  11. x = one + one / 2.0
  12. assert x == 1.5
  13. assert x - one == 0.5
  14. assert x * x == 2.25
  15. assert x / 2.0 == 0.75
  16. assert x * (-0.5) == -0.75
  17. assert -x == -1.5
  18. for x in float_vals:
  19. assert repr(-x) == repr(getattr(x, "__neg__")())
  20. for y in float_vals:
  21. assert repr(x + y) == repr(getattr(x, "__add__")(y))
  22. assert repr(x - y) == repr(getattr(x, "__sub__")(y))
  23. assert repr(x * y) == repr(getattr(x, "__mul__")(y))
  24. if y != 0:
  25. assert repr(x / y) == repr(getattr(x, "__truediv__")(y))
  26. def test_mod() -> None:
  27. zero = float(0.0)
  28. one = zero + 1.0
  29. x = one + one / 2.0
  30. assert x % 0.4 == 0.29999999999999993
  31. assert (-x) % 0.4 == 0.10000000000000009
  32. assert x % -0.4 == -0.10000000000000009
  33. assert (-x) % -0.4 == -0.29999999999999993
  34. for x in float_vals:
  35. for y in float_vals:
  36. if y != 0:
  37. assert repr(x % y) == repr(getattr(x, "__mod__")(y))
  38. def test_floor_div() -> None:
  39. for x in float_vals:
  40. for y in float_vals:
  41. if y != 0:
  42. assert repr(x // y) == repr(getattr(x, "__floordiv__")(y))
  43. else:
  44. with assertRaises(ZeroDivisionError, "float floor division by zero"):
  45. x // y
  46. def test_mixed_arithmetic() -> None:
  47. zf = float(0.0)
  48. zn = int()
  49. assert (zf + 5.5) + (zn + 1) == 6.5
  50. assert (zn - 2) - (zf - 5.5) == 3.5
  51. x = zf + 3.4
  52. x += zn + 2
  53. assert x == 5.4
  54. def test_arithmetic_errors() -> None:
  55. zero = float(0.0)
  56. one = zero + 1.0
  57. with assertRaises(ZeroDivisionError, "float division by zero"):
  58. print(one / zero)
  59. with assertRaises(ZeroDivisionError, "float modulo"):
  60. print(one % zero)
  61. def test_comparisons() -> None:
  62. zero = float(0.0)
  63. one = zero + 1.0
  64. x = one + one / 2.0
  65. assert x < (1.51 + zero)
  66. assert not (x < (1.49 + zero))
  67. assert x > (1.49 + zero)
  68. assert not (x > (1.51 + zero))
  69. assert x <= (1.5 + zero)
  70. assert not (x <= (1.49 + zero))
  71. assert x >= (1.5 + zero)
  72. assert not (x >= (1.51 + zero))
  73. for x in float_vals:
  74. for y in float_vals:
  75. assert (x <= y) == getattr(x, "__le__")(y)
  76. assert (x < y) == getattr(x, "__lt__")(y)
  77. assert (x >= y) == getattr(x, "__ge__")(y)
  78. assert (x > y) == getattr(x, "__gt__")(y)
  79. assert (x == y) == getattr(x, "__eq__")(y)
  80. assert (x != y) == getattr(x, "__ne__")(y)
  81. def test_mixed_comparisons() -> None:
  82. zf = float(0.0)
  83. zn = int()
  84. if (zf + 1.0) == (zn + 1):
  85. assert True
  86. else:
  87. assert False
  88. if (zf + 1.1) == (zn + 1):
  89. assert False
  90. else:
  91. assert True
  92. assert (zf + 1.1) != (zn + 1)
  93. assert (zf + 1.1) > (zn + 1)
  94. assert not (zf + 0.9) > (zn + 1)
  95. assert (zn + 1) < (zf + 1.1)
  96. def test_boxing_and_unboxing() -> None:
  97. x = 1.5
  98. boxed: Any = x
  99. assert repr(boxed) == "1.5"
  100. assert type(boxed) is float
  101. y: float = boxed
  102. assert y == x
  103. boxed_int: Any = 5
  104. assert [type(boxed_int)] == [int] # Avoid mypy type narrowing
  105. z: float = boxed_int
  106. assert z == 5.0
  107. for xx in float_vals:
  108. bb: Any = xx
  109. yy: float = bb
  110. assert repr(xx) == repr(bb)
  111. assert repr(xx) == repr(yy)
  112. for b in True, False:
  113. boxed_bool: Any = b
  114. assert type(boxed_bool) is bool
  115. zz: float = boxed_bool
  116. assert zz == int(b)
  117. def test_unboxing_failure() -> None:
  118. boxed: Any = '1.5'
  119. with assertRaises(TypeError):
  120. x: float = boxed
  121. def identity(x: float) -> float:
  122. return x
  123. def test_coerce_from_int_literal() -> None:
  124. assert identity(34) == 34.0
  125. assert identity(-1) == -1.0
  126. def test_coerce_from_short_tagged_int() -> None:
  127. n = int() - 17
  128. assert identity(n) == -17.0
  129. for i in range(-300, 300):
  130. assert identity(i) == float(i)
  131. def test_coerce_from_long_tagged_int() -> None:
  132. n = int() + 2**100
  133. x = identity(n)
  134. assert repr(x) == '1.2676506002282294e+30'
  135. n = int() - 2**100
  136. y = identity(n)
  137. assert repr(y) == '-1.2676506002282294e+30'
  138. def test_coerce_from_very_long_tagged_int() -> None:
  139. n = int() + 10**1000
  140. with assertRaises(OverflowError, "int too large to convert to float"):
  141. identity(n)
  142. with assertRaises(OverflowError, "int too large to convert to float"):
  143. identity(int(n))
  144. n = int() - 10**1000
  145. with assertRaises(OverflowError, "int too large to convert to float"):
  146. identity(n)
  147. with assertRaises(OverflowError, "int too large to convert to float"):
  148. identity(int(n))
  149. def test_explicit_conversion_from_int() -> None:
  150. float_any: Any = float
  151. a = [0, 1, 2, 3, -1, -2, 13257, -928745]
  152. for n in range(1, 100):
  153. for delta in -1, 0, 1, 2342345:
  154. a.append(2**n + delta)
  155. a.append(-2**n + delta)
  156. for x in a:
  157. assert repr(float(x)) == repr(float_any(x))
  158. def test_explicit_conversion_to_int() -> None:
  159. int_any: Any = int
  160. for x in float_vals:
  161. if math.isinf(x):
  162. with assertRaises(OverflowError, "cannot convert float infinity to integer"):
  163. int(x)
  164. elif math.isnan(x):
  165. with assertRaises(ValueError, "cannot convert float NaN to integer"):
  166. int(x)
  167. else:
  168. assert repr(int(x)) == repr(int_any(x))
  169. # Test some edge cases
  170. assert 2**30 == int(2.0**30 + int())
  171. assert 2**30 - 1 == int(1073741823.9999999 + int()) # math.nextafter(2.0**30, 0))
  172. assert -2**30 - 1 == int(-2.0**30 - 1 + int())
  173. assert -2**30 == int(-1073741824.9999998 + int()) # math.nextafter(-2.0**30 - 1, 0)
  174. assert 2**62 == int(2.0**62 + int())
  175. assert 2**62 == int(2.0**62 - 1 + int())
  176. assert -2**62 == int(-2.0**62 + int())
  177. assert -2**62 == int(-2.0**62 - 1 + int())
  178. def str_to_float(x: str) -> float:
  179. return float(x)
  180. def test_str_to_float() -> None:
  181. assert str_to_float("1") == 1.0
  182. assert str_to_float("1.234567") == 1.234567
  183. assert str_to_float("44324") == 44324.0
  184. assert str_to_float("23.4") == 23.4
  185. assert str_to_float("-43.44e-4") == -43.44e-4
  186. assert str_to_float("-43.44e-4") == -43.44e-4
  187. assert math.isinf(str_to_float("inf"))
  188. assert math.isinf(str_to_float("-inf"))
  189. assert str_to_float("inf") > 0.0
  190. assert str_to_float("-inf") < 0.0
  191. assert math.isnan(str_to_float("nan"))
  192. assert math.isnan(str_to_float("NaN"))
  193. assert repr(str_to_float("-0.0")) == "-0.0"
  194. def test_abs() -> None:
  195. assert abs(0.0) == 0.0
  196. assert abs(-1.234567) == 1.234567
  197. assert abs(44324.732) == 44324.732
  198. assert abs(-23.4) == 23.4
  199. assert abs(-43.44e-4) == 43.44e-4
  200. abs_any: Any = abs
  201. for x in float_vals:
  202. assert repr(abs(x)) == repr(abs_any(x))
  203. def test_float_min_max() -> None:
  204. for x in float_vals:
  205. for y in float_vals:
  206. min_any: Any = min
  207. assert repr(min(x, y)) == repr(min_any(x, y))
  208. max_any: Any = max
  209. assert repr(max(x, y)) == repr(max_any(x, y))
  210. def default(x: float = 2) -> float:
  211. return x + 1
  212. def test_float_default_value() -> None:
  213. assert default(1.2) == 2.2
  214. for i in range(-200, 200):
  215. assert default(float(i)) == i + 1
  216. assert default() == 3.0
  217. def test_float_default_value_wrapper() -> None:
  218. f: Any = default
  219. assert f(1.2) == 2.2
  220. for i in range(-200, 200):
  221. assert f(float(i)) == i + 1
  222. assert f() == 3.0
  223. class C:
  224. def __init__(self, x: float) -> None:
  225. self.x = x
  226. def test_float_attr() -> None:
  227. for i in range(-200, 200):
  228. f = float(i)
  229. c = C(f)
  230. assert c.x == f
  231. a: Any = c
  232. assert a.x == f
  233. c.x = FLOAT_MAGIC
  234. assert c.x == FLOAT_MAGIC
  235. assert a.x == FLOAT_MAGIC
  236. a.x = 1.0
  237. assert a.x == 1.0
  238. a.x = FLOAT_MAGIC
  239. assert a.x == FLOAT_MAGIC
  240. class D:
  241. def __init__(self, x: float) -> None:
  242. if x:
  243. self.x = x
  244. def test_float_attr_maybe_undefned() -> None:
  245. for i in range(-200, 200):
  246. if i == 0:
  247. d = D(0.0)
  248. with assertRaises(AttributeError):
  249. d.x
  250. a: Any = d
  251. with assertRaises(AttributeError):
  252. a.x
  253. d.x = FLOAT_MAGIC
  254. assert d.x == FLOAT_MAGIC
  255. assert a.x == FLOAT_MAGIC
  256. d.x = 0.0
  257. assert d.x == 0.0
  258. assert a.x == 0.0
  259. a.x = FLOAT_MAGIC
  260. assert a.x == FLOAT_MAGIC
  261. d = D(0.0)
  262. a = cast(Any, d)
  263. a.x = FLOAT_MAGIC
  264. assert d.x == FLOAT_MAGIC
  265. else:
  266. f = float(i)
  267. d = D(f)
  268. assert d.x == f
  269. a2: Any = d
  270. assert a2.x == f
  271. def f(x: float) -> float:
  272. return x + 1
  273. def test_return_values() -> None:
  274. a: Any = f
  275. for i in range(-200, 200):
  276. x = float(i)
  277. assert f(x) == x + 1
  278. assert a(x) == x + 1
  279. for x in float_vals:
  280. if not math.isnan(x):
  281. assert f(x) == x + 1
  282. else:
  283. assert math.isnan(f(x))
  284. def exc() -> float:
  285. raise IndexError('x')
  286. def test_exception() -> None:
  287. with assertRaises(IndexError):
  288. exc()
  289. a: Any = exc
  290. with assertRaises(IndexError):
  291. a()
  292. def test_undefined_local_var() -> None:
  293. if not int():
  294. x = -113.0
  295. assert x == -113.0
  296. if int():
  297. y = -113.0
  298. with assertRaises(UnboundLocalError, 'local variable "y" referenced before assignment'):
  299. print(y)
  300. if not int():
  301. x2 = -1.0
  302. assert x2 == -1.0
  303. if int():
  304. y2 = -1.0
  305. with assertRaises(UnboundLocalError, 'local variable "y2" referenced before assignment'):
  306. print(y2)
  307. def test_tuples() -> None:
  308. t1: tuple[float, float] = (1.5, 2.5)
  309. assert t1 == tuple([1.5, 2.5])
  310. n = int() + 5
  311. t2: tuple[float, float, float, float] = (n, 1.5, -7, -113)
  312. assert t2 == tuple([5.0, 1.5, -7.0, -113.0])
  313. [case testFloatGlueMethodsAndInheritance]
  314. from typing import Any
  315. from typing_extensions import Final
  316. from mypy_extensions import trait
  317. from testutil import assertRaises
  318. MAGIC: Final = -113.0
  319. class Base:
  320. def foo(self) -> float:
  321. return 5.0
  322. def bar(self, x: float = 2.0) -> float:
  323. return x + 1
  324. def hoho(self, x: float) -> float:
  325. return x - 1
  326. class Derived(Base):
  327. def foo(self, x: float = 5.0) -> float:
  328. return x + 10
  329. def bar(self, x: float = 3, y: float = 20) -> float:
  330. return x + y + 2
  331. def hoho(self, x: float = 7) -> float:
  332. return x - 2
  333. def test_derived_adds_bitmap() -> None:
  334. b: Base = Derived()
  335. assert b.foo() == 15
  336. def test_derived_adds_another_default_arg() -> None:
  337. b: Base = Derived()
  338. assert b.bar() == 25
  339. assert b.bar(1) == 23
  340. assert b.bar(MAGIC) == MAGIC + 22
  341. def test_derived_switches_arg_to_have_default() -> None:
  342. b: Base = Derived()
  343. assert b.hoho(5) == 3
  344. assert b.hoho(MAGIC) == MAGIC - 2
  345. @trait
  346. class T:
  347. @property
  348. def x(self) -> float: ...
  349. @property
  350. def y(self) -> float: ...
  351. class C(T):
  352. x: float = 1.0
  353. y: float = 4
  354. def test_read_only_property_in_trait_implemented_as_attribute() -> None:
  355. c = C()
  356. c.x = 5.5
  357. assert c.x == 5.5
  358. c.x = MAGIC
  359. assert c.x == MAGIC
  360. assert c.y == 4
  361. c.y = 6.5
  362. assert c.y == 6.5
  363. t: T = C()
  364. assert t.y == 4
  365. t = c
  366. assert t.x == MAGIC
  367. c.x = 55.5
  368. assert t.x == 55.5
  369. assert t.y == 6.5
  370. a: Any = c
  371. assert a.x == 55.5
  372. assert a.y == 6.5
  373. a.x = 7.0
  374. a.y = 8.0
  375. assert a.x == 7
  376. assert a.y == 8
  377. class D(T):
  378. xx: float
  379. @property
  380. def x(self) -> float:
  381. return self.xx
  382. @property
  383. def y(self) -> float:
  384. raise TypeError
  385. def test_read_only_property_in_trait_implemented_as_property() -> None:
  386. d = D()
  387. d.xx = 5.0
  388. assert d.x == 5
  389. d.xx = MAGIC
  390. assert d.x == MAGIC
  391. with assertRaises(TypeError):
  392. d.y
  393. t: T = d
  394. assert t.x == MAGIC
  395. d.xx = 6.0
  396. assert t.x == 6
  397. with assertRaises(TypeError):
  398. t.y
  399. @trait
  400. class T2:
  401. x: float
  402. y: float
  403. class C2(T2):
  404. pass
  405. def test_inherit_trait_attribute() -> None:
  406. c = C2()
  407. c.x = 5.0
  408. assert c.x == 5
  409. c.x = MAGIC
  410. assert c.x == MAGIC
  411. with assertRaises(AttributeError):
  412. c.y
  413. c.y = 6.0
  414. assert c.y == 6.0
  415. t: T2 = C2()
  416. with assertRaises(AttributeError):
  417. t.y
  418. t = c
  419. assert t.x == MAGIC
  420. c.x = 55.0
  421. assert t.x == 55
  422. assert t.y == 6
  423. a: Any = c
  424. assert a.x == 55
  425. assert a.y == 6
  426. a.x = 7.0
  427. a.y = 8.0
  428. assert a.x == 7
  429. assert a.y == 8
  430. class D2(T2):
  431. x: float
  432. y: float = 4
  433. def test_implement_trait_attribute() -> None:
  434. d = D2()
  435. d.x = 5.0
  436. assert d.x == 5
  437. d.x = MAGIC
  438. assert d.x == MAGIC
  439. assert d.y == 4
  440. d.y = 6.0
  441. assert d.y == 6
  442. t: T2 = D2()
  443. assert t.y == 4
  444. t = d
  445. assert t.x == MAGIC
  446. d.x = 55.0
  447. assert t.x == 55
  448. assert t.y == 6
  449. a: Any = d
  450. assert a.x == 55
  451. assert a.y == 6
  452. a.x = 7.0
  453. a.y = 8.0
  454. assert a.x == 7
  455. assert a.y == 8