-
-
Notifications
You must be signed in to change notification settings - Fork 30.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
gh-101410: support custom messages for domain errors in the math module #124299
base: main
Are you sure you want to change the base?
Conversation
…h module This adds basic support to override default messages for domain errors in the math_1() helper. The sqrt(), atanh(), log2(), log10() and log() functions were modified as examples. New macro supports gradual changing of error messages in other 1-arg functions. Co-authored-by: Sergey B Kirpichev <skirpichev@gmail.com>
#101492 somehow stuck, here I would like to continue this work. @CharlieZhao95, are you ok with this? The given pr introduces a new macro and change only few functions, that covers all cases in math_1(). I hope, this also address reviews in the mentioned pr (tests added, error messages print converted argument, etc). I kept only short error messages. Not sure if it worth printing the function name, as it usually shown in tracebacks. >>> import math
>>> for i in range(5, -10, -2):
... print(math.log(i))
...
1.6094379124341003
1.0986122886681098
0.0
Traceback (most recent call last):
File "<python-input-1>", line 2, in <module>
print(math.log(i))
~~~~~~~~^^^
ValueError: expected a positive input, got -1 Not sure also if we must suggest cmath in error messages. But if we decide to do so, probably it does make sense for almost every domain error in the math module and we can do this with a template. diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c
index 665b02e702..c4516fabda 100644
--- a/Modules/mathmodule.c
+++ b/Modules/mathmodule.c
@@ -1046,7 +1046,11 @@ math_2(PyObject *const *args, Py_ssize_t nargs,
#define FUNC1D(funcname, func, can_overflow, docstring, err_msg) \
static PyObject * math_##funcname(PyObject *self, PyObject *args) { \
- return math_1(args, func, can_overflow, err_msg); \
+ return math_1(args, func, can_overflow, \
+ (err_msg \
+ "\nSee cmath." \
+ #funcname \
+ "(), that supports complex numbers")); \
}\
PyDoc_STRVAR(math_##funcname##_doc, docstring);
CC @rhettinger as author of the issue, I would appreciate feedback |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me. Just some nitpicks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
More informative error messages is good, but I afraid that the cost may be too high. If this is really an error due to invalid input data, then some cost is more tolerable. But if the exception is used in the EAFP style of solving computational error (for example, the argument of sqrt()
in sqrt(b*b-4*a*c)
can be a small negative number due to limited precision computation and can be replaced by 0), additional cost harms the average performance.
But it's only printing. Currently, math_1() uses PyFloat_FromDouble() for converted by PyFloat_AsDouble() value; well, maybe I should just use PyOS_double_to_string(). Anyway it doesn't seems to be too expensive in either way. On another hand, with this - we don't print the original value of the argument (something like Fraction(1/2**1000). Maybe it's better to omit the value at all? |
If include the value, it should be a converted value, not the original value, because conversion can change the value (for example turn a small positive value into 0). The repr of the original value has also larger chance to produce long and expensive result. |
This is how it works. loghelper() is an exception. I see only one solution for loghelper(): use two messages. One for PyLong-branch (this message will come from loghelper argument to distinguish arguments of 2-arg form) and a common template for the math_1() fallback. |
* use PyOS_double_to_string * drop loghelper arg * don't print argument value in PyLong-branch of loghelper()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you. You addressed all my concerns. Extreme slow cases were removed, and formatting error messages in common case was optimized.
I would approve this PR, but I want first to know opinion of the author of the request, @rhettinger.
And I think that we can add custom error messages for more functions: acos(), asin(), gamma(), lgamma(). Maybe pow(), where rules are complex.
I would prefer to make first required changes in helpers. This pr changes math_1(). Following pr can add custom error messages for all math_1-based functions, it will be mostly mechanical process. Then we can address e.g. atan2 and pow. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for continuing this work! A simple comment here :)
A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated. Once you have made the requested changes, please leave a comment on this pull request containing the phrase |
I have made the requested changes; please review again |
Thanks for making the requested changes! @JelleZijlstra: please review the changes made to this pull request. |
Ok, as Serhiy interested in Raymond's opinion, I've asked for review. Meanwhile, I've added one another commit (I feel this pr isn't too big for review). With this, all 1-arg functions should be covered. I would prefer, if specific error messages will be added in a separate pr. PR description adjusted. |
Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com>
This adds basic support to override default messages for domain errors in the math_1() and math_1a() helpers. The sqrt(), atanh(), log2(), log10(), log() and gamma() functions were modified as examples. New macros support gradual changing of error messages in other 1-arg functions.