8

Catching Python's OverflowError after some dumb calculation, I checked the error's args and saw it's a tuple containing an integer as its first coordinate. I assume this is some kind of error number (errno). However, I could not find any documentation or reference for it.

Example:

try:
    1e4**100
except OverflowError as ofe:
    print ofe.args

## prints '(34, 'Numerical result out of range')'

Do you know what 34 means in this context? Do you know other possible error numbers for this exception?

vaultah
  • 44,105
  • 12
  • 114
  • 143
Bach
  • 6,145
  • 7
  • 36
  • 61
  • 1
    For the record, 1E400 is not representable as a [double](http://en.wikipedia.org/wiki/Double-precision_floating-point_format) which is the usual internal representation of Python's float. – Gassa Apr 09 '14 at 07:40
  • For another record, `1e400` equals `inf` in python 2.7 (as `math.isinf(1e400)` shows). – Bach Apr 09 '14 at 07:51

1 Answers1

6

There is a module in the standard library called errno:

This module makes available standard errno system symbols. The value of each symbol is the corresponding integer value. The names and descriptions are borrowed from linux/include/errno.h, which should be pretty all-inclusive.

/usr/include/linux/errno.h includes /usr/include/asm/errno.h that includes /usr/include/asm-generic/errno-base.h.

me@my_pc:~$ cat /usr/include/asm-generic/errno-base.h | grep 34
#define ERANGE      34  /* Math result not representable */

Now we know that the 34 error code stands for ERANGE.

1e4**100 is processed with float_pow function from Object/floatobject.c. Partial source code of that function:

static PyObject *
float_pow(PyObject *v, PyObject *w, PyObject *z)
{
    // 107 lines omitted

    if (errno != 0) {
        /* We do not 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);
}

So, 1e4**100 causes ERANGE error (resulting in PyExc_OverflowError) and then the higher level OverflowError exception raises.

vaultah
  • 44,105
  • 12
  • 114
  • 143