Значение номеров ошибок в исключениях Python

Поймав OverflowError Python после некоторых глупых вычислений, я проверил args ошибки и увидел, что это кортеж, содержащий целое число в качестве его первой координаты. Я предполагаю, что это какой-то номер ошибки (errno). Однако я не смог найти никакой документации или ссылки на него.

Пример:

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

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

Вы знаете, что означает 34 в этом контексте? Знаете ли вы другие возможные номера ошибок для этого исключения?


person Bach    schedule 09.04.2014    source источник
comment
Для справки, 1E400 не может быть представлен как двойной, который является обычным внутренним представление Python с плавающей запятой.   -  person Gassa    schedule 09.04.2014
comment
Для другой записи 1e400 равно inf в python 2.7 (как показывает math.isinf(1e400)).   -  person Bach    schedule 09.04.2014


Ответы (1)


В стандартной библиотеке есть модуль под названием errno:

Этот модуль делает доступными стандартные системные символы errno. Значением каждого символа является соответствующее целочисленное значение. Имена и описания заимствованы из linux/include/errno.h, который должен быть всеобъемлющим.

/usr/include/linux/errno.h включает /usr/include/asm/errno.h, который включает /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 */

Теперь мы знаем, что код ошибки 34 означает ERANGE.

1e4**100 обрабатывается с помощью float_pow function из Object/floatobject.c. Частичный исходный код этой функции:

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);
}

Таким образом, 1e4**100 вызывает ошибку ERANGE (что приводит к PyExc_OverflowError), а затем возникает исключение более высокого уровня OverflowError.

person vaultah    schedule 09.04.2014
comment
Это мило. Я считаю, что у меня точно такой же результат, как и у вас. - person Bach; 09.04.2014