exceptions.md
1> **Источник:** https://python-all.ru/3.4/c-api/exceptions.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# Обработка исключений89Функции, описанные в этой главе, позволяют обрабатывать и возбуждать исключения Python. Важно понимать некоторые основы обработки исключений в Python. Механизм в чём-то похож на переменную `errno` в Unix: существует глобальный индикатор (на поток) последней произошедшей ошибки. Большинство функций не сбрасывают его при успехе, но устанавливают, чтобы указать причину ошибки в случае неудачи. Большинство функций также возвращают индикатор ошибки – обычно *NULL*, если ожидается возврат указателя, или `-1`, если возвращается целое число (исключение: функции `PyArg_*()` возвращают `1` при успехе и `0` при ошибке).1011Когда функция должна завершиться ошибкой, потому что вызванная ей функция завершилась ошибкой, она обычно не устанавливает индикатор ошибки; его уже установила вызванная функция. Она отвечает либо за обработку ошибки и очистку исключения, либо за возврат после освобождения всех удерживаемых ресурсов (таких как ссылки на объекты или выделенная память); она *не* должна продолжать нормальное выполнение, если не готова обработать ошибку. При возврате из-за ошибки важно указать вызывающему коду, что ошибка была установлена. Если ошибка не обрабатывается или не аккуратно распространяется, последующие вызовы Python/C API могут вести себя не так, как задумано, и могут отказать загадочным образом.1213Индикатор ошибки состоит из трёх объектов Python, соответствующих результату вызова `sys.exc_info()`. Существуют функции API для взаимодействия с индикатором ошибки разными способами. Для каждого потока предусмотрен отдельный индикатор ошибки.1415#### `void PyErr_PrintEx(int set_sys_last_vars)`1617Выводит стандартную трассировку в `sys.stderr` и очищает индикатор ошибки. Вызывайте эту функцию только при установленном индикаторе ошибки (иначе возникнет фатальная ошибка!).1819Если *set\_sys\_last\_vars* не равно нулю, переменные [`sys.last_type`](https://python-all.ru/3.4/library/sys.html#sys.last_type), [`sys.last_value`](https://python-all.ru/3.4/library/sys.html#sys.last_value) и [`sys.last_traceback`](https://python-all.ru/3.4/library/sys.html#sys.last_traceback) будут установлены в тип, значение и трассировку напечатанного исключения соответственно.2021#### `void PyErr_Print()`2223Псевдоним для `PyErr_PrintEx(1)`.2425#### `PyObject* PyErr_Occurred()`2627*Возвращаемое значение: заимствованная ссылка.*2829Проверяет, установлен ли индикатор ошибки. Если установлен, возвращает *тип* исключения (первый аргумент последнего вызова одной из функций `PyErr_Set*()` или [`PyErr_Restore()`](https://python-all.ru/3.4/c-api/exceptions.html#c.PyErr_Restore)). Если не установлен, возвращает *NULL*. Вы не владеете ссылкой на возвращаемое значение, поэтому не нужно вызывать [`Py_DECREF()`](https://python-all.ru/3.4/c-api/refcounting.html#c.Py_DECREF).3031> **Примечание**32>33> Не сравнивайте возвращаемое значение с конкретным исключением; используйте вместо этого [`PyErr_ExceptionMatches()`](https://python-all.ru/3.4/c-api/exceptions.html#c.PyErr_ExceptionMatches) (см. ниже). Сравнение может легко оказаться неверным, так как исключение может быть экземпляром, а не классом (для классовых исключений) или подклассом ожидаемого исключения.3435#### `int PyErr_ExceptionMatches(PyObject *exc)`3637Эквивалентно `PyErr_GivenExceptionMatches(PyErr_Occurred(), exc)`. Функцию следует вызывать только тогда, когда исключение действительно установлено; в противном случае возникнет нарушение доступа к памяти.3839#### `int PyErr_GivenExceptionMatches(PyObject *given, PyObject *exc)`4041Возвращает истину, если исключение *given* соответствует исключению в *exc*. Если *exc* – объект класса, также возвращает истину, когда *given* является экземпляром подкласса. Если *exc* – кортеж, выполняется поиск совпадения по всем исключениям кортежа (и рекурсивно по вложенным кортежам).4243#### `void PyErr_NormalizeException(PyObject**exc, PyObject**val, PyObject**tb)`4445При определённых обстоятельствах значения, возвращаемые [`PyErr_Fetch()`](https://python-all.ru/3.4/c-api/exceptions.html#c.PyErr_Fetch) (см. ниже), могут оказаться «ненормализованными»: `*exc` является объектом класса, но `*val` не является экземпляром того же класса. Данная функция позволяет инстанцировать класс в таком случае. Если значения уже нормализованы, ничего не происходит. Отложенная нормализация реализована для повышения производительности.4647> **Примечание**48>49> Эта функция *не* устанавливает неявно атрибут `__traceback__` у значения исключения. Если требуется правильно задать трассировку, потребуется следующий дополнительный фрагмент:50>51> ```c52> if (tb != NULL) {53> PyException_SetTraceback(val, tb);54> }55> ```5657#### `void PyErr_Clear()`5859Очищает индикатор ошибки. Если индикатор ошибки не установлен, эффекта нет.6061#### `void PyErr_Fetch(PyObject **ptype, PyObject **pvalue, PyObject **ptraceback)`6263Извлекает индикатор ошибки в три переменные, адреса которых передаются. Если индикатор ошибки не установлен, устанавливает все три переменные в *NULL*. Если установлен, он будет очищен, и вы получаете владение ссылкой на каждый извлечённый объект. Значение и объект traceback могут быть *NULL*, даже если объект типа не NULL.6465> **Примечание**66>67> Эта функция обычно используется только кодом, которому нужно обрабатывать исключения, или кодом, которому требуется временно сохранить и восстановить индикатор ошибки.6869#### `void PyErr_Restore(PyObject *type, PyObject *value, PyObject *traceback)`7071Set 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.)7273> **Примечание**74>75> Эта функция обычно используется только кодом, которому нужно временно сохранить и восстановить индикатор ошибки; для сохранения текущего состояния исключения используйте [`PyErr_Fetch()`](https://python-all.ru/3.4/c-api/exceptions.html#c.PyErr_Fetch).7677#### `void PyErr_GetExcInfo(PyObject **ptype, PyObject **pvalue, PyObject **ptraceback)`7879Извлекает информацию об исключении в том виде, как она известна из `sys.exc_info()`. Речь идёт об исключении, которое уже было перехвачено, а не о только что возбуждённом. Возвращает новые ссылки на три объекта; любой из них может быть *NULL*. Состояние информации об исключении не изменяется.8081> **Примечание**82>83> Эта функция обычно не используется кодом, который хочет обрабатывать исключения. Скорее, она может применяться, когда коду нужно временно сохранить и восстановить состояние исключения. Используйте [`PyErr_SetExcInfo()`](https://python-all.ru/3.4/c-api/exceptions.html#c.PyErr_SetExcInfo) для восстановления или очистки состояния исключения.8485Новое в версии 3.3.8687#### `void PyErr_SetExcInfo(PyObject *type, PyObject *value, PyObject *traceback)`8889Устанавливает информацию об исключении в том виде, как она известна из `sys.exc_info()`. Речь идёт об исключении, которое уже было перехвачено, а не о только что возбуждённом. Эта функция «похищает» ссылки на аргументы. Чтобы очистить состояние исключения, передайте *NULL* во все три аргумента. Общие правила относительно трёх аргументов см. в [`PyErr_Restore()`](https://python-all.ru/3.4/c-api/exceptions.html#c.PyErr_Restore).9091> **Примечание**92>93> Эта функция обычно не используется кодом, который хочет обрабатывать исключения. Скорее, она может применяться, когда коду нужно временно сохранить и восстановить состояние исключения. Используйте [`PyErr_GetExcInfo()`](https://python-all.ru/3.4/c-api/exceptions.html#c.PyErr_GetExcInfo) для чтения состояния исключения.9495Новое в версии 3.3.9697#### `void PyErr_SetString(PyObject *type, const char *message)`9899Это самый распространённый способ установки индикатора ошибки. Первый аргумент задаёт тип исключения; обычно это одно из стандартных исключений, например `PyExc_RuntimeError`. Увеличивать счётчик ссылок на него не нужно. Второй аргумент – сообщение об ошибке; оно декодируется из `'utf-8`’.100101#### `void PyErr_SetObject(PyObject *type, PyObject *value)`102103Эта функция аналогична [`PyErr_SetString()`](https://python-all.ru/3.4/c-api/exceptions.html#c.PyErr_SetString), но позволяет указать произвольный объект Python для параметра «value» исключения.104105#### `PyObject* PyErr_Format(PyObject *exception, const char *format, ...)`106107*Возвращаемое значение: всегда NULL.*108109Эта функция устанавливает индикатор ошибки и возвращает *NULL*. *исключение* должен быть классом исключения Python. Параметры *format* и последующие помогают форматировать сообщение об ошибке; они имеют те же значения и смысл, что и в [`PyUnicode_FromFormat()`](https://python-all.ru/3.4/c-api/unicode.html#c.PyUnicode_FromFormat). *format* – строка в кодировке ASCII.110111#### `void PyErr_SetNone(PyObject *type)`112113Это сокращённая запись для `PyErr_SetObject(type, Py_None)`.114115#### `int PyErr_BadArgument()`116117Это сокращённая запись для `PyErr_SetString(PyExc_TypeError, message)`, где *message* указывает, что встроенная операция была вызвана с недопустимым аргументом. В основном используется внутри.118119#### `PyObject* PyErr_NoMemory()`120121*Возвращаемое значение: всегда NULL.*122123Это сокращённая запись для `PyErr_SetNone(PyExc_MemoryError)`; она возвращает *NULL*, чтобы функция выделения объекта могла написать `return PyErr_NoMemory();` при нехватке памяти.124125#### `PyObject* PyErr_SetFromErrno(PyObject *type)`126127*Возвращаемое значение: всегда NULL.*128129Это вспомогательная функция для возбуждения исключения, когда функция библиотеки C вернула ошибку и установила переменную C `errno`. Она создаёт объект-кортеж, первый элемент которого – целое значение `errno`, а второй – соответствующее сообщение об ошибке (полученное через `strerror()`), и затем вызывает `PyErr_SetObject(type, object)`. В Unix, когда значение `errno` равно `EINTR`, что указывает на прерванный системный вызов, эта функция вызывает [`PyErr_CheckSignals()`](https://python-all.ru/3.4/c-api/exceptions.html#c.PyErr_CheckSignals), и если тот установил индикатор ошибки, оставляет его таким. Функция всегда возвращает *NULL*, поэтому обёрточная функция вокруг системного вызова может написать `return PyErr_SetFromErrno(type);` когда системный вызов возвращает ошибку.130131#### `PyObject* PyErr_SetFromErrnoWithFilenameObject(PyObject *type, PyObject *filenameObject)`132133Аналогично [`PyErr_SetFromErrno()`](https://python-all.ru/3.4/c-api/exceptions.html#c.PyErr_SetFromErrno), с дополнительным поведением: если *filenameObject* не равен *NULL*, он передаётся конструктору *type* как третий параметр. В случае исключения [`OSError`](https://python-all.ru/3.4/library/exceptions.html#OSError) это используется для определения атрибута `filename` экземпляра исключения.134135#### `PyObject* PyErr_SetFromErrnoWithFilenameObjects(PyObject *type, PyObject *filenameObject, PyObject *filenameObject2)`136137Аналогично [`PyErr_SetFromErrnoWithFilenameObject()`](https://python-all.ru/3.4/c-api/exceptions.html#c.PyErr_SetFromErrnoWithFilenameObject), но принимает второй объект имени файла для возбуждения ошибок, когда функция, принимающая два имени файлов, завершается неудачей.138139Новое в версии 3.4.140141#### `PyObject* PyErr_SetFromErrnoWithFilename(PyObject *type, const char *filename)`142143*Возвращаемое значение: всегда NULL.*144145Аналогично [`PyErr_SetFromErrnoWithFilenameObject()`](https://python-all.ru/3.4/c-api/exceptions.html#c.PyErr_SetFromErrnoWithFilenameObject), но имя файла задаётся как C-строка. *filename* декодируется из файловой системной кодировки ([`os.fsdecode()`](https://python-all.ru/3.4/library/os.html#os.fsdecode)).146147#### `PyObject* PyErr_SetFromWindowsErr(int ierr)`148149*Возвращаемое значение: всегда NULL.*150151Это вспомогательная функция для возбуждения [`WindowsError`](https://python-all.ru/3.4/library/exceptions.html#WindowsError). Если вызвана с *ierr* равным `0`, используется код ошибки, возвращённый вызовом `GetLastError()`. Она вызывает функцию Win32 `FormatMessage()`, чтобы получить описание Windows для кода ошибки, заданного *ierr* или `GetLastError()`, затем создаёт объект-кортеж, первый элемент которого – значение *ierr*, а второй – соответствующее сообщение об ошибке (полученное через `FormatMessage()`), и затем вызывает `PyErr_SetObject(PyExc_WindowsError, object)`. Эта функция всегда возвращает *NULL*. Доступность: Windows.152153#### `PyObject* PyErr_SetExcFromWindowsErr(PyObject *type, int ierr)`154155*Возвращаемое значение: всегда NULL.*156157Аналогично [`PyErr_SetFromWindowsErr()`](https://python-all.ru/3.4/c-api/exceptions.html#c.PyErr_SetFromWindowsErr), с дополнительным параметром, указывающим тип возбуждаемого исключения. Доступность: Windows.158159#### `PyObject* PyErr_SetFromWindowsErrWithFilename(int ierr, const char *filename)`160161*Возвращаемое значение: всегда NULL.*162163Аналогично `PyErr_SetFromWindowsErrWithFilenameObject()`, но имя файла задаётся как C-строка. *filename* декодируется из файловой системной кодировки ([`os.fsdecode()`](https://python-all.ru/3.4/library/os.html#os.fsdecode)). Доступность: Windows.164165#### `PyObject* PyErr_SetExcFromWindowsErrWithFilenameObject(PyObject *type, int ierr, PyObject *filename)`166167Аналогично `PyErr_SetFromWindowsErrWithFilenameObject()`, с дополнительным параметром, указывающим тип возбуждаемого исключения. Доступность: Windows.168169#### `PyObject* PyErr_SetExcFromWindowsErrWithFilenameObjects(PyObject *type, int ierr, PyObject *filename, PyObject *filename2)`170171Аналогично [`PyErr_SetExcFromWindowsErrWithFilenameObject()`](https://python-all.ru/3.4/c-api/exceptions.html#c.PyErr_SetExcFromWindowsErrWithFilenameObject), но принимает второй объект имени файла. Доступность: Windows.172173Новое в версии 3.4.174175#### `PyObject* PyErr_SetExcFromWindowsErrWithFilename(PyObject *type, int ierr, const char *filename)`176177*Возвращаемое значение: всегда NULL.*178179Аналогично [`PyErr_SetFromWindowsErrWithFilename()`](https://python-all.ru/3.4/c-api/exceptions.html#c.PyErr_SetFromWindowsErrWithFilename), с дополнительным параметром, указывающим тип возбуждаемого исключения. Доступность: Windows.180181#### `PyObject* PyErr_SetImportError(PyObject *msg, PyObject *name, PyObject *path)`182183Это вспомогательная функция для возбуждения [`ImportError`](https://python-all.ru/3.4/library/exceptions.html#ImportError). *msg* будет установлен как строка сообщения исключения. *name* и *path*, каждый из которых может быть `NULL`, будут установлены как соответствующие атрибуты [`ImportError`](https://python-all.ru/3.4/library/exceptions.html#ImportError) – `name` и `path`.184185Новое в версии 3.3.186187#### `void PyErr_SyntaxLocationObject(PyObject *filename, int lineno, int col_offset)`188189Устанавливает информацию о файле, строке и смещении для текущего исключения. Если текущее исключение не является [`SyntaxError`](https://python-all.ru/3.4/library/exceptions.html#SyntaxError), то устанавливаются дополнительные атрибуты, которые заставляют подсистему вывода исключений считать, что исключение является [`SyntaxError`](https://python-all.ru/3.4/library/exceptions.html#SyntaxError).190191Новое в версии 3.4.192193#### `void PyErr_SyntaxLocationEx(const char *filename, int lineno, int col_offset)`194195Как [`PyErr_SyntaxLocationObject()`](https://python-all.ru/3.4/c-api/exceptions.html#c.PyErr_SyntaxLocationObject), но *filename* – это байтовая строка, декодированная из кодировки файловой системы ([`os.fsdecode()`](https://python-all.ru/3.4/library/os.html#os.fsdecode)).196197Новое в версии 3.2.198199#### `void PyErr_SyntaxLocation(const char *filename, int lineno)`200201Как [`PyErr_SyntaxLocationEx()`](https://python-all.ru/3.4/c-api/exceptions.html#c.PyErr_SyntaxLocationEx), но параметр col\_offset опущен.202203#### `void PyErr_BadInternalCall()`204205Это сокращённая форма для `PyErr_SetString(PyExc_SystemError, message)`, где *message* указывает, что внутренняя операция (например, функция Python/C API) была вызвана с недопустимым аргументом. В основном используется внутри.206207#### `int PyErr_WarnEx(PyObject *category, const char *message, Py_ssize_t stack_level)`208209Выдаёт предупреждение. Аргумент *category* – это категория предупреждения (см. ниже) или *NULL*; аргумент *message* – строка в кодировке UTF-8. *stack\_level* – положительное число, указывающее количество фреймов стека; предупреждение будет выдано из текущей исполняемой строки в этом фрейме стека. *stack\_level*, равный 1, – это функция, вызывающая [`PyErr_WarnEx()`](https://python-all.ru/3.4/c-api/exceptions.html#c.PyErr_WarnEx), 2 – функция, стоящая над ней, и так далее.210211Обычно эта функция выводит предупреждение в *sys.stderr*; однако возможно, что пользователь указал превращать предупреждения в ошибки, и в этом случае будет вызвано исключение. Также возможно, что функция вызывает исключение из-за проблемы в механизме предупреждений (реализация импортирует модуль [`warnings`](https://python-all.ru/3.4/library/warnings.html#module-warnings) для выполнения основной работы). Возвращаемое значение – `0`, если исключение не возникло, или `-1`, если возникло. (Невозможно определить, было ли предупреждение фактически выведено, а также причину исключения; это сделано намеренно.) Если возникло исключение, вызывающий код должен выполнить обычную обработку исключений (например, [`Py_DECREF()`](https://python-all.ru/3.4/c-api/refcounting.html#c.Py_DECREF) для владеемых ссылок и вернуть значение ошибки).212213Категории предупреждений должны быть подклассами `Warning`; категория предупреждения по умолчанию – `RuntimeWarning`. Стандартные категории предупреждений Python доступны как глобальные переменные, имена которых – `PyExc_`, за которым следует имя исключения Python. Они имеют тип [`PyObject*`](https://python-all.ru/3.4/c-api/structures.html#c.PyObject); все они являются объектами классов. Их имена: `PyExc_Warning`, `PyExc_UserWarning`, `PyExc_UnicodeWarning`, `PyExc_DeprecationWarning`, `PyExc_SyntaxWarning`, `PyExc_RuntimeWarning` и `PyExc_FutureWarning`. `PyExc_Warning` является подклассом `PyExc_Exception`; остальные категории предупреждений являются подклассами `PyExc_Warning`.214215Информацию об управлении предупреждениями см. в документации модуля [`warnings`](https://python-all.ru/3.4/library/warnings.html#module-warnings) и опции [*-W*](https://python-all.ru/3.4/using/cmdline.html#cmdoption-W) в документации командной строки. C API для управления предупреждениями не существует.216217#### `int PyErr_WarnExplicitObject(PyObject *category, PyObject *message, PyObject *filename, int lineno, PyObject *module, PyObject *registry)`218219Выдаёт предупреждение с явным контролем всех атрибутов предупреждения. Это простая обёртка вокруг функции Python [`warnings.warn_explicit()`](https://python-all.ru/3.4/library/warnings.html#warnings.warn_explicit), см. описание там. Аргументы *module* и *registry* могут быть установлены в *NULL* для получения эффекта по умолчанию, как описано там.220221Новое в версии 3.4.222223#### `int PyErr_WarnExplicit(PyObject *category, const char *message, const char *filename, int lineno, const char *module, PyObject *registry)`224225Аналогично [`PyErr_WarnExplicitObject()`](https://python-all.ru/3.4/c-api/exceptions.html#c.PyErr_WarnExplicitObject), за исключением того, что *message* и *module* – строки в кодировке UTF-8, а *filename* декодируется из кодировки файловой системы ([`os.fsdecode()`](https://python-all.ru/3.4/library/os.html#os.fsdecode)).226227#### `int PyErr_WarnFormat(PyObject *category, Py_ssize_t stack_level, const char *format, ...)`228229Функция, аналогичная [`PyErr_WarnEx()`](https://python-all.ru/3.4/c-api/exceptions.html#c.PyErr_WarnEx), но использующая [`PyUnicode_FromFormat()`](https://python-all.ru/3.4/c-api/unicode.html#c.PyUnicode_FromFormat) для форматирования сообщения предупреждения. *format* – строка в кодировке ASCII.230231Новое в версии 3.2.232233#### `int PyErr_CheckSignals()`234235Эта функция взаимодействует с обработкой сигналов Python. Она проверяет, был ли отправлен сигнал процессам, и если да, вызывает соответствующий обработчик сигнала. Если модуль [`signal`](https://python-all.ru/3.4/library/signal.html#module-signal) поддерживается, может быть вызван обработчик сигнала, написанный на Python. Во всех случаях действие по умолчанию для `SIGINT` – возбуждение исключения [`KeyboardInterrupt`](https://python-all.ru/3.4/library/exceptions.html#KeyboardInterrupt). Если исключение возбуждено, устанавливается индикатор ошибки, и функция возвращает `-1`; в противном случае функция возвращает `0`. Индикатор ошибки может быть сброшен или не сброшен, если он был установлен ранее.236237#### `void PyErr_SetInterrupt()`238239Эта функция имитирует поступление сигнала `SIGINT` – при следующем вызове [`PyErr_CheckSignals()`](https://python-all.ru/3.4/c-api/exceptions.html#c.PyErr_CheckSignals) будет возбуждено исключение [`KeyboardInterrupt`](https://python-all.ru/3.4/library/exceptions.html#KeyboardInterrupt). Может быть вызвана без захвата блокировки интерпретатора.240241#### `int PySignal_SetWakeupFd(int fd)`242243Эта вспомогательная функция задаёт файловый дескриптор, в который будет записан байт `'\0'` при получении сигнала. Возвращает предыдущий такой файловый дескриптор. Значение `-1` отключает эту возможность; это начальное состояние. Эквивалентно [`signal.set_wakeup_fd()`](https://python-all.ru/3.4/library/signal.html#signal.set_wakeup_fd) в Python, но без проверки ошибок. *fd* должен быть корректным файловым дескриптором. Функцию следует вызывать только из главного потока.244245#### `PyObject* PyErr_NewException(const char *name, PyObject *base, PyObject *dict)`246247*Возвращаемое значение: новая ссылка.*248249Эта вспомогательная функция создаёт и возвращает новый класс исключения. Аргумент *name* должен быть именем нового исключения – строкой C вида `module.classname`. Аргументы *base* и *dict* обычно равны *NULL*. Создаётся объект класса, производный от [`Exception`](https://python-all.ru/3.4/library/exceptions.html#Exception) (доступен в C как `PyExc_Exception`).250251Атрибут `__module__` нового класса устанавливается в первую часть (до последней точки) аргумента *name*, а имя класса – в последнюю часть (после последней точки). Аргумент *base* можно использовать для указания альтернативных базовых классов; это может быть как один класс, так и кортеж классов. Аргумент *dict* можно использовать для указания словаря переменных и методов класса.252253#### `PyObject* PyErr_NewExceptionWithDoc(const char *name, const char *doc, PyObject *base, PyObject *dict)`254255*Возвращаемое значение: новая ссылка.*256257То же, что [`PyErr_NewException()`](https://python-all.ru/3.4/c-api/exceptions.html#c.PyErr_NewException), за исключением того, что новому классу исключения можно легко задать строку документации: если *doc* не равен *NULL*, он будет использован как docstring класса исключения.258259Новое в версии 3.2.260261#### `void PyErr_WriteUnraisable(PyObject *obj)`262263Эта вспомогательная функция выводит предупреждение в `sys.stderr`, когда исключение установлено, но интерпретатор не может его фактически возбудить. Используется, например, когда исключение возникает в методе [`__del__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__del__).264265Функция вызывается с одним аргументом *obj*, который идентифицирует контекст, в котором возникло не вызываемое исключение. В сообщении предупреждения будет выведено repr от *obj*.266267## Объекты исключений268269#### `PyObject* PyException_GetTraceback(PyObject *ex)`270271*Возвращаемое значение: новая ссылка.*272273Возвращает traceback, связанный с исключением, как новую ссылку, доступную из Python через `__traceback__`. Если traceback не связан, возвращает *NULL*.274275#### `int PyException_SetTraceback(PyObject *ex, PyObject *tb)`276277Устанавливает traceback, связанный с исключением, в *tb*. Используйте `Py_None` для его очистки.278279#### `PyObject* PyException_GetContext(PyObject *ex)`280281Возвращает контекст (другой экземпляр исключения, при обработке которого было возбуждено *ex*), связанный с исключением, как новую ссылку, доступную из Python через `__context__`. Если контекст не связан, возвращает *NULL*.282283#### `void PyException_SetContext(PyObject *ex, PyObject *ctx)`284285Устанавливает контекст, связанный с исключением, в *ctx*. Используйте *NULL* для его очистки. Проверка типа на то, что *ctx* является экземпляром исключения, не выполняется. Функция забирает ссылку на *ctx*.286287#### `PyObject* PyException_GetCause(PyObject *ex)`288289Возвращает причину (либо экземпляр исключения, либо [`None`](https://python-all.ru/3.4/library/constants.html#None), установленную конструкцией `raise ... from ...`), связанную с исключением, как новую ссылку, доступную из Python через `__cause__`.290291#### `void PyException_SetCause(PyObject *ex, PyObject *cause)`292293Устанавливает причину, связанную с исключением, в *cause*. Используйте *NULL* для её очистки. Проверка типа, что *cause* является экземпляром исключения или [`None`](https://python-all.ru/3.4/library/constants.html#None), не выполняется. Эта функция похищает ссылку на *cause*.294295Эта функция неявно устанавливает `__suppress_context__` в `True`.296297## Объекты исключений Unicode298299Следующие функции используются для создания и изменения исключений Unicode из C.300301#### `PyObject* PyUnicodeDecodeError_Create(const char *encoding, const char *object, Py_ssize_t length, Py_ssize_t start, Py_ssize_t end, const char *reason)`302303Создаёт объект [`UnicodeDecodeError`](https://python-all.ru/3.4/library/exceptions.html#UnicodeDecodeError) с атрибутами *encoding*, *object*, *length*, *start*, *end* и *reason*. *encoding* и *reason* – строки в кодировке UTF-8.304305#### `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)`306307Создаёт объект [`UnicodeEncodeError`](https://python-all.ru/3.4/library/exceptions.html#UnicodeEncodeError) с атрибутами *encoding*, *object*, *length*, *start*, *end* и *reason*. *encoding* и *reason* – строки в кодировке UTF-8.308309#### `PyObject* PyUnicodeTranslateError_Create(const Py_UNICODE *object, Py_ssize_t length, Py_ssize_t start, Py_ssize_t end, const char *reason)`310311Создаёт объект [`UnicodeTranslateError`](https://python-all.ru/3.4/library/exceptions.html#UnicodeTranslateError) с атрибутами *object*, *length*, *start*, *end* и *reason*. *reason* – строка в кодировке UTF-8.312313#### `PyObject* PyUnicodeDecodeError_GetEncoding(PyObject *exc)`314315#### `PyObject* PyUnicodeEncodeError_GetEncoding(PyObject *exc)`316317Возвращает атрибут *encoding* указанного объекта исключения.318319#### `PyObject* PyUnicodeDecodeError_GetObject(PyObject *exc)`320321#### `PyObject* PyUnicodeEncodeError_GetObject(PyObject *exc)`322323#### `PyObject* PyUnicodeTranslateError_GetObject(PyObject *exc)`324325Возвращает атрибут *object* указанного объекта исключения.326327#### `int PyUnicodeDecodeError_GetStart(PyObject *exc, Py_ssize_t *start)`328329#### `int PyUnicodeEncodeError_GetStart(PyObject *exc, Py_ssize_t *start)`330331#### `int PyUnicodeTranslateError_GetStart(PyObject *exc, Py_ssize_t *start)`332333Получает атрибут *start* заданного объекта исключения и помещает его в *\*start*. *start* не должен быть *NULL*. Возвращает `0` в случае успеха, `-1` при неудаче.334335#### `int PyUnicodeDecodeError_SetStart(PyObject *exc, Py_ssize_t start)`336337#### `int PyUnicodeEncodeError_SetStart(PyObject *exc, Py_ssize_t start)`338339#### `int PyUnicodeTranslateError_SetStart(PyObject *exc, Py_ssize_t start)`340341Устанавливает атрибут *start* указанного объекта исключения в значение *start*. Возвращает `0` при успехе, `-1` при ошибке.342343#### `int PyUnicodeDecodeError_GetEnd(PyObject *exc, Py_ssize_t *end)`344345#### `int PyUnicodeEncodeError_GetEnd(PyObject *exc, Py_ssize_t *end)`346347#### `int PyUnicodeTranslateError_GetEnd(PyObject *exc, Py_ssize_t *end)`348349Получает атрибут *end* заданного объекта исключения и помещает его в *\*end*. *end* не должен быть *NULL*. Возвращает `0` в случае успеха, `-1` при неудаче.350351#### `int PyUnicodeDecodeError_SetEnd(PyObject *exc, Py_ssize_t end)`352353#### `int PyUnicodeEncodeError_SetEnd(PyObject *exc, Py_ssize_t end)`354355#### `int PyUnicodeTranslateError_SetEnd(PyObject *exc, Py_ssize_t end)`356357Устанавливает атрибут *end* указанного объекта исключения в *end*. Возвращает `0` в случае успеха, `-1` при ошибке.358359#### `PyObject* PyUnicodeDecodeError_GetReason(PyObject *exc)`360361#### `PyObject* PyUnicodeEncodeError_GetReason(PyObject *exc)`362363#### `PyObject* PyUnicodeTranslateError_GetReason(PyObject *exc)`364365Возвращает атрибут *reason* указанного объекта исключения.366367#### `int PyUnicodeDecodeError_SetReason(PyObject *exc, const char *reason)`368369#### `int PyUnicodeEncodeError_SetReason(PyObject *exc, const char *reason)`370371#### `int PyUnicodeTranslateError_SetReason(PyObject *exc, const char *reason)`372373Устанавливает атрибут *reason* указанного объекта исключения в значение *reason*. Возвращает `0` в случае успеха, `-1` в случае ошибки.374375## Управление рекурсией376377Эти две функции предоставляют способ выполнения безопасных рекурсивных вызовов на уровне C как в ядре, так и в модулях расширения. Они необходимы, если рекурсивный код не обязательно вызывает код Python (который автоматически отслеживает свою глубину рекурсии).378379#### `int Py_EnterRecursiveCall(const char *where)`380381Отмечает точку, в которой будет выполнен рекурсивный вызов на уровне C.382383Если определён `USE_STACKCHECK`, эта функция проверяет, не переполнился ли стек ОС с помощью [`PyOS_CheckStack()`](https://python-all.ru/3.4/c-api/sys.html#c.PyOS_CheckStack). Если это так, она устанавливает [`MemoryError`](https://python-all.ru/3.4/library/exceptions.html#MemoryError) и возвращает ненулевое значение.384385Затем функция проверяет, достигнут ли лимит рекурсии. Если это так, устанавливается [`RuntimeError`](https://python-all.ru/3.4/library/exceptions.html#RuntimeError) и возвращается ненулевое значение. В противном случае возвращается ноль.386387*where* должна быть строкой, например `" in instance check"`, которая будет добавлена к сообщению [`RuntimeError`](https://python-all.ru/3.4/library/exceptions.html#RuntimeError), вызванному пределом глубины рекурсии.388389#### `void Py_LeaveRecursiveCall()`390391Завершает [`Py_EnterRecursiveCall()`](https://python-all.ru/3.4/c-api/exceptions.html#c.Py_EnterRecursiveCall). Должен вызываться один раз для каждого *успешного* вызова [`Py_EnterRecursiveCall()`](https://python-all.ru/3.4/c-api/exceptions.html#c.Py_EnterRecursiveCall).392393Правильная реализация [`tp_repr`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_repr) для контейнерных типов требует специальной обработки рекурсии. Помимо защиты стека, [`tp_repr`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_repr) также должен отслеживать объекты для предотвращения циклов. Следующие две функции упрощают эту функциональность. По сути, это C-эквивалент [`reprlib.recursive_repr()`](https://python-all.ru/3.4/library/reprlib.html#reprlib.recursive_repr).394395#### `int Py_ReprEnter(PyObject *object)`396397Вызывается в начале реализации [`tp_repr`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_repr) для обнаружения циклов.398399Если объект уже был обработан, функция возвращает положительное целое число. В этом случае реализация [`tp_repr`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_repr) должна вернуть строковый объект, указывающий на цикл. Например, объекты [`dict`](https://python-all.ru/3.4/library/stdtypes.html#dict) возвращают `{...}`, а объекты [`list`](https://python-all.ru/3.4/library/stdtypes.html#list) возвращают `[...]`.400401Функция вернёт отрицательное целое число, если превышен лимит рекурсии. В этом случае реализация [`tp_repr`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_repr) обычно должна возвращать `NULL`.402403В противном случае функция возвращает ноль, и реализация [`tp_repr`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_repr) может продолжить работу нормально.404405#### `void Py_ReprLeave(PyObject *object)`406407Завершает [`Py_ReprEnter()`](https://python-all.ru/3.4/c-api/exceptions.html#c.Py_ReprEnter). Должен вызываться один раз для каждого вызова [`Py_ReprEnter()`](https://python-all.ru/3.4/c-api/exceptions.html#c.Py_ReprEnter), который возвращает ноль.408409## Стандартные исключения410411Все стандартные исключения Python доступны как глобальные переменные, имена которых состоят из `PyExc_`, за которым следует имя исключения Python. Они имеют тип [`PyObject*`](https://python-all.ru/3.4/c-api/structures.html#c.PyObject); все они являются объектами классов. Для полноты картины, вот все переменные:412413| Имя в C | Имя в Python | Примечания |414| --- | --- | --- |415| `PyExc_BaseException` | [`BaseException`](https://python-all.ru/3.4/library/exceptions.html#BaseException) | (1) |416| `PyExc_Exception` | [`исключение`](https://python-all.ru/3.4/library/exceptions.html#Exception) | (1) |417| `PyExc_ArithmeticError` | [`ArithmeticError`](https://python-all.ru/3.4/library/exceptions.html#ArithmeticError) | (1) |418| `PyExc_LookupError` | [`LookupError`](https://python-all.ru/3.4/library/exceptions.html#LookupError) | (1) |419| `PyExc_AssertionError` | [`AssertionError`](https://python-all.ru/3.4/library/exceptions.html#AssertionError) | |420| `PyExc_AttributeError` | [`AttributeError`](https://python-all.ru/3.4/library/exceptions.html#AttributeError) | |421| `PyExc_BlockingIOError` | [`BlockingIOError`](https://python-all.ru/3.4/library/exceptions.html#BlockingIOError) | |422| `PyExc_BrokenPipeError` | [`BrokenPipeError`](https://python-all.ru/3.4/library/exceptions.html#BrokenPipeError) | |423| `PyExc_ChildProcessError` | [`ChildProcessError`](https://python-all.ru/3.4/library/exceptions.html#ChildProcessError) | |424| `PyExc_ConnectionError` | [`ConnectionError`](https://python-all.ru/3.4/library/exceptions.html#ConnectionError) | |425| `PyExc_ConnectionAbortedError` | [`ConnectionAbortedError`](https://python-all.ru/3.4/library/exceptions.html#ConnectionAbortedError) | |426| `PyExc_ConnectionRefusedError` | [`ConnectionRefusedError`](https://python-all.ru/3.4/library/exceptions.html#ConnectionRefusedError) | |427| `PyExc_ConnectionResetError` | [`ConnectionResetError`](https://python-all.ru/3.4/library/exceptions.html#ConnectionResetError) | |428| `PyExc_FileExistsError` | [`FileExistsError`](https://python-all.ru/3.4/library/exceptions.html#FileExistsError) | |429| `PyExc_FileNotFoundError` | [`FileNotFoundError`](https://python-all.ru/3.4/library/exceptions.html#FileNotFoundError) | |430| `PyExc_EOFError` | [`EOFError`](https://python-all.ru/3.4/library/exceptions.html#EOFError) | |431| `PyExc_FloatingPointError` | [`FloatingPointError`](https://python-all.ru/3.4/library/exceptions.html#FloatingPointError) | |432| `PyExc_ImportError` | [`ImportError`](https://python-all.ru/3.4/library/exceptions.html#ImportError) | |433| `PyExc_IndexError` | [`IndexError`](https://python-all.ru/3.4/library/exceptions.html#IndexError) | |434| `PyExc_InterruptedError` | [`InterruptedError`](https://python-all.ru/3.4/library/exceptions.html#InterruptedError) | |435| `PyExc_IsADirectoryError` | [`IsADirectoryError`](https://python-all.ru/3.4/library/exceptions.html#IsADirectoryError) | |436| `PyExc_KeyError` | [`KeyError`](https://python-all.ru/3.4/library/exceptions.html#KeyError) | |437| `PyExc_KeyboardInterrupt` | [`KeyboardInterrupt`](https://python-all.ru/3.4/library/exceptions.html#KeyboardInterrupt) | |438| `PyExc_MemoryError` | [`MemoryError`](https://python-all.ru/3.4/library/exceptions.html#MemoryError) | |439| `PyExc_NameError` | [`NameError`](https://python-all.ru/3.4/library/exceptions.html#NameError) | |440| `PyExc_NotADirectoryError` | [`NotADirectoryError`](https://python-all.ru/3.4/library/exceptions.html#NotADirectoryError) | |441| `PyExc_NotImplementedError` | [`NotImplementedError`](https://python-all.ru/3.4/library/exceptions.html#NotImplementedError) | |442| `PyExc_OSError` | [`OSError`](https://python-all.ru/3.4/library/exceptions.html#OSError) | (1) |443| `PyExc_OverflowError` | [`OverflowError`](https://python-all.ru/3.4/library/exceptions.html#OverflowError) | |444| `PyExc_PermissionError` | [`PermissionError`](https://python-all.ru/3.4/library/exceptions.html#PermissionError) | |445| `PyExc_ProcessLookupError` | [`ProcessLookupError`](https://python-all.ru/3.4/library/exceptions.html#ProcessLookupError) | |446| `PyExc_ReferenceError` | [`ReferenceError`](https://python-all.ru/3.4/library/exceptions.html#ReferenceError) | (2) |447| `PyExc_RuntimeError` | [`RuntimeError`](https://python-all.ru/3.4/library/exceptions.html#RuntimeError) | |448| `PyExc_SyntaxError` | [`SyntaxError`](https://python-all.ru/3.4/library/exceptions.html#SyntaxError) | |449| `PyExc_SystemError` | [`SystemError`](https://python-all.ru/3.4/library/exceptions.html#SystemError) | |450| `PyExc_TimeoutError` | [`TimeoutError`](https://python-all.ru/3.4/library/exceptions.html#TimeoutError) | |451| `PyExc_SystemExit` | [`SystemExit`](https://python-all.ru/3.4/library/exceptions.html#SystemExit) | |452| `PyExc_TypeError` | [`TypeError`](https://python-all.ru/3.4/library/exceptions.html#TypeError) | |453| `PyExc_ValueError` | [`ValueError`](https://python-all.ru/3.4/library/exceptions.html#ValueError) | |454| `PyExc_ZeroDivisionError` | [`ZeroDivisionError`](https://python-all.ru/3.4/library/exceptions.html#ZeroDivisionError) | |455456Новое в версии 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**](https://python-all.ru/3.4/c-api/exceptions.html).457458Это псевдонимы для совместимости с `PyExc_OSError`:459460| Имя в C | Примечания |461| --- | --- |462| `PyExc_EnvironmentError` | |463| `PyExc_IOError` | |464| `PyExc_WindowsError` | (3) |465466Изменено в версии 3.3: Раньше эти псевдонимы были отдельными типами исключений.467468Примечания:4694701. Это базовый класс для других стандартных исключений.4712. То же самое, что [`weakref.ReferenceError`](https://python-all.ru/3.4/library/weakref.html#weakref.ReferenceError).4723. Определён только в Windows; код, использующий это, должен проверять, определён ли макрос препроцессора `MS_WINDOWS`.473