This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author eryksun
Recipients docs@python, eryksun, steven.daprano
Date 2022-03-26.22:46:01
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <>
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);
    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 :
        return NULL;
    return PyFloat_FromDouble(ix);

Here's a direct example using ctypes:

    import ctypes
    import errno

    libm = ctypes.CDLL('', use_errno=True)
    libm.pow.argtypes = (ctypes.c_double, ctypes.c_double)
    libm.pow.restype = ctypes.c_double

    >>> errno.ERANGE
    >>> ctypes.set_errno(0)
    >>> libm.pow(1e300, 2)
    >>> ctypes.get_errno() == errno.ERANGE
Date User Action Args
2022-03-26 22:46:01eryksunsetrecipients: + eryksun, steven.daprano, docs@python
2022-03-26 22:46:01eryksunsetmessageid: <>
2022-03-26 22:46:01eryksunlinkissue47134 messages
2022-03-26 22:46:01eryksuncreate