testutil.py 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. # Simple support library for our run tests.
  2. from contextlib import contextmanager
  3. from collections.abc import Iterator
  4. import math
  5. from typing import (
  6. Any, Iterator, TypeVar, Generator, Optional, List, Tuple, Sequence,
  7. Union, Callable, Awaitable,
  8. )
  9. from typing import Final
  10. FLOAT_MAGIC: Final = -113.0
  11. # Various different float values
  12. float_vals = [
  13. float(n) * 0.25 for n in range(-10, 10)
  14. ] + [
  15. -0.0,
  16. 1.0/3.0,
  17. math.sqrt(2.0),
  18. 1.23e200,
  19. -2.34e200,
  20. 5.43e-100,
  21. -6.532e-200,
  22. float('inf'),
  23. -float('inf'),
  24. float('nan'),
  25. FLOAT_MAGIC,
  26. math.pi,
  27. 2.0 * math.pi,
  28. math.pi / 2.0,
  29. -math.pi / 2.0,
  30. -1.7976931348623158e+308, # Smallest finite value
  31. -2.2250738585072014e-308, # Closest to zero negative normal value
  32. -7.5491e-312, # Arbitrary negative subnormal value
  33. -5e-324, # Closest to zero negative subnormal value
  34. 1.7976931348623158e+308, # Largest finite value
  35. 2.2250738585072014e-308, # Closest to zero positive normal value
  36. -6.3492e-312, # Arbitrary positive subnormal value
  37. 5e-324, # Closest to zero positive subnormal value
  38. ]
  39. @contextmanager
  40. def assertRaises(typ: type, msg: str = '') -> Iterator[None]:
  41. try:
  42. yield
  43. except Exception as e:
  44. assert isinstance(e, typ), f"{e!r} is not a {typ.__name__}"
  45. assert msg in str(e), f'Message "{e}" does not match "{msg}"'
  46. else:
  47. assert False, f"Expected {typ.__name__} but got no exception"
  48. def assertDomainError() -> Any:
  49. return assertRaises(ValueError, "math domain error")
  50. def assertMathRangeError() -> Any:
  51. return assertRaises(OverflowError, "math range error")
  52. T = TypeVar('T')
  53. U = TypeVar('U')
  54. V = TypeVar('V')
  55. def run_generator(gen: Generator[T, V, U],
  56. inputs: Optional[List[V]] = None,
  57. p: bool = False) -> Tuple[Sequence[T], Union[U, str]]:
  58. res: List[T] = []
  59. i = -1
  60. while True:
  61. try:
  62. if i >= 0 and inputs:
  63. # ... fixtures don't have send
  64. val = gen.send(inputs[i]) # type: ignore
  65. elif not hasattr(gen, '__next__'): # type: ignore
  66. val = gen.send(None) # type: ignore
  67. else:
  68. val = next(gen)
  69. except StopIteration as e:
  70. return (tuple(res), e.value)
  71. except Exception as e:
  72. return (tuple(res), str(e))
  73. if p:
  74. print(val)
  75. res.append(val)
  76. i += 1
  77. F = TypeVar('F', bound=Callable)
  78. class async_val(Awaitable[V]):
  79. def __init__(self, val: T) -> None:
  80. self.val = val
  81. def __await__(self) -> Generator[T, V, V]:
  82. z = yield self.val
  83. return z
  84. # Wrap a mypyc-generated function in a real python function, to allow it to be
  85. # stuck into classes and the like.
  86. def make_python_function(f: F) -> F:
  87. def g(*args: Any, **kwargs: Any) -> Any:
  88. return f(*args, **kwargs)
  89. return g # type: ignore