Документация Python неофициальный перевод
Содержание страницы

Обработка исключенийException Handling

Функции, описанные в этой главе, позволяют обрабатывать и возбуждать исключения Python. Важно понимать некоторые основы обработки исключений в Python. Механизм в чём-то похож на переменную errno в Unix: существует глобальный индикатор (на поток) последней произошедшей ошибки. Большинство функций не сбрасывают его при успехе, но устанавливают, чтобы указать причину ошибки в случае неудачи. Большинство функций также возвращают индикатор ошибки – обычно NULL, если ожидается возврат указателя, или -1, если возвращается целое число (исключение: функции PyArg_*() возвращают 1 при успехе и 0 при ошибке).

Когда функция должна завершиться ошибкой, потому что вызванная ей функция завершилась ошибкой, она обычно не устанавливает индикатор ошибки; его уже установила вызванная функция. Она отвечает либо за обработку ошибки и очистку исключения, либо за возврат после освобождения всех удерживаемых ресурсов (таких как ссылки на объекты или выделенная память); она не должна продолжать нормальное выполнение, если не готова обработать ошибку. При возврате из-за ошибки важно указать вызывающему коду, что ошибка была установлена. Если ошибка не обрабатывается или не аккуратно распространяется, последующие вызовы Python/C API могут вести себя не так, как задумано, и могут отказать загадочным образом.

Индикатор ошибки состоит из трёх объектов Python, соответствующих результату вызова sys.exc_info(). Существуют функции API для взаимодействия с индикатором ошибки разными способами. Для каждого потока предусмотрен отдельный индикатор ошибки.

void PyErr_PrintEx(int set_sys_last_vars)

Выводит стандартную трассировку в sys.stderr и очищает индикатор ошибки. Вызывайте эту функцию только при установленном индикаторе ошибки (иначе возникнет фатальная ошибка!).

Если set_sys_last_vars не равно нулю, переменные sys.last_type, sys.last_value и sys.last_traceback будут установлены в тип, значение и трассировку напечатанного исключения соответственно.

void PyErr_Print()

Псевдоним для PyErr_PrintEx(1).

PyObject* PyErr_Occurred()
Возвращаемое значение: заимствованная ссылка.

Проверяет, установлен ли индикатор ошибки. Если установлен, возвращает тип исключения (первый аргумент последнего вызова одной из функций PyErr_Set*() или PyErr_Restore()). Если не установлен, возвращает NULL. Вы не владеете ссылкой на возвращаемое значение, поэтому не нужно вызывать Py_DECREF().

Примечание

Не сравнивайте возвращаемое значение с конкретным исключением; используйте вместо этого PyErr_ExceptionMatches() (см. ниже). Сравнение может легко оказаться неверным, так как исключение может быть экземпляром, а не классом (для классовых исключений) или подклассом ожидаемого исключения.

int PyErr_ExceptionMatches(PyObject *exc)

Эквивалентно PyErr_GivenExceptionMatches(PyErr_Occurred(), exc). Функцию следует вызывать только тогда, когда исключение действительно установлено; в противном случае возникнет нарушение доступа к памяти.

int PyErr_GivenExceptionMatches(PyObject *given, PyObject *exc)

Возвращает истину, если исключение given соответствует исключению в exc. Если exc – объект класса, также возвращает истину, когда given является экземпляром подкласса. Если exc – кортеж, выполняется поиск совпадения по всем исключениям кортежа (и рекурсивно по вложенным кортежам).

void PyErr_NormalizeException(PyObject**exc, PyObject**val, PyObject**tb)

При определённых обстоятельствах значения, возвращаемые PyErr_Fetch() (см. ниже), могут оказаться «ненормализованными»: *exc является объектом класса, но *val не является экземпляром того же класса. Данная функция позволяет инстанцировать класс в таком случае. Если значения уже нормализованы, ничего не происходит. Отложенная нормализация реализована для повышения производительности.

Примечание

Эта функция не устанавливает неявно атрибут __traceback__ у значения исключения. Если требуется правильно задать трассировку, потребуется следующий дополнительный фрагмент:

if (tb != NULL) {
  PyException_SetTraceback(val, tb);
}
void PyErr_Clear()

Очищает индикатор ошибки. Если индикатор ошибки не установлен, эффекта нет.

void PyErr_Fetch(PyObject **ptype, PyObject **pvalue, PyObject **ptraceback)

Извлекает индикатор ошибки в три переменные, адреса которых передаются. Если индикатор ошибки не установлен, устанавливает все три переменные в NULL. Если установлен, он будет очищен, и вы получаете владение ссылкой на каждый извлечённый объект. Значение и объект traceback могут быть NULL, даже если объект типа не NULL.

Примечание

Эта функция обычно используется только кодом, которому нужно обрабатывать исключения, или кодом, которому требуется временно сохранить и восстановить индикатор ошибки.

void PyErr_Restore(PyObject *type, PyObject *value, PyObject *traceback)

Set the error indicator from the three objects. If the error indicator is already set, it is cleared first. If the objects are NULL, the error indicator is cleared. Do not pass a NULL type and non-NULL value or traceback. The exception type should be a class. Do not pass an invalid exception type or value. (Violating these rules will cause subtle problems later.) This call takes away a reference to each object: you must own a reference to each object before the call and after the call you no longer own these references. (If you don’t understand this, don’t use this function. I warned you.)

Примечание

Эта функция обычно используется только кодом, которому нужно временно сохранить и восстановить индикатор ошибки; для сохранения текущего состояния исключения используйте PyErr_Fetch().

void PyErr_GetExcInfo(PyObject **ptype, PyObject **pvalue, PyObject **ptraceback)

Извлекает информацию об исключении в том виде, как она известна из sys.exc_info(). Речь идёт об исключении, которое уже было перехвачено, а не о только что возбуждённом. Возвращает новые ссылки на три объекта; любой из них может быть NULL. Состояние информации об исключении не изменяется.

Примечание

Эта функция обычно не используется кодом, который хочет обрабатывать исключения. Скорее, она может применяться, когда коду нужно временно сохранить и восстановить состояние исключения. Используйте PyErr_SetExcInfo() для восстановления или очистки состояния исключения.

Новое в версии 3.3.

void PyErr_SetExcInfo(PyObject *type, PyObject *value, PyObject *traceback)

Устанавливает информацию об исключении в том виде, как она известна из sys.exc_info(). Речь идёт об исключении, которое уже было перехвачено, а не о только что возбуждённом. Эта функция «похищает» ссылки на аргументы. Чтобы очистить состояние исключения, передайте NULL во все три аргумента. Общие правила относительно трёх аргументов см. в PyErr_Restore().

Примечание

Эта функция обычно не используется кодом, который хочет обрабатывать исключения. Скорее, она может применяться, когда коду нужно временно сохранить и восстановить состояние исключения. Используйте PyErr_GetExcInfo() для чтения состояния исключения.

Новое в версии 3.3.

void PyErr_SetString(PyObject *type, const char *message)

Это самый распространённый способ установки индикатора ошибки. Первый аргумент задаёт тип исключения; обычно это одно из стандартных исключений, например PyExc_RuntimeError. Увеличивать счётчик ссылок на него не нужно. Второй аргумент – сообщение об ошибке; оно декодируется из 'utf-8’.

void PyErr_SetObject(PyObject *type, PyObject *value)

Эта функция аналогична PyErr_SetString(), но позволяет указать произвольный объект Python для параметра «value» исключения.

PyObject* PyErr_Format(PyObject *exception, const char *format, ...)
Возвращаемое значение: всегда NULL.

Эта функция устанавливает индикатор ошибки и возвращает NULL. исключение должен быть классом исключения Python. Параметры format и последующие помогают форматировать сообщение об ошибке; они имеют те же значения и смысл, что и в PyUnicode_FromFormat(). format – строка в кодировке ASCII.

void PyErr_SetNone(PyObject *type)

Это сокращённая запись для PyErr_SetObject(type, Py_None).

int PyErr_BadArgument()

Это сокращённая запись для PyErr_SetString(PyExc_TypeError, message), где message указывает, что встроенная операция была вызвана с недопустимым аргументом. В основном используется внутри.

PyObject* PyErr_NoMemory()
Возвращаемое значение: всегда NULL.

Это сокращённая запись для PyErr_SetNone(PyExc_MemoryError); она возвращает NULL, чтобы функция выделения объекта могла написать return PyErr_NoMemory(); при нехватке памяти.

PyObject* PyErr_SetFromErrno(PyObject *type)
Возвращаемое значение: всегда NULL.

Это вспомогательная функция для возбуждения исключения, когда функция библиотеки C вернула ошибку и установила переменную C errno. Она создаёт объект-кортеж, первый элемент которого – целое значение errno, а второй – соответствующее сообщение об ошибке (полученное через strerror()), и затем вызывает PyErr_SetObject(type, object). В Unix, когда значение errno равно EINTR, что указывает на прерванный системный вызов, эта функция вызывает PyErr_CheckSignals(), и если тот установил индикатор ошибки, оставляет его таким. Функция всегда возвращает NULL, поэтому обёрточная функция вокруг системного вызова может написать return PyErr_SetFromErrno(type); когда системный вызов возвращает ошибку.

PyObject* PyErr_SetFromErrnoWithFilenameObject(PyObject *type, PyObject *filenameObject)

Аналогично PyErr_SetFromErrno(), с дополнительным поведением: если filenameObject не равен NULL, он передаётся конструктору type как третий параметр. В случае исключения OSError это используется для определения атрибута filename экземпляра исключения.

PyObject* PyErr_SetFromErrnoWithFilenameObjects(PyObject *type, PyObject *filenameObject, PyObject *filenameObject2)

Аналогично PyErr_SetFromErrnoWithFilenameObject(), но принимает второй объект имени файла для возбуждения ошибок, когда функция, принимающая два имени файлов, завершается неудачей.

Новое в версии 3.4.

PyObject* PyErr_SetFromErrnoWithFilename(PyObject *type, const char *filename)
Возвращаемое значение: всегда NULL.

Аналогично PyErr_SetFromErrnoWithFilenameObject(), но имя файла задаётся как C-строка. filename декодируется из файловой системной кодировки (os.fsdecode()).

PyObject* PyErr_SetFromWindowsErr(int ierr)
Возвращаемое значение: всегда NULL.

Это вспомогательная функция для возбуждения WindowsError. Если вызвана с ierr равным 0, используется код ошибки, возвращённый вызовом GetLastError(). Она вызывает функцию Win32 FormatMessage(), чтобы получить описание Windows для кода ошибки, заданного ierr или GetLastError(), затем создаёт объект-кортеж, первый элемент которого – значение ierr, а второй – соответствующее сообщение об ошибке (полученное через FormatMessage()), и затем вызывает PyErr_SetObject(PyExc_WindowsError, object). Эта функция всегда возвращает NULL. Доступность: Windows.

PyObject* PyErr_SetExcFromWindowsErr(PyObject *type, int ierr)
Возвращаемое значение: всегда NULL.

Аналогично PyErr_SetFromWindowsErr(), с дополнительным параметром, указывающим тип возбуждаемого исключения. Доступность: Windows.

PyObject* PyErr_SetFromWindowsErrWithFilename(int ierr, const char *filename)
Возвращаемое значение: всегда NULL.

Аналогично PyErr_SetFromWindowsErrWithFilenameObject(), но имя файла задаётся как C-строка. filename декодируется из файловой системной кодировки (os.fsdecode()). Доступность: Windows.

PyObject* PyErr_SetExcFromWindowsErrWithFilenameObject(PyObject *type, int ierr, PyObject *filename)

Аналогично PyErr_SetFromWindowsErrWithFilenameObject(), с дополнительным параметром, указывающим тип возбуждаемого исключения. Доступность: Windows.

PyObject* PyErr_SetExcFromWindowsErrWithFilenameObjects(PyObject *type, int ierr, PyObject *filename, PyObject *filename2)

Аналогично PyErr_SetExcFromWindowsErrWithFilenameObject(), но принимает второй объект имени файла. Доступность: Windows.

Новое в версии 3.4.

PyObject* PyErr_SetExcFromWindowsErrWithFilename(PyObject *type, int ierr, const char *filename)
Возвращаемое значение: всегда NULL.

Аналогично PyErr_SetFromWindowsErrWithFilename(), с дополнительным параметром, указывающим тип возбуждаемого исключения. Доступность: Windows.

PyObject* PyErr_SetImportError(PyObject *msg, PyObject *name, PyObject *path)

Это вспомогательная функция для возбуждения ImportError. msg будет установлен как строка сообщения исключения. name и path, каждый из которых может быть NULL, будут установлены как соответствующие атрибуты ImportErrorname и path.

Новое в версии 3.3.

void PyErr_SyntaxLocationObject(PyObject *filename, int lineno, int col_offset)

Устанавливает информацию о файле, строке и смещении для текущего исключения. Если текущее исключение не является SyntaxError, то устанавливаются дополнительные атрибуты, которые заставляют подсистему вывода исключений считать, что исключение является SyntaxError.

Новое в версии 3.4.

void PyErr_SyntaxLocationEx(const char *filename, int lineno, int col_offset)

Как PyErr_SyntaxLocationObject(), но filename – это байтовая строка, декодированная из кодировки файловой системы (os.fsdecode()).

Новое в версии 3.2.

void PyErr_SyntaxLocation(const char *filename, int lineno)

Как PyErr_SyntaxLocationEx(), но параметр col_offset опущен.

void PyErr_BadInternalCall()

Это сокращённая форма для PyErr_SetString(PyExc_SystemError, message), где message указывает, что внутренняя операция (например, функция Python/C API) была вызвана с недопустимым аргументом. В основном используется внутри.

int PyErr_WarnEx(PyObject *category, const char *message, Py_ssize_t stack_level)

Выдаёт предупреждение. Аргумент category – это категория предупреждения (см. ниже) или NULL; аргумент message – строка в кодировке UTF-8. stack_level – положительное число, указывающее количество фреймов стека; предупреждение будет выдано из текущей исполняемой строки в этом фрейме стека. stack_level, равный 1, – это функция, вызывающая PyErr_WarnEx(), 2 – функция, стоящая над ней, и так далее.

Обычно эта функция выводит предупреждение в sys.stderr; однако возможно, что пользователь указал превращать предупреждения в ошибки, и в этом случае будет вызвано исключение. Также возможно, что функция вызывает исключение из-за проблемы в механизме предупреждений (реализация импортирует модуль warnings для выполнения основной работы). Возвращаемое значение – 0, если исключение не возникло, или -1, если возникло. (Невозможно определить, было ли предупреждение фактически выведено, а также причину исключения; это сделано намеренно.) Если возникло исключение, вызывающий код должен выполнить обычную обработку исключений (например, Py_DECREF() для владеемых ссылок и вернуть значение ошибки).

Категории предупреждений должны быть подклассами Warning; категория предупреждения по умолчанию – RuntimeWarning. Стандартные категории предупреждений Python доступны как глобальные переменные, имена которых – PyExc_, за которым следует имя исключения Python. Они имеют тип PyObject*; все они являются объектами классов. Их имена: PyExc_Warning, PyExc_UserWarning, PyExc_UnicodeWarning, PyExc_DeprecationWarning, PyExc_SyntaxWarning, PyExc_RuntimeWarning и PyExc_FutureWarning. PyExc_Warning является подклассом PyExc_Exception; остальные категории предупреждений являются подклассами PyExc_Warning.

Информацию об управлении предупреждениями см. в документации модуля warnings и опции -W в документации командной строки. C API для управления предупреждениями не существует.

int PyErr_WarnExplicitObject(PyObject *category, PyObject *message, PyObject *filename, int lineno, PyObject *module, PyObject *registry)

Выдаёт предупреждение с явным контролем всех атрибутов предупреждения. Это простая обёртка вокруг функции Python warnings.warn_explicit(), см. описание там. Аргументы module и registry могут быть установлены в NULL для получения эффекта по умолчанию, как описано там.

Новое в версии 3.4.

int PyErr_WarnExplicit(PyObject *category, const char *message, const char *filename, int lineno, const char *module, PyObject *registry)

Аналогично PyErr_WarnExplicitObject(), за исключением того, что message и module – строки в кодировке UTF-8, а filename декодируется из кодировки файловой системы (os.fsdecode()).

int PyErr_WarnFormat(PyObject *category, Py_ssize_t stack_level, const char *format, ...)

Функция, аналогичная PyErr_WarnEx(), но использующая PyUnicode_FromFormat() для форматирования сообщения предупреждения. format – строка в кодировке ASCII.

Новое в версии 3.2.

int PyErr_CheckSignals()

Эта функция взаимодействует с обработкой сигналов Python. Она проверяет, был ли отправлен сигнал процессам, и если да, вызывает соответствующий обработчик сигнала. Если модуль signal поддерживается, может быть вызван обработчик сигнала, написанный на Python. Во всех случаях действие по умолчанию для SIGINT – возбуждение исключения KeyboardInterrupt. Если исключение возбуждено, устанавливается индикатор ошибки, и функция возвращает -1; в противном случае функция возвращает 0. Индикатор ошибки может быть сброшен или не сброшен, если он был установлен ранее.

void PyErr_SetInterrupt()

Эта функция имитирует поступление сигнала SIGINT – при следующем вызове PyErr_CheckSignals() будет возбуждено исключение KeyboardInterrupt. Может быть вызвана без захвата блокировки интерпретатора.

int PySignal_SetWakeupFd(int fd)

Эта вспомогательная функция задаёт файловый дескриптор, в который будет записан байт '\0' при получении сигнала. Возвращает предыдущий такой файловый дескриптор. Значение -1 отключает эту возможность; это начальное состояние. Эквивалентно signal.set_wakeup_fd() в Python, но без проверки ошибок. fd должен быть корректным файловым дескриптором. Функцию следует вызывать только из главного потока.

PyObject* PyErr_NewException(const char *name, PyObject *base, PyObject *dict)
Возвращаемое значение: новая ссылка.

Эта вспомогательная функция создаёт и возвращает новый класс исключения. Аргумент name должен быть именем нового исключения – строкой C вида module.classname. Аргументы base и dict обычно равны NULL. Создаётся объект класса, производный от Exception (доступен в C как PyExc_Exception).

Атрибут __module__ нового класса устанавливается в первую часть (до последней точки) аргумента name, а имя класса – в последнюю часть (после последней точки). Аргумент base можно использовать для указания альтернативных базовых классов; это может быть как один класс, так и кортеж классов. Аргумент dict можно использовать для указания словаря переменных и методов класса.

PyObject* PyErr_NewExceptionWithDoc(const char *name, const char *doc, PyObject *base, PyObject *dict)
Возвращаемое значение: новая ссылка.

То же, что PyErr_NewException(), за исключением того, что новому классу исключения можно легко задать строку документации: если doc не равен NULL, он будет использован как docstring класса исключения.

Новое в версии 3.2.

void PyErr_WriteUnraisable(PyObject *obj)

Эта вспомогательная функция выводит предупреждение в sys.stderr, когда исключение установлено, но интерпретатор не может его фактически возбудить. Используется, например, когда исключение возникает в методе __del__().

Функция вызывается с одним аргументом obj, который идентифицирует контекст, в котором возникло не вызываемое исключение. В сообщении предупреждения будет выведено repr от obj.

Объекты исключенийException Objects

PyObject* PyException_GetTraceback(PyObject *ex)
Возвращаемое значение: новая ссылка.

Возвращает traceback, связанный с исключением, как новую ссылку, доступную из Python через __traceback__. Если traceback не связан, возвращает NULL.

int PyException_SetTraceback(PyObject *ex, PyObject *tb)

Устанавливает traceback, связанный с исключением, в tb. Используйте Py_None для его очистки.

PyObject* PyException_GetContext(PyObject *ex)

Возвращает контекст (другой экземпляр исключения, при обработке которого было возбуждено ex), связанный с исключением, как новую ссылку, доступную из Python через __context__. Если контекст не связан, возвращает NULL.

void PyException_SetContext(PyObject *ex, PyObject *ctx)

Устанавливает контекст, связанный с исключением, в ctx. Используйте NULL для его очистки. Проверка типа на то, что ctx является экземпляром исключения, не выполняется. Функция забирает ссылку на ctx.

PyObject* PyException_GetCause(PyObject *ex)

Возвращает причину (либо экземпляр исключения, либо None, установленную конструкцией raise ... from ...), связанную с исключением, как новую ссылку, доступную из Python через __cause__.

void PyException_SetCause(PyObject *ex, PyObject *cause)

Устанавливает причину, связанную с исключением, в cause. Используйте NULL для её очистки. Проверка типа, что cause является экземпляром исключения или None, не выполняется. Эта функция похищает ссылку на cause.

Эта функция неявно устанавливает __suppress_context__ в True.

Объекты исключений UnicodeUnicode Exception Objects

Следующие функции используются для создания и изменения исключений Unicode из C.

PyObject* PyUnicodeDecodeError_Create(const char *encoding, const char *object, Py_ssize_t length, Py_ssize_t start, Py_ssize_t end, const char *reason)

Создаёт объект UnicodeDecodeError с атрибутами encoding, object, length, start, end и reason. encoding и reason – строки в кодировке UTF-8.

PyObject* PyUnicodeEncodeError_Create(const char *encoding, const Py_UNICODE *object, Py_ssize_t length, Py_ssize_t start, Py_ssize_t end, const char *reason)

Создаёт объект UnicodeEncodeError с атрибутами encoding, object, length, start, end и reason. encoding и reason – строки в кодировке UTF-8.

PyObject* PyUnicodeTranslateError_Create(const Py_UNICODE *object, Py_ssize_t length, Py_ssize_t start, Py_ssize_t end, const char *reason)

Создаёт объект UnicodeTranslateError с атрибутами object, length, start, end и reason. reason – строка в кодировке UTF-8.

PyObject* PyUnicodeDecodeError_GetEncoding(PyObject *exc)
PyObject* PyUnicodeEncodeError_GetEncoding(PyObject *exc)

Возвращает атрибут encoding указанного объекта исключения.

PyObject* PyUnicodeDecodeError_GetObject(PyObject *exc)
PyObject* PyUnicodeEncodeError_GetObject(PyObject *exc)
PyObject* PyUnicodeTranslateError_GetObject(PyObject *exc)

Возвращает атрибут object указанного объекта исключения.

int PyUnicodeDecodeError_GetStart(PyObject *exc, Py_ssize_t *start)
int PyUnicodeEncodeError_GetStart(PyObject *exc, Py_ssize_t *start)
int PyUnicodeTranslateError_GetStart(PyObject *exc, Py_ssize_t *start)

Получает атрибут start заданного объекта исключения и помещает его в *start. start не должен быть NULL. Возвращает 0 в случае успеха, -1 при неудаче.

int PyUnicodeDecodeError_SetStart(PyObject *exc, Py_ssize_t start)
int PyUnicodeEncodeError_SetStart(PyObject *exc, Py_ssize_t start)
int PyUnicodeTranslateError_SetStart(PyObject *exc, Py_ssize_t start)

Устанавливает атрибут start указанного объекта исключения в значение start. Возвращает 0 при успехе, -1 при ошибке.

int PyUnicodeDecodeError_GetEnd(PyObject *exc, Py_ssize_t *end)
int PyUnicodeEncodeError_GetEnd(PyObject *exc, Py_ssize_t *end)
int PyUnicodeTranslateError_GetEnd(PyObject *exc, Py_ssize_t *end)

Получает атрибут end заданного объекта исключения и помещает его в *end. end не должен быть NULL. Возвращает 0 в случае успеха, -1 при неудаче.

int PyUnicodeDecodeError_SetEnd(PyObject *exc, Py_ssize_t end)
int PyUnicodeEncodeError_SetEnd(PyObject *exc, Py_ssize_t end)
int PyUnicodeTranslateError_SetEnd(PyObject *exc, Py_ssize_t end)

Устанавливает атрибут end указанного объекта исключения в end. Возвращает 0 в случае успеха, -1 при ошибке.

PyObject* PyUnicodeDecodeError_GetReason(PyObject *exc)
PyObject* PyUnicodeEncodeError_GetReason(PyObject *exc)
PyObject* PyUnicodeTranslateError_GetReason(PyObject *exc)

Возвращает атрибут reason указанного объекта исключения.

int PyUnicodeDecodeError_SetReason(PyObject *exc, const char *reason)
int PyUnicodeEncodeError_SetReason(PyObject *exc, const char *reason)
int PyUnicodeTranslateError_SetReason(PyObject *exc, const char *reason)

Устанавливает атрибут reason указанного объекта исключения в значение reason. Возвращает 0 в случае успеха, -1 в случае ошибки.

Управление рекурсиейRecursion Control

Эти две функции предоставляют способ выполнения безопасных рекурсивных вызовов на уровне C как в ядре, так и в модулях расширения. Они необходимы, если рекурсивный код не обязательно вызывает код Python (который автоматически отслеживает свою глубину рекурсии).

int Py_EnterRecursiveCall(const char *where)

Отмечает точку, в которой будет выполнен рекурсивный вызов на уровне C.

Если определён USE_STACKCHECK, эта функция проверяет, не переполнился ли стек ОС с помощью PyOS_CheckStack(). Если это так, она устанавливает MemoryError и возвращает ненулевое значение.

Затем функция проверяет, достигнут ли лимит рекурсии. Если это так, устанавливается RuntimeError и возвращается ненулевое значение. В противном случае возвращается ноль.

where должна быть строкой, например " in instance check", которая будет добавлена к сообщению RuntimeError, вызванному пределом глубины рекурсии.

void Py_LeaveRecursiveCall()

Завершает Py_EnterRecursiveCall(). Должен вызываться один раз для каждого успешного вызова Py_EnterRecursiveCall().

Правильная реализация tp_repr для контейнерных типов требует специальной обработки рекурсии. Помимо защиты стека, tp_repr также должен отслеживать объекты для предотвращения циклов. Следующие две функции упрощают эту функциональность. По сути, это C-эквивалент reprlib.recursive_repr().

int Py_ReprEnter(PyObject *object)

Вызывается в начале реализации tp_repr для обнаружения циклов.

Если объект уже был обработан, функция возвращает положительное целое число. В этом случае реализация tp_repr должна вернуть строковый объект, указывающий на цикл. Например, объекты dict возвращают {...}, а объекты list возвращают [...].

Функция вернёт отрицательное целое число, если превышен лимит рекурсии. В этом случае реализация tp_repr обычно должна возвращать NULL.

В противном случае функция возвращает ноль, и реализация tp_repr может продолжить работу нормально.

void Py_ReprLeave(PyObject *object)

Завершает Py_ReprEnter(). Должен вызываться один раз для каждого вызова Py_ReprEnter(), который возвращает ноль.

Стандартные исключенияStandard Exceptions

Все стандартные исключения Python доступны как глобальные переменные, имена которых состоят из PyExc_, за которым следует имя исключения Python. Они имеют тип PyObject*; все они являются объектами классов. Для полноты картины, вот все переменные:

Имя в C Имя в Python Примечания
PyExc_BaseException BaseException (1)
PyExc_Exception исключение (1)
PyExc_ArithmeticError ArithmeticError (1)
PyExc_LookupError LookupError (1)
PyExc_AssertionError AssertionError  
PyExc_AttributeError AttributeError  
PyExc_BlockingIOError BlockingIOError  
PyExc_BrokenPipeError BrokenPipeError  
PyExc_ChildProcessError ChildProcessError  
PyExc_ConnectionError ConnectionError  
PyExc_ConnectionAbortedError ConnectionAbortedError  
PyExc_ConnectionRefusedError ConnectionRefusedError  
PyExc_ConnectionResetError ConnectionResetError  
PyExc_FileExistsError FileExistsError  
PyExc_FileNotFoundError FileNotFoundError  
PyExc_EOFError EOFError  
PyExc_FloatingPointError FloatingPointError  
PyExc_ImportError ImportError  
PyExc_IndexError IndexError  
PyExc_InterruptedError InterruptedError  
PyExc_IsADirectoryError IsADirectoryError  
PyExc_KeyError KeyError  
PyExc_KeyboardInterrupt KeyboardInterrupt  
PyExc_MemoryError MemoryError  
PyExc_NameError NameError  
PyExc_NotADirectoryError NotADirectoryError  
PyExc_NotImplementedError NotImplementedError  
PyExc_OSError OSError (1)
PyExc_OverflowError OverflowError  
PyExc_PermissionError PermissionError  
PyExc_ProcessLookupError ProcessLookupError  
PyExc_ReferenceError ReferenceError (2)
PyExc_RuntimeError RuntimeError  
PyExc_SyntaxError SyntaxError  
PyExc_SystemError SystemError  
PyExc_TimeoutError TimeoutError  
PyExc_SystemExit SystemExit  
PyExc_TypeError TypeError  
PyExc_ValueError ValueError  
PyExc_ZeroDivisionError ZeroDivisionError  

Новое в версии 3.3: PyExc_BlockingIOError, PyExc_BrokenPipeError, PyExc_ChildProcessError, PyExc_ConnectionError, PyExc_ConnectionAbortedError, PyExc_ConnectionRefusedError, PyExc_ConnectionResetError, PyExc_FileExistsError, PyExc_FileNotFoundError, PyExc_InterruptedError, PyExc_IsADirectoryError, PyExc_NotADirectoryError, PyExc_PermissionError, PyExc_ProcessLookupError и PyExc_TimeoutError были введены в соответствии с PEP 3151.

Это псевдонимы для совместимости с PyExc_OSError:

Имя в C Примечания
PyExc_EnvironmentError  
PyExc_IOError  
PyExc_WindowsError (3)

Изменено в версии 3.3: Раньше эти псевдонимы были отдельными типами исключений.

Примечания:

  1. Это базовый класс для других стандартных исключений.
  2. То же самое, что weakref.ReferenceError.
  3. Определён только в Windows; код, использующий это, должен проверять, определён ли макрос препроцессора MS_WINDOWS.