Skip to content
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

Document the meaning of the number in OverflowError #91290

Open
stevendaprano opened this issue Mar 26, 2022 · 3 comments
Open

Document the meaning of the number in OverflowError #91290

stevendaprano opened this issue Mar 26, 2022 · 3 comments
Labels
3.7 (EOL) end of life 3.8 only security fixes 3.9 only security fixes 3.10 only security fixes 3.11 only security fixes docs Documentation in the Doc dir type-feature A feature request or enhancement

Comments

@stevendaprano
Copy link
Member

BPO 47134
Nosy @stevendaprano, @eryksun

Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

Show more details

GitHub fields:

assignee = None
closed_at = None
created_at = <Date 2022-03-26.22:10:10.212>
labels = ['3.7', '3.8', '3.9', '3.10', '3.11', 'type-feature', 'docs']
title = 'Document the meaning of the number in OverflowError'
updated_at = <Date 2022-03-26.22:46:01.129>
user = 'https://github.com/stevendaprano'

bugs.python.org fields:

activity = <Date 2022-03-26.22:46:01.129>
actor = 'eryksun'
assignee = 'docs@python'
closed = False
closed_date = None
closer = None
components = ['Documentation']
creation = <Date 2022-03-26.22:10:10.212>
creator = 'steven.daprano'
dependencies = []
files = []
hgrepos = []
issue_num = 47134
keywords = []
message_count = 2.0
messages = ['416093', '416096']
nosy_count = 3.0
nosy_names = ['steven.daprano', 'docs@python', 'eryksun']
pr_nums = []
priority = 'normal'
resolution = None
stage = None
status = 'open'
superseder = None
type = 'enhancement'
url = 'https://bugs.python.org/issue47134'
versions = ['Python 3.7', 'Python 3.8', 'Python 3.9', 'Python 3.10', 'Python 3.11']

@stevendaprano
Copy link
Member Author

OverflowError sometimes (but not always) includes some sort of numeric code:

>>> 1e+300 ** 2
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OverflowError: (34, 'Numerical result out of range')

but the meaning of the 34 is not documented:

https://docs.python.org/3/library/exceptions.html#OverflowError

help(OverflowError) is no more insightful, saying only:

    __init__(self, /, *args, **kwargs)
        Initialize self.  See help(type(self)) for accurate signature.

Other OverflowError exceptions do not include the numeric code:

>>> math.exp(10000)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OverflowError: math range error

Is it an error code from C? Something to do with the number of digits of precision? An easter-egg to do with The Count Of Monte Cristo?

@stevendaprano stevendaprano added 3.7 (EOL) end of life 3.8 only security fixes 3.9 only security fixes 3.10 only security fixes 3.11 only security fixes labels Mar 26, 2022
@stevendaprano stevendaprano added 3.9 only security fixes docs Documentation in the Doc dir 3.10 only security fixes type-feature A feature request or enhancement 3.11 only security fixes labels Mar 26, 2022
@stevendaprano stevendaprano added docs Documentation in the Doc dir type-feature A feature request or enhancement labels Mar 26, 2022
@eryksun
Copy link
Contributor

eryksun commented Mar 26, 2022

The error code for 1e+300 ** 2 is ERANGE, from calling libm pow(). Since pow() returns a double, there's no way to indicate an error in the return value. Instead, C errno is set to 0 beforehand and checked for a non-zero error value after the call. If the error code isn't ERANGE, then float.pow() raises ValueError instead of OverflowError. Here's the relevant snippet from float_pow() in Objects/floatobject.c:

/* Now iv and iw are finite, iw is nonzero, and iv is
 * positive and not equal to 1.0.  We finally allow
 * the platform pow to step in and do the rest.
 */
errno = 0;
ix = pow(iv, iw);
_Py_ADJUST_ERANGE1(ix);
if (negate_result)
    ix = -ix;
    if (errno != 0) {
        /* We don't expect any errno value other than ERANGE, but
         * the range of libm bugs appears unbounded.
         */
        PyErr_SetFromErrno(errno == ERANGE ? PyExc_OverflowError :
                             PyExc_ValueError);
        return NULL;
    }
    return PyFloat_FromDouble(ix);

Here's a direct example using ctypes:

    import ctypes
    import errno

    libm = ctypes.CDLL('libm.so.6', use_errno=True)
    libm.pow.argtypes = (ctypes.c_double, ctypes.c_double)
    libm.pow.restype = ctypes.c_double
    >>> errno.ERANGE
    34
    >>> ctypes.set_errno(0)
    0
    >>> libm.pow(1e300, 2)
    inf
    >>> ctypes.get_errno() == errno.ERANGE
    True

@ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
@slateny
Copy link
Contributor

slateny commented Sep 9, 2022

For improvements, maybe the errno page can directly list the constant equivalents, and then the page could be referenced in the exceptions page?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
3.7 (EOL) end of life 3.8 only security fixes 3.9 only security fixes 3.10 only security fixes 3.11 only security fixes docs Documentation in the Doc dir type-feature A feature request or enhancement
Projects
None yet
Development

No branches or pull requests

3 participants