gh-101410: Improve error messages in math module#101492
gh-101410: Improve error messages in math module#101492CharlieZhao95 wants to merge 12 commits intopython:mainfrom
Conversation
Modules/mathmodule.c
Outdated
| "Return the square root of x.") | ||
| "Return the square root of x.", | ||
| "math.sqrt() expects a non-negative input, got '%R'.\n" | ||
| "See cmath.sqrt() for variation that supports complex numbers") |
There was a problem hiding this comment.
Perhaps an a before variation would be more correct? Or
See cmath.sqrt(), which also supports negative inputs. I don't know what's better - just a suggestion (:
There was a problem hiding this comment.
Perhaps an
abeforevariationwould be more correct? Or
See cmath.sqrt(), which also supports negative inputs. I don't know what's better - just a suggestion (:
Thanks! It seems reasonable to me to add a. Let's wait for others to reply. :)
|
I guess similar functions and macros can have the same changes (eg |
| if (Py_IS_NAN(r) && !Py_IS_NAN(x)) { | ||
| PyErr_SetString(PyExc_ValueError, | ||
| "math domain error"); /* invalid arg */ | ||
| PyErr_Format(PyExc_ValueError, err_msg, arg); /* invalid arg */ |
There was a problem hiding this comment.
Shouldn't same message be used below on the line 1076 as well (infinite r for finite input)? atanh(-1) is an example.
There was a problem hiding this comment.
Shouldn't same message be used below on the line 1076 as well (infinite r for finite input)? atanh(-1) is an example.
I was wondering if there is a function that can have both input and output( NAN r for non-NAN x and infinite r for finite x).
If such a function exists, it may lead to confusing error messages, because one error message corresponds to two scenarios. I haven't thought of such a function yet, please suggest if it exists. :)
There was a problem hiding this comment.
Same atanh :)
atanh(2) - for the 1st scenario and atanh(1) - for the second. I doubt it will be confusing if you raise instead something like ValueError("atanh expects an argument from (-1, -1), got %R"). I don't think it does make sense to have a different descriptions for pole errors (like atanh(1)). @mdickinson ?
serhiy-storchaka
left a comment
There was a problem hiding this comment.
Would not be better to output the converted C double value x instead of the original Python object arg? The repr of the Python object can be arbitrary long, unlike to the string representation of C double. Also, there may be some errors introduced at converting Python object to C double, not visible from its repr. Although it is much more cumbersome.
|
For example, |
Thanks for your suggestion! I forgot this PR while waiting for others to review it, and it’s time to pick it up :) IMO, it is better to use the C double variable. The only drawback is that we will lose some floating point precision in error message. Does this confuse others? Perhaps this minor flaw is acceptable. # Using double(%f), the default value is six decimal places.
>>> math.sqrt(-math.pi)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: math.sqrt() expects a nonnegative input, got '-3.141593'.
See cmath.sqrt() for a variation that supports complex numbers
>>> math.pi
3.141592653589793
>>> math.sqrt(-0.00000001)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: math.sqrt() expects a nonnegative input, got '-0.000000'.
See cmath.sqrt() for a variation that supports complex numbers |
Perhaps just append ' (rounded)' to the end of the line? A |
|
In most cases functions in the module are 1-arg. I think that if we show the function domain (e.g. |
|
Of course, the output should be more precise and consistent with Python representation, so do not use
Before writing code, wait to see if other core developers (in particular @mdickinson and @tim-one) have something to say about this idea. |
|
FYI, @CharlieZhao95, this branch has unresolved conflicts. Are you planing to finish this? If not, I'll open a pr, based on this work. |
Thanks for reminding! BTW, is it time to continue this PR? Maybe we can make this PR simpler (remove |
picnixz
left a comment
There was a problem hiding this comment.
Can you add tests for checking the new messages?
Misc/NEWS.d/next/Library/2023-02-01-16-41-31.gh-issue-101410.Dt2aQE.rst
Outdated
Show resolved
Hide resolved
| return NULL; | ||
|
|
||
| num = loghelper(args[0], m_log); | ||
| num = loghelper(args[0], m_log, "math.log() expects a positive input, got '%R'."); |
There was a problem hiding this comment.
I don't think using quotes around numbers is relevant. For instance, if it's a custom class of a float that overrides __repr__, then you don't necessarily want to surround the __repr__ by quotes.
| num = loghelper(args[0], m_log, "math.log() expects a positive input, got '%R'."); | |
| num = loghelper(args[0], m_log, "math.log() expects a positive input, got %R."); |
| /*[clinic end generated code: output=5425899a4d5d6acb input=08321262bae4f39b]*/ | ||
| { | ||
| return loghelper(x, m_log2); | ||
| return loghelper(x, m_log2, "math.log2() expects a positive input, got '%R'."); |
| /*[clinic end generated code: output=be72a64617df9c6f input=b2469d02c6469e53]*/ | ||
| { | ||
| return loghelper(x, m_log10); | ||
| return loghelper(x, m_log10, "math.log10() expects a positive input, got '%R'."); |
…t2aQE.rst Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com>
Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com>
Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com>
Sure :) I'm waiting for other core developers to reply. I will add tests after they finalize the solution. |
|
This work continued in #124299 |
Make several math functions support custom error messages.
math.sqrt()andmath.log()now provide more helpful error messages.