Files
micropython/tests/float/math_fun.py
Alessandro Gatti eae83df201 tests/float/math_fun: Fix domain error tests with CPython 3.14.
This commit makes tests exercising certain math functions' limit work
when using CPython 3.14 to validate the tests' output.

CPython 3.14 introduced more descriptive messages when math domain error
conditions are encountered rather than a single generic message.  This
breaks the tests in question as MicroPython uses a single error message
when reporting these conditions (both to closely follow CPython and to
save firmware space).

The math domain tests now look for an error pattern that is compatible
with both CPython 3.14 and previous versions, converting messages in the
newer format into the previous one.  This makes the tests' behaviour
under MicroPython comparable with CPython for the foreseeable future.

Signed-off-by: Alessandro Gatti <a.gatti@frob.it>
2026-01-15 20:53:33 +01:00

94 lines
2.8 KiB
Python

# Tests the functions imported from math
try:
from math import *
except ImportError:
print("SKIP")
raise SystemExit
test_values = [-100.0, -1.23456, -1, -0.5, 0.0, 0.5, 1.23456, 100.0]
test_values_small = [
-10.0,
-1.23456,
-1,
-0.5,
0.0,
0.5,
1.23456,
10.0,
] # so we don't overflow 32-bit precision
unit_range_test_values = [-1.0, -0.75, -0.5, -0.25, 0.0, 0.25, 0.5, 0.75, 1.0]
functions = [
("sqrt", sqrt, test_values),
("exp", exp, test_values_small),
("log", log, test_values),
("cos", cos, test_values),
("sin", sin, test_values),
("tan", tan, test_values),
("acos", acos, unit_range_test_values),
("asin", asin, unit_range_test_values),
("atan", atan, test_values),
("ceil", ceil, test_values),
("fabs", fabs, test_values),
("floor", floor, test_values),
("trunc", trunc, test_values),
("radians", radians, test_values),
("degrees", degrees, test_values),
]
for function_name, function, test_vals in functions:
for value in test_vals:
try:
ans = "{:.5g}".format(function(value))
except ValueError as e:
ans = str(e)
if ans.startswith("expected a "):
# CPython 3.14 changed messages to be more detailed; convert them back to simple ones
ans = "math domain error"
print("{}({:.5g}) = {}".format(function_name, value, ans))
tuple_functions = [
("frexp", frexp, test_values),
("modf", modf, test_values),
]
for function_name, function, test_vals in tuple_functions:
for value in test_vals:
x, y = function(value)
print("{}({:.5g}) = ({:.5g}, {:.5g})".format(function_name, value, x, y))
binary_functions = [
(
"copysign",
copysign,
[(23.0, 42.0), (-23.0, 42.0), (23.0, -42.0), (-23.0, -42.0), (1.0, 0.0), (1.0, -0.0)],
),
("pow", pow, ((1.0, 0.0), (0.0, 1.0), (2.0, 0.5), (-3.0, 5.0), (-3.0, -4.0))),
("atan2", atan2, ((1.0, 0.0), (0.0, 1.0), (2.0, 0.5), (-3.0, 5.0), (-3.0, -4.0))),
("fmod", fmod, ((1.0, 1.0), (0.0, 1.0), (2.0, 0.5), (-3.0, 5.0), (-3.0, -4.0))),
("ldexp", ldexp, ((1.0, 0), (0.0, 1), (2.0, 2), (3.0, -2), (-3.0, -4))),
(
"log",
log,
(
(2.0, 2.0),
(3.0, 2.0),
(4.0, 5.0),
(0.0, 1.0),
(1.0, 0.0),
(-1.0, 1.0),
(1.0, -1.0),
(2.0, 1.0),
),
),
]
for function_name, function, test_vals in binary_functions:
for value1, value2 in test_vals:
try:
ans = "{:.5g}".format(function(value1, value2))
except (ValueError, ZeroDivisionError) as e:
ans = type(e)
print("{}({:.5g}, {:.5g}) = {}".format(function_name, value1, value2, ans))