Skip to content

Customize and improve error messages in the math module. #101410

Description

@rhettinger

The default error messages on a several math functions are mostly opaque and and unhelpful.

>>> sqrt(-5)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: math domain error

It would require some effort, but the code could be refactored to give a customized and helpful response, a least in common cases (falling back to the C error code message when the cause is not known):

ValueError:  math.sqrt() expects a non-negative input.  See cmath.sqrt() for variation that supports complex numbers
ValueError:  math.log() requires a non-negative input.   

Linked PRs

Activity

  1. CharlieZhao95 commented on Feb 1, 2023

    @CharlieZhao95
    Contributor

    I checked the error message of sqrt in Julia and here is the result:

    julia> sqrt(-5)
    ERROR: DomainError with -5.0:
    sqrt will only return a complex result if called with a complex argument. Try sqrt(Complex(x)).
    

    Maybe we can also consider adding error messages for input parameters, such as

    >>> sqrt(-5)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    ValueError:  math.sqrt() expects a non-negative input, got '-5.0'.  
    See cmath.sqrt() for variation that supports complex numbers
    

    It seems that we need to expand the macro FUNC1 and the function math_1_to_whatever to add the parameter error_msg to them. Is this a feasible solution? I want to try to work for it. :)

  2. added a commit that references this issue on Dec 5, 2023
  3. added a commit that references this issue on Jul 22, 2024
  4. added a commit that references this issue on Sep 21, 2024
  5. self-assigned this
    on Sep 21, 2024
  6. added 2 commits that reference this issue on Sep 21, 2024
  7. serhiy-storchaka commented on Sep 22, 2024

    @serhiy-storchaka
    Member

    Should the error message contain the value? There is a difference between sqrt() taking -5 and -2.220446049250313e-16. Knowing this difference can help to find an error. Especially if the function definition range is limited from two sides.

    On other side, formatting the repr takes a time, and if the exception is common (it is the result of limited precision in other computations), this can harm the average performance. And for math.log() the input can be an arbitrary large integer. Its decimal representation can be arbitrary long and take arbitrary long time for calculation.

  8. skirpichev commented on Sep 22, 2024

    @skirpichev
    Member

    And for math.log() the input can be an arbitrary large integer.

    math.log() is a special snowflake. I think here we should keep here just a basic message like "expected a positive input" in the branch, that handle large integers.

  9. added a commit that references this issue on Jan 23, 2025
  10. vstinner commented on Jan 23, 2025

    @vstinner
    Member

    Issue implemented in the change 75f59bb.

  11. skirpichev commented on Jan 24, 2025

    @skirpichev
    Member

    No, that just add some infrastructure to support this with few example. Most functions aren't converted yet, though it should be mostly mechanical.

    BTW, latest review change 8d28fd8 should be, probably, reverted - see discussion in this issue right above.

  12. vstinner commented on Jan 24, 2025

    @vstinner
    Member

    @serhiy-storchaka:

    On other side, formatting the repr takes a time, and if the exception is common (it is the result of limited precision in other computations), this can harm the average performance. And for math.log() the input can be an arbitrary large integer. Its decimal representation can be arbitrary long and take arbitrary long time for calculation.

    @skirpichev:

    BTW, latest review change 8d28fd8 should be, probably, reverted - see discussion in this issue right above.

    Oh. str(int) can produce long output for large integers, I forgot that.

    If the change is reverted, please add a comment to explain why the error message doesn't include the argument.

    It reminds me a list.remove(x) change which added repr(x) to the error message: the change introduced a loop on some special objects which produced an infinite output leading to a crash (out of memory):

    commit f6cdc6b4a191b75027de342aa8b5d344fb31313e
    Author: Victor Stinner <vstinner@python.org>
    Date:   Mon Mar 18 14:54:45 2024 +0100
    
        Revert "gh-96844: Improve error message of list.remove (gh-106455)" (#116956)
        
        This reverts commit 217f47d6e5e56bca78b8556e910cd00890f6f84a.
    
  13. added a commit that references this issue on Jan 31, 2025
  14. removed their assignment
    on Feb 1, 2025
  15. added a commit that references this issue on Apr 17, 2025
  16. added a commit that references this issue on Apr 17, 2025
  17. added a commit that references this issue on Apr 22, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    extension-modulesC modules in the Modules dirtype-featureA feature request or enhancement

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions