From 77a643c7c5c896a80dc8bc580f14f7ef6bd341be Mon Sep 17 00:00:00 2001 From: Sergey B Kirpichev Date: Fri, 31 Jan 2025 07:41:34 +0300 Subject: [PATCH 1/8] gh-101410: customize error messages for 1-arg math functions This also reverts loghelper() change in 75f59bb629 for integer input. The error message shouldn't include argument value here. --- Lib/test/mathdata/ieee754.txt | 16 ++++++------ Lib/test/test_math.py | 2 +- Modules/mathmodule.c | 46 +++++++++++++++++++++-------------- 3 files changed, 37 insertions(+), 27 deletions(-) diff --git a/Lib/test/mathdata/ieee754.txt b/Lib/test/mathdata/ieee754.txt index 0dac69040ad011..9be667826a6001 100644 --- a/Lib/test/mathdata/ieee754.txt +++ b/Lib/test/mathdata/ieee754.txt @@ -127,31 +127,31 @@ Trigonometric Functions >>> sin(INF) Traceback (most recent call last): ... -ValueError: math domain error +ValueError: expected a finite input, got inf >>> sin(NINF) Traceback (most recent call last): ... -ValueError: math domain error +ValueError: expected a finite input, got -inf >>> sin(NAN) nan >>> cos(INF) Traceback (most recent call last): ... -ValueError: math domain error +ValueError: expected a finite input, got inf >>> cos(NINF) Traceback (most recent call last): ... -ValueError: math domain error +ValueError: expected a finite input, got -inf >>> cos(NAN) nan >>> tan(INF) Traceback (most recent call last): ... -ValueError: math domain error +ValueError: expected a finite input, got inf >>> tan(NINF) Traceback (most recent call last): ... -ValueError: math domain error +ValueError: expected a finite input, got -inf >>> tan(NAN) nan @@ -169,11 +169,11 @@ True >>> asin(INF), asin(NINF) Traceback (most recent call last): ... -ValueError: math domain error +ValueError: expected a number in range from -1 up to 1, got inf >>> acos(INF), acos(NINF) Traceback (most recent call last): ... -ValueError: math domain error +ValueError: expected a number in range from -1 up to 1, got inf >>> equal(atan(INF), PI/2), equal(atan(NINF), -PI/2) (True, True) diff --git a/Lib/test/test_math.py b/Lib/test/test_math.py index 2c57d288bc03ff..05ca591ff3a5ae 100644 --- a/Lib/test/test_math.py +++ b/Lib/test/test_math.py @@ -2533,7 +2533,7 @@ def test_exception_messages(self): math.log(x) x = -123 with self.assertRaisesRegex(ValueError, - f"expected a positive input, got {x}"): + f"expected a positive input"): math.log(x) with self.assertRaisesRegex(ValueError, f"expected a float or nonnegative integer, got {x}"): diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c index b4c15a143f9838..231e8371c5c530 100644 --- a/Modules/mathmodule.c +++ b/Modules/mathmodule.c @@ -1089,17 +1089,20 @@ math_2(PyObject *const *args, Py_ssize_t nargs, }\ PyDoc_STRVAR(math_##funcname##_doc, docstring); -FUNC1(acos, acos, 0, +FUNC1D(acos, acos, 0, "acos($module, x, /)\n--\n\n" "Return the arc cosine (measured in radians) of x.\n\n" - "The result is between 0 and pi.") -FUNC1(acosh, acosh, 0, + "The result is between 0 and pi.", + "expected a number in range from -1 up to 1, got %s") +FUNC1D(acosh, acosh, 0, "acosh($module, x, /)\n--\n\n" - "Return the inverse hyperbolic cosine of x.") -FUNC1(asin, asin, 0, + "Return the inverse hyperbolic cosine of x.", + "expected argument value not less than 1, got %s") +FUNC1D(asin, asin, 0, "asin($module, x, /)\n--\n\n" "Return the arc sine (measured in radians) of x.\n\n" - "The result is between -pi/2 and pi/2.") + "The result is between -pi/2 and pi/2.", + "expected a number in range from -1 up to 1, got %s") FUNC1(asinh, asinh, 0, "asinh($module, x, /)\n--\n\n" "Return the inverse hyperbolic sine of x.") @@ -1161,9 +1164,10 @@ FUNC2(copysign, copysign, "Return a float with the magnitude (absolute value) of x but the sign of y.\n\n" "On platforms that support signed zeros, copysign(1.0, -0.0)\n" "returns -1.0.\n") -FUNC1(cos, cos, 0, +FUNC1D(cos, cos, 0, "cos($module, x, /)\n--\n\n" - "Return the cosine of x (measured in radians).") + "Return the cosine of x (measured in radians).", + "expected a finite input, got %s") FUNC1(cosh, cosh, 1, "cosh($module, x, /)\n--\n\n" "Return the hyperbolic cosine of x.") @@ -1229,22 +1233,25 @@ FUNC1AD(gamma, m_tgamma, "gamma($module, x, /)\n--\n\n" "Gamma function at x.", "expected a float or nonnegative integer, got %s") -FUNC1A(lgamma, m_lgamma, +FUNC1AD(lgamma, m_lgamma, "lgamma($module, x, /)\n--\n\n" - "Natural logarithm of absolute value of Gamma function at x.") -FUNC1(log1p, m_log1p, 0, + "Natural logarithm of absolute value of Gamma function at x.", + "expected a float or nonnegative integer, got %s") +FUNC1D(log1p, m_log1p, 0, "log1p($module, x, /)\n--\n\n" "Return the natural logarithm of 1+x (base e).\n\n" - "The result is computed in a way which is accurate for x near zero.") + "The result is computed in a way which is accurate for x near zero.", + "expected argument value > -1, got %s") FUNC2(remainder, m_remainder, "remainder($module, x, y, /)\n--\n\n" "Difference between x and the closest integer multiple of y.\n\n" "Return x - n*y where n*y is the closest integer multiple of y.\n" "In the case where x is exactly halfway between two multiples of\n" "y, the nearest even value of n is used. The result is always exact.") -FUNC1(sin, sin, 0, +FUNC1D(sin, sin, 0, "sin($module, x, /)\n--\n\n" - "Return the sine of x (measured in radians).") + "Return the sine of x (measured in radians).", + "expected a finite input, got %s") FUNC1(sinh, sinh, 1, "sinh($module, x, /)\n--\n\n" "Return the hyperbolic sine of x.") @@ -1252,9 +1259,10 @@ FUNC1D(sqrt, sqrt, 0, "sqrt($module, x, /)\n--\n\n" "Return the square root of x.", "expected a nonnegative input, got %s") -FUNC1(tan, tan, 0, +FUNC1D(tan, tan, 0, "tan($module, x, /)\n--\n\n" - "Return the tangent of x (measured in radians).") + "Return the tangent of x (measured in radians).", + "expected a finite input, got %s") FUNC1(tanh, tanh, 0, "tanh($module, x, /)\n--\n\n" "Return the hyperbolic tangent of x.") @@ -2232,8 +2240,10 @@ loghelper(PyObject* arg, double (*func)(double)) /* Negative or zero inputs give a ValueError. */ if (!_PyLong_IsPositive((PyLongObject *)arg)) { - PyErr_Format(PyExc_ValueError, - "expected a positive input, got %S", arg); + /* The input can be an arbitrary large integer, so we + don't include it's value in the error message. */ + PyErr_SetString(PyExc_ValueError, + "expected a positive input"); return NULL; } From d88b55f2df8797e850a39a098148c30684692356 Mon Sep 17 00:00:00 2001 From: Sergey B Kirpichev Date: Fri, 31 Jan 2025 07:47:35 +0300 Subject: [PATCH 2/8] + news --- .../Library/2023-02-01-16-41-31.gh-issue-101410.Dt2aQE.rst | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Misc/NEWS.d/next/Library/2023-02-01-16-41-31.gh-issue-101410.Dt2aQE.rst b/Misc/NEWS.d/next/Library/2023-02-01-16-41-31.gh-issue-101410.Dt2aQE.rst index 31493686daec97..e512fcea88e557 100644 --- a/Misc/NEWS.d/next/Library/2023-02-01-16-41-31.gh-issue-101410.Dt2aQE.rst +++ b/Misc/NEWS.d/next/Library/2023-02-01-16-41-31.gh-issue-101410.Dt2aQE.rst @@ -1,3 +1,2 @@ -Support custom messages for domain errors in the :mod:`math` module -(:func:`math.sqrt`, :func:`math.log` and :func:`math.atanh` were modified as -examples). Patch by Charlie Zhao and Sergey B Kirpichev. +Support custom messages for domain errors in the :mod:`math` module. +Patch by Charlie Zhao and Sergey B Kirpichev. From b99661eea8af85b891c5aaa7f791bc1fceebec5a Mon Sep 17 00:00:00 2001 From: Sergey B Kirpichev Date: Tue, 4 Feb 2025 03:18:04 +0300 Subject: [PATCH 3/8] Update Lib/test/test_math.py --- Lib/test/test_math.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/test_math.py b/Lib/test/test_math.py index 05ca591ff3a5ae..8910e16aad5536 100644 --- a/Lib/test/test_math.py +++ b/Lib/test/test_math.py @@ -2533,7 +2533,7 @@ def test_exception_messages(self): math.log(x) x = -123 with self.assertRaisesRegex(ValueError, - f"expected a positive input"): + "expected a positive input"): math.log(x) with self.assertRaisesRegex(ValueError, f"expected a float or nonnegative integer, got {x}"): From 81ae02603a17a04edaab29def6c8bfa8652eff77 Mon Sep 17 00:00:00 2001 From: Sergey B Kirpichev Date: Thu, 6 Feb 2025 05:20:57 +0300 Subject: [PATCH 4/8] address review: correct gamma/lgamma error msgs --- Lib/test/test_math.py | 2 +- Modules/mathmodule.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Lib/test/test_math.py b/Lib/test/test_math.py index 8910e16aad5536..ccab9efcc21004 100644 --- a/Lib/test/test_math.py +++ b/Lib/test/test_math.py @@ -2536,7 +2536,7 @@ def test_exception_messages(self): "expected a positive input"): math.log(x) with self.assertRaisesRegex(ValueError, - f"expected a float or nonnegative integer, got {x}"): + f"expected a float or positive integer, got {x}"): math.gamma(x) x = 1.0 with self.assertRaisesRegex(ValueError, diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c index 231e8371c5c530..d6b0d0d97ec5bc 100644 --- a/Modules/mathmodule.c +++ b/Modules/mathmodule.c @@ -1232,11 +1232,11 @@ math_floor(PyObject *module, PyObject *number) FUNC1AD(gamma, m_tgamma, "gamma($module, x, /)\n--\n\n" "Gamma function at x.", - "expected a float or nonnegative integer, got %s") + "expected a float or positive integer, got %s") FUNC1AD(lgamma, m_lgamma, "lgamma($module, x, /)\n--\n\n" "Natural logarithm of absolute value of Gamma function at x.", - "expected a float or nonnegative integer, got %s") + "expected a float or positive integer, got %s") FUNC1D(log1p, m_log1p, 0, "log1p($module, x, /)\n--\n\n" "Return the natural logarithm of 1+x (base e).\n\n" From 11365cb72e7aed52d812397b5042ce59f6b6f3b6 Mon Sep 17 00:00:00 2001 From: Sergey B Kirpichev Date: Thu, 6 Feb 2025 13:31:57 +0300 Subject: [PATCH 5/8] Update Misc/NEWS.d/next/Library/2023-02-01-16-41-31.gh-issue-101410.Dt2aQE.rst --- .../Library/2023-02-01-16-41-31.gh-issue-101410.Dt2aQE.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Library/2023-02-01-16-41-31.gh-issue-101410.Dt2aQE.rst b/Misc/NEWS.d/next/Library/2023-02-01-16-41-31.gh-issue-101410.Dt2aQE.rst index e512fcea88e557..655f434dbfdc1b 100644 --- a/Misc/NEWS.d/next/Library/2023-02-01-16-41-31.gh-issue-101410.Dt2aQE.rst +++ b/Misc/NEWS.d/next/Library/2023-02-01-16-41-31.gh-issue-101410.Dt2aQE.rst @@ -1,2 +1,3 @@ -Support custom messages for domain errors in the :mod:`math` module. +Added more detailed messages for domain errors in the :mod:`math` module. +Patch by Charlie Zhao and Sergey B Kirpichev. Patch by Charlie Zhao and Sergey B Kirpichev. From 53b68c2f05d55982efacce2fb83efd99e7356495 Mon Sep 17 00:00:00 2001 From: Sergey B Kirpichev Date: Thu, 6 Feb 2025 14:42:01 +0300 Subject: [PATCH 6/8] address review: fix typo in news & gamma/lgamma error messages --- Lib/test/test_math.py | 2 +- .../Library/2023-02-01-16-41-31.gh-issue-101410.Dt2aQE.rst | 1 - Modules/mathmodule.c | 4 ++-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/Lib/test/test_math.py b/Lib/test/test_math.py index ccab9efcc21004..7588d6b89d41d6 100644 --- a/Lib/test/test_math.py +++ b/Lib/test/test_math.py @@ -2536,7 +2536,7 @@ def test_exception_messages(self): "expected a positive input"): math.log(x) with self.assertRaisesRegex(ValueError, - f"expected a float or positive integer, got {x}"): + f"expected a noninteger or positive integer, got {x}"): math.gamma(x) x = 1.0 with self.assertRaisesRegex(ValueError, diff --git a/Misc/NEWS.d/next/Library/2023-02-01-16-41-31.gh-issue-101410.Dt2aQE.rst b/Misc/NEWS.d/next/Library/2023-02-01-16-41-31.gh-issue-101410.Dt2aQE.rst index 655f434dbfdc1b..165216a414c1c7 100644 --- a/Misc/NEWS.d/next/Library/2023-02-01-16-41-31.gh-issue-101410.Dt2aQE.rst +++ b/Misc/NEWS.d/next/Library/2023-02-01-16-41-31.gh-issue-101410.Dt2aQE.rst @@ -1,3 +1,2 @@ Added more detailed messages for domain errors in the :mod:`math` module. Patch by Charlie Zhao and Sergey B Kirpichev. -Patch by Charlie Zhao and Sergey B Kirpichev. diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c index d6b0d0d97ec5bc..e493c60fbe4ce6 100644 --- a/Modules/mathmodule.c +++ b/Modules/mathmodule.c @@ -1232,11 +1232,11 @@ math_floor(PyObject *module, PyObject *number) FUNC1AD(gamma, m_tgamma, "gamma($module, x, /)\n--\n\n" "Gamma function at x.", - "expected a float or positive integer, got %s") + "expected a noninteger or positive integer, got %s") FUNC1AD(lgamma, m_lgamma, "lgamma($module, x, /)\n--\n\n" "Natural logarithm of absolute value of Gamma function at x.", - "expected a float or positive integer, got %s") + "expected a noninteger or positive integer, got %s") FUNC1D(log1p, m_log1p, 0, "log1p($module, x, /)\n--\n\n" "Return the natural logarithm of 1+x (base e).\n\n" From 8edc47d14a0ab7b662e5a92a00fbf1d1d422fe1e Mon Sep 17 00:00:00 2001 From: Sergey B Kirpichev Date: Sat, 29 Mar 2025 10:35:50 +0300 Subject: [PATCH 7/8] add news to whatsnew --- Doc/whatsnew/3.14.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Doc/whatsnew/3.14.rst b/Doc/whatsnew/3.14.rst index ac5b53ef94bfb1..4db98f0d4d73a4 100644 --- a/Doc/whatsnew/3.14.rst +++ b/Doc/whatsnew/3.14.rst @@ -679,6 +679,13 @@ json (Contributed by Trey Hunner in :gh:`122873`.) +math +---- + +* Added more detailed messages for domain errors in the module. + (Contributed by by Charlie Zhao and Sergey B Kirpichev in :gh:`101410`.) + + mimetypes --------- From 8939f2be83a60d1be7e9626cc0c075a670e30cc5 Mon Sep 17 00:00:00 2001 From: Sergey B Kirpichev Date: Sat, 29 Mar 2025 13:04:29 +0300 Subject: [PATCH 8/8] Update Doc/whatsnew/3.14.rst Co-authored-by: Victor Stinner --- Doc/whatsnew/3.14.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/whatsnew/3.14.rst b/Doc/whatsnew/3.14.rst index 4db98f0d4d73a4..6aeb5dd0b23bb0 100644 --- a/Doc/whatsnew/3.14.rst +++ b/Doc/whatsnew/3.14.rst @@ -682,7 +682,7 @@ json math ---- -* Added more detailed messages for domain errors in the module. +* Added more detailed error messages for domain errors in the module. (Contributed by by Charlie Zhao and Sergey B Kirpichev in :gh:`101410`.)