exceptions.md
1> **Источник:** https://python-all.ru/3.5/c-api/exceptions.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# Обработка исключений89Функции, описанные в этой главе, позволяют обрабатывать и возбуждать исключения Python. Важно понимать некоторые основы обработки исключений Python. Она работает примерно как переменная `errno` в POSIX: существует глобальный (потоковый) индикатор последней произошедшей ошибки. Большинство функций C API не сбрасывают его при успехе, но устанавливают для указания причины ошибки при неудаче. Большинство функций C API также возвращают индикатор ошибки, обычно *NULL*, если они должны возвращать указатель, или `-1`, если возвращают целое число (исключение: функции `PyArg_*()` возвращают `1` при успехе и `0` при ошибке).1011Конкретно, индикатор ошибки состоит из трёх указателей на объекты: типа исключения, значения исключения и объекта traceback. Любой из этих указателей может быть NULL, если не установлен (хотя некоторые комбинации запрещены; например, нельзя иметь ненулевой traceback, если тип исключения NULL).1213Когда функция должна завершиться ошибкой, потому что вызванная ей функция завершилась ошибкой, она обычно не устанавливает индикатор ошибки; его уже установила вызванная функция. Она отвечает либо за обработку ошибки и очистку исключения, либо за возврат после освобождения всех удерживаемых ресурсов (таких как ссылки на объекты или выделенная память); она *не* должна продолжать нормальное выполнение, если не готова обработать ошибку. При возврате из-за ошибки важно указать вызывающему коду, что ошибка была установлена. Если ошибка не обрабатывается или не аккуратно распространяется, последующие вызовы Python/C API могут вести себя не так, как задумано, и могут отказать загадочным образом.1415> **Примечание**16>17> Индикатор ошибки **не** является результатом [`sys.exc_info()`](https://python-all.ru/3.5/library/sys.html#sys.exc_info). Первый соответствует исключению, которое еще не перехвачено (и поэтому все еще распространяется), тогда как второй возвращает исключение после его перехвата (и поэтому прекратило распространение).1819## Печать и очистка2021#### `void PyErr_Clear()`2223Очищает индикатор ошибки. Если индикатор ошибки не установлен, эффекта нет.2425#### `void PyErr_PrintEx(int set_sys_last_vars)`2627Выводит стандартную трассировку в `sys.stderr` и очищает индикатор ошибки. Эту функцию следует вызывать только при установленном индикаторе ошибки. (В противном случае произойдет фатальная ошибка!)2829Если *set\_sys\_last\_vars* ненулевое, переменные [`sys.last_type`](https://python-all.ru/3.5/library/sys.html#sys.last_type), [`sys.last_value`](https://python-all.ru/3.5/library/sys.html#sys.last_value) и [`sys.last_traceback`](https://python-all.ru/3.5/library/sys.html#sys.last_traceback) будут установлены в тип, значение и трассировку напечатанного исключения соответственно.3031#### `void PyErr_Print()`3233Псевдоним для `PyErr_PrintEx(1)`.3435#### `void PyErr_WriteUnraisable(PyObject *obj)`3637Эта вспомогательная функция выводит предупреждающее сообщение в `sys.stderr`, когда исключение было установлено, но интерпретатор не может его фактически возбудить. Она используется, например, когда исключение возникает в методе [`__del__()`](https://python-all.ru/3.5/reference/datamodel.html#object.__del__).3839Функция вызывается с единственным аргументом *obj*, идентифицирующим контекст, в котором возникло необрабатываемое исключение. Если возможно, в предупреждающем сообщении будет выведено представление (repr) *obj*.4041## Возбуждение исключений4243Эти функции помогают установить индикатор ошибки текущего потока. Для удобства некоторые из этих функций всегда возвращают указатель NULL для использования в операторе `return`.4445#### `void PyErr_SetString(PyObject *type, const char *message)`4647Это наиболее распространенный способ установки индикатора ошибки. Первый аргумент задает тип исключения; обычно это одно из стандартных исключений, например `PyExc_RuntimeError`. Увеличивать счетчик ссылок для него не требуется. Второй аргумент – сообщение об ошибке; оно декодируется из `'utf-8`’.4849#### `void PyErr_SetObject(PyObject *type, PyObject *value)`5051Эта функция аналогична [`PyErr_SetString()`](https://python-all.ru/3.5/c-api/exceptions.html#c.PyErr_SetString), но позволяет указать произвольный объект Python для «значения» исключения.5253#### `PyObject* PyErr_Format(PyObject *exception, const char *format, ...)`5455*Возвращаемое значение: всегда NULL.*5657Эта функция устанавливает индикатор ошибки и возвращает *NULL*. *исключение* должен быть классом исключения Python. Параметр *format* и последующие параметры помогают форматировать сообщение об ошибке; они имеют тот же смысл и значения, что и в [`PyUnicode_FromFormat()`](https://python-all.ru/3.5/c-api/unicode.html#c.PyUnicode_FromFormat). *format* – это строка в кодировке ASCII.5859#### `PyObject* PyErr_FormatV(PyObject *exception, const char *format, va_list vargs)`6061*Возвращаемое значение: всегда NULL.*6263То же, что и [`PyErr_Format()`](https://python-all.ru/3.5/c-api/exceptions.html#c.PyErr_Format), но принимает аргумент `va_list` вместо переменного числа аргументов.6465Новое в версии 3.5.6667#### `void PyErr_SetNone(PyObject *type)`6869Это сокращение для `PyErr_SetObject(type, Py_None)`.7071#### `int PyErr_BadArgument()`7273Это сокращение для `PyErr_SetString(PyExc_TypeError, message)`, где *message* указывает, что встроенная операция была вызвана с недопустимым аргументом. В основном предназначено для внутреннего использования.7475#### `PyObject* PyErr_NoMemory()`7677*Возвращаемое значение: всегда NULL.*7879Это сокращённая запись для `PyErr_SetNone(PyExc_MemoryError)`; она возвращает *NULL*, чтобы функция выделения объекта могла записать `return PyErr_NoMemory();` при нехватке памяти.8081#### `PyObject* PyErr_SetFromErrno(PyObject *type)`8283*Возвращаемое значение: всегда NULL.*8485Это удобная функция для возбуждения исключения, когда библиотечная функция C вернула ошибку и установила переменную C `errno`. Она создаёт объект-кортеж, первый элемент которого – целое значение `errno`, а второй – соответствующее сообщение об ошибке (полученное из `strerror()`), и затем вызывает `PyErr_SetObject(type, object)`. В Unix, когда значение `errno` равно `EINTR`, что указывает на прерванный системный вызов, эта функция вызывает [`PyErr_CheckSignals()`](https://python-all.ru/3.5/c-api/exceptions.html#c.PyErr_CheckSignals), и если тот устанавливает индикатор ошибки, оставляет его установленным. Функция всегда возвращает *NULL*, поэтому функция-обёртка вокруг системного вызова может записать `return PyErr_SetFromErrno(type);`, когда системный вызов возвращает ошибку.8687#### `PyObject* PyErr_SetFromErrnoWithFilenameObject(PyObject *type, PyObject *filenameObject)`8889Аналогично [`PyErr_SetFromErrno()`](https://python-all.ru/3.5/c-api/exceptions.html#c.PyErr_SetFromErrno), с дополнительным поведением: если *filenameObject* не равен *NULL*, он передаётся конструктору *type* в качестве третьего параметра. В случае исключения [`OSError`](https://python-all.ru/3.5/library/exceptions.html#OSError) это используется для определения атрибута `filename` экземпляра исключения.9091#### `PyObject* PyErr_SetFromErrnoWithFilenameObjects(PyObject *type, PyObject *filenameObject, PyObject *filenameObject2)`9293Аналогично [`PyErr_SetFromErrnoWithFilenameObject()`](https://python-all.ru/3.5/c-api/exceptions.html#c.PyErr_SetFromErrnoWithFilenameObject), но принимает второй объект имени файла; используется для возбуждения ошибок, когда функция, принимающая два имени файла, завершается неудачей.9495Новое в версии 3.4.9697#### `PyObject* PyErr_SetFromErrnoWithFilename(PyObject *type, const char *filename)`9899*Возвращаемое значение: всегда NULL.*100101Аналогично [`PyErr_SetFromErrnoWithFilenameObject()`](https://python-all.ru/3.5/c-api/exceptions.html#c.PyErr_SetFromErrnoWithFilenameObject), но имя файла задаётся как C-строка. *filename* декодируется из кодировки файловой системы ([`os.fsdecode()`](https://python-all.ru/3.5/library/os.html#os.fsdecode)).102103#### `PyObject* PyErr_SetFromWindowsErr(int ierr)`104105*Возвращаемое значение: всегда NULL.*106107Это удобная функция для возбуждения [`WindowsError`](https://python-all.ru/3.5/library/exceptions.html#WindowsError). Если она вызвана с *ierr* равным `0`, используется код ошибки, возвращённый вызовом `GetLastError()`. Она вызывает функцию Win32 `FormatMessage()` для получения описания Windows для кода ошибки, заданного *ierr* или `GetLastError()`, затем создаёт объект-кортеж, первый элемент которого – значение *ierr*, а второй – соответствующее сообщение об ошибке (полученное из `FormatMessage()`), и затем вызывает `PyErr_SetObject(PyExc_WindowsError, object)`. Эта функция всегда возвращает *NULL*. Доступность: Windows.108109#### `PyObject* PyErr_SetExcFromWindowsErr(PyObject *type, int ierr)`110111*Возвращаемое значение: всегда NULL.*112113Аналогично [`PyErr_SetFromWindowsErr()`](https://python-all.ru/3.5/c-api/exceptions.html#c.PyErr_SetFromWindowsErr), с дополнительным параметром, указывающим тип возбуждаемого исключения. Доступность: Windows.114115#### `PyObject* PyErr_SetFromWindowsErrWithFilename(int ierr, const char *filename)`116117*Возвращаемое значение: всегда NULL.*118119Аналогично `PyErr_SetFromWindowsErrWithFilenameObject()`, но имя файла задаётся как строка C. *filename* декодируется из файловой системной кодировки ([`os.fsdecode()`](https://python-all.ru/3.5/library/os.html#os.fsdecode)). Доступность: Windows.120121#### `PyObject* PyErr_SetExcFromWindowsErrWithFilenameObject(PyObject *type, int ierr, PyObject *filename)`122123Аналогично `PyErr_SetFromWindowsErrWithFilenameObject()`, с дополнительным параметром, указывающим тип возбуждаемого исключения. Доступность: Windows.124125#### `PyObject* PyErr_SetExcFromWindowsErrWithFilenameObjects(PyObject *type, int ierr, PyObject *filename, PyObject *filename2)`126127Аналогично [`PyErr_SetExcFromWindowsErrWithFilenameObject()`](https://python-all.ru/3.5/c-api/exceptions.html#c.PyErr_SetExcFromWindowsErrWithFilenameObject), но принимает второй объект имени файла. Доступность: Windows.128129Новое в версии 3.4.130131#### `PyObject* PyErr_SetExcFromWindowsErrWithFilename(PyObject *type, int ierr, const char *filename)`132133*Возвращаемое значение: всегда NULL.*134135Аналогично [`PyErr_SetFromWindowsErrWithFilename()`](https://python-all.ru/3.5/c-api/exceptions.html#c.PyErr_SetFromWindowsErrWithFilename), с дополнительным параметром, указывающим тип возбуждаемого исключения. Доступность: Windows.136137#### `PyObject* PyErr_SetImportError(PyObject *msg, PyObject *name, PyObject *path)`138139Это удобная функция для возбуждения [`ImportError`](https://python-all.ru/3.5/library/exceptions.html#ImportError). *msg* будет установлен как строка сообщения исключения. *name* и *path*, оба могут быть `NULL`, будут установлены как соответствующие атрибуты [`ImportError`](https://python-all.ru/3.5/library/exceptions.html#ImportError): `name` и `path`.140141Новое в версии 3.3.142143#### `void PyErr_SyntaxLocationObject(PyObject *filename, int lineno, int col_offset)`144145Устанавливает информацию о файле, строке и смещении для текущего исключения. Если текущее исключение не является [`SyntaxError`](https://python-all.ru/3.5/library/exceptions.html#SyntaxError), то устанавливаются дополнительные атрибуты, из-за которых подсистема печати исключений считает исключение [`SyntaxError`](https://python-all.ru/3.5/library/exceptions.html#SyntaxError).146147Новое в версии 3.4.148149#### `void PyErr_SyntaxLocationEx(const char *filename, int lineno, int col_offset)`150151Как и [`PyErr_SyntaxLocationObject()`](https://python-all.ru/3.5/c-api/exceptions.html#c.PyErr_SyntaxLocationObject), но *filename* – это байтовая строка, декодированная из файловой системной кодировки ([`os.fsdecode()`](https://python-all.ru/3.5/library/os.html#os.fsdecode)).152153Новое в версии 3.2.154155#### `void PyErr_SyntaxLocation(const char *filename, int lineno)`156157Как [`PyErr_SyntaxLocationEx()`](https://python-all.ru/3.5/c-api/exceptions.html#c.PyErr_SyntaxLocationEx), но параметр col\_offset опущен.158159#### `void PyErr_BadInternalCall()`160161Это сокращение для `PyErr_SetString(PyExc_SystemError, message)`, где *message* указывает, что внутренняя операция (например, функция Python/C API) была вызвана с недопустимым аргументом. Предназначено в основном для внутреннего использования.162163## Выдача предупреждений164165Используйте эти функции для выдачи предупреждений из кода на C. Они аналогичны соответствующим функциям, экспортируемым модулем Python [`warnings`](https://python-all.ru/3.5/library/warnings.html#module-warnings). Обычно они выводят предупреждающее сообщение в *sys.stderr*; однако возможно, что пользователь указал превращать предупреждения в ошибки, и в этом случае они возбудят исключение. Также возможно, что функции возбуждают исключение из-за проблемы с механизмом предупреждений. Возвращаемое значение – `0`, если исключение не возбуждено, или `-1`, если исключение возбуждено. (Невозможно определить, было ли предупреждение фактически напечатано или какова причина исключения; это сделано намеренно.) Если исключение возбуждено, вызывающий код должен выполнить обычную обработку исключений (например, [`Py_DECREF()`](https://python-all.ru/3.5/c-api/refcounting.html#c.Py_DECREF) принадлежащие ссылки и вернуть значение ошибки).166167#### `int PyErr_WarnEx(PyObject *category, const char *message, Py_ssize_t stack_level)`168169Выдаёт предупреждение. Аргумент *category* – это категория предупреждения (см. ниже) или *NULL*; аргумент *message* – строка в кодировке UTF-8. *stack\_level* – положительное число, задающее количество кадров стека; предупреждение будет выдано из текущей исполняемой строки кода в этом кадре стека. Значение *stack\_level* равное 1 соответствует функции, вызывающей [`PyErr_WarnEx()`](https://python-all.ru/3.5/c-api/exceptions.html#c.PyErr_WarnEx), 2 – функции уровнем выше и так далее.170171Категории предупреждений должны быть подклассами `PyExc_Warning`; `PyExc_Warning` является подклассом `PyExc_Exception`; категория предупреждений по умолчанию – `PyExc_RuntimeWarning`. Стандартные категории предупреждений Python доступны в виде глобальных переменных, имена которых перечислены в разделе [Стандартные категории предупреждений](https://python-all.ru/3.5/c-api/exceptions.html#standardwarningcategories).172173Информацию об управлении предупреждениями см. в документации модуля [`warnings`](https://python-all.ru/3.5/library/warnings.html#module-warnings) и опции [`-W`](https://python-all.ru/3.5/using/cmdline.html#cmdoption-w) в документации командной строки. API для управления предупреждениями на C не существует.174175#### `int PyErr_WarnExplicitObject(PyObject *category, PyObject *message, PyObject *filename, int lineno, PyObject *module, PyObject *registry)`176177Выдаёт предупреждение с явным контролем всех атрибутов предупреждения. Это прямая обёртка вокруг функции Python [`warnings.warn_explicit()`](https://python-all.ru/3.5/library/warnings.html#warnings.warn_explicit); обратитесь к ней за дополнительной информацией. Аргументы *module* и *registry* могут быть установлены в *NULL* для получения описанного там эффекта по умолчанию.178179Новое в версии 3.4.180181#### `int PyErr_WarnExplicit(PyObject *category, const char *message, const char *filename, int lineno, const char *module, PyObject *registry)`182183Похоже на [`PyErr_WarnExplicitObject()`](https://python-all.ru/3.5/c-api/exceptions.html#c.PyErr_WarnExplicitObject), за исключением того, что *message* и *module* – это строки в кодировке UTF-8, а *filename* декодируется из файловой системной кодировки ([`os.fsdecode()`](https://python-all.ru/3.5/library/os.html#os.fsdecode)).184185#### `int PyErr_WarnFormat(PyObject *category, Py_ssize_t stack_level, const char *format, ...)`186187Функция, аналогичная [`PyErr_WarnEx()`](https://python-all.ru/3.5/c-api/exceptions.html#c.PyErr_WarnEx), но использующая [`PyUnicode_FromFormat()`](https://python-all.ru/3.5/c-api/unicode.html#c.PyUnicode_FromFormat) для форматирования предупреждающего сообщения. *format* – это строка в ASCII-кодировке.188189Новое в версии 3.2.190191## Опрос индикатора ошибки192193#### `PyObject* PyErr_Occurred()`194195*Возвращаемое значение: заимствованная ссылка.*196197Проверяет, установлен ли индикатор ошибки. Если установлен, возвращает *type* исключения (первый аргумент последнего вызова одной из функций `PyErr_Set*()` или [`PyErr_Restore()`](https://python-all.ru/3.5/c-api/exceptions.html#c.PyErr_Restore)). Если не установлен, возвращает *NULL*. Вы не владеете ссылкой на возвращаемое значение, поэтому вам не нужно его [`Py_DECREF()`](https://python-all.ru/3.5/c-api/refcounting.html#c.Py_DECREF).198199> **Примечание**200>201> Не сравнивайте возвращаемое значение с конкретным исключением; используйте вместо этого [`PyErr_ExceptionMatches()`](https://python-all.ru/3.5/c-api/exceptions.html#c.PyErr_ExceptionMatches), как показано ниже. (Сравнение может легко не сработать, так как исключение может быть экземпляром, а не классом (в случае классового исключения) или подклассом ожидаемого исключения.)202203#### `int PyErr_ExceptionMatches(PyObject *exc)`204205Эквивалентно `PyErr_GivenExceptionMatches(PyErr_Occurred(), exc)`. Эту функцию следует вызывать только тогда, когда исключение действительно установлено; при отсутствии возбуждённого исключения произойдёт нарушение доступа к памяти.206207#### `int PyErr_GivenExceptionMatches(PyObject *given, PyObject *exc)`208209Возвращает истину, если *заданное* исключение соответствует типу исключения в *exc*. Если *exc* – объект класса, также возвращает истину, когда *given* является экземпляром подкласса. Если *exc* – кортеж, производится поиск соответствия среди всех типов исключений в кортеже (и рекурсивно во вложенных кортежах).210211#### `void PyErr_Fetch(PyObject **ptype, PyObject **pvalue, PyObject **ptraceback)`212213Извлекает индикатор ошибки в три переменные, адреса которых передаются. Если индикатор ошибки не установлен, устанавливает все три переменные в *NULL*. Если установлен, он будет очищен, и вы получаете владение ссылкой на каждый извлечённый объект. Значение и объект traceback могут быть *NULL*, даже если объект типа не NULL.214215> **Примечание**216>217> Обычно эта функция используется только в коде, которому требуется перехватывать исключения, или в коде, которому нужно временно сохранять и восстанавливать индикатор ошибки. Например:218>219> ```c220> {221> PyObject *type, *value, *traceback;222> PyErr_Fetch(&type, &value, &traceback);223>224> /* ... код, который может вызвать другие ошибки ... */225>226> PyErr_Restore(type, value, traceback);227> }228> ```229230#### `void PyErr_Restore(PyObject *type, PyObject *value, PyObject *traceback)`231232Set 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.)233234> **Примечание**235>236> Обычно эта функция используется только в коде, которому нужно временно сохранять и восстанавливать индикатор ошибки. Используйте [`PyErr_Fetch()`](https://python-all.ru/3.5/c-api/exceptions.html#c.PyErr_Fetch) для сохранения текущего индикатора ошибки.237238#### `void PyErr_NormalizeException(PyObject**exc, PyObject**val, PyObject**tb)`239240При определенных обстоятельствах значения, возвращаемые [`PyErr_Fetch()`](https://python-all.ru/3.5/c-api/exceptions.html#c.PyErr_Fetch) ниже, могут быть «ненормализованными», то есть `*exc` является объектом класса, но `*val` не является экземпляром того же класса. В этом случае данная функция может использоваться для создания экземпляра класса. Если значения уже нормализованы, ничего не происходит. Отложенная нормализация реализована для повышения производительности.241242> **Примечание**243>244> Эта функция *не* устанавливает неявно атрибут `__traceback__` значения исключения. Если требуется корректно установить traceback, понадобится следующий дополнительный фрагмент кода:245>246> ```c247> if (tb != NULL) {248> PyException_SetTraceback(val, tb);249> }250> ```251252#### `void PyErr_GetExcInfo(PyObject **ptype, PyObject **pvalue, PyObject **ptraceback)`253254Извлекает информацию об исключении, как она известна из `sys.exc_info()`. Это относится к исключению, которое было *уже перехвачено*, а не к только что возбуждённому. Возвращает новые ссылки на три объекта, любой из которых может быть *NULL*. Не изменяет состояние информации об исключении.255256> **Примечание**257>258> Эта функция обычно не используется кодом, который хочет обрабатывать исключения. Скорее, она может использоваться, когда коду нужно временно сохранить и восстановить состояние исключения. Используйте [`PyErr_SetExcInfo()`](https://python-all.ru/3.5/c-api/exceptions.html#c.PyErr_SetExcInfo), чтобы восстановить или очистить состояние исключения.259260Новое в версии 3.3.261262#### `void PyErr_SetExcInfo(PyObject *type, PyObject *value, PyObject *traceback)`263264Устанавливает информацию об исключении, как она известна из `sys.exc_info()`. Это относится к исключению, которое было *уже перехвачено*, а не к только что возбуждённому. Эта функция крадёт ссылки аргументов. Чтобы очистить состояние исключения, передайте *NULL* для всех трёх аргументов. Общие правила относительно трёх аргументов см. в [`PyErr_Restore()`](https://python-all.ru/3.5/c-api/exceptions.html#c.PyErr_Restore).265266> **Примечание**267>268> Эта функция обычно не используется кодом, который хочет обрабатывать исключения. Скорее, она может использоваться, когда коду нужно временно сохранить и восстановить состояние исключения. Используйте [`PyErr_GetExcInfo()`](https://python-all.ru/3.5/c-api/exceptions.html#c.PyErr_GetExcInfo), чтобы прочитать состояние исключения.269270Новое в версии 3.3.271272## Обработка сигналов273274#### `int PyErr_CheckSignals()`275276Эта функция взаимодействует с обработкой сигналов Python. Она проверяет, был ли отправлен сигнал процессам, и если да, вызывает соответствующий обработчик сигнала. Если модуль [`signal`](https://python-all.ru/3.5/library/signal.html#module-signal) поддерживается, может быть вызван обработчик сигнала, написанный на Python. Во всех случаях эффект по умолчанию для `SIGINT` – возбуждение исключения [`KeyboardInterrupt`](https://python-all.ru/3.5/library/exceptions.html#KeyboardInterrupt). Если исключение возбуждено, устанавливается индикатор ошибки, и функция возвращает `-1`; в противном случае функция возвращает `0`. Индикатор ошибки может быть сброшен или не сброшен, если он был установлен ранее.277278#### `void PyErr_SetInterrupt()`279280Эта функция имитирует действие сигнала `SIGINT` – при следующем вызове [`PyErr_CheckSignals()`](https://python-all.ru/3.5/c-api/exceptions.html#c.PyErr_CheckSignals) будет возбуждено [`KeyboardInterrupt`](https://python-all.ru/3.5/library/exceptions.html#KeyboardInterrupt). Её можно вызывать, не удерживая блокировку интерпретатора.281282#### `int PySignal_SetWakeupFd(int fd)`283284Эта вспомогательная функция задаёт файловый дескриптор, в который при получении сигнала записывается номер сигнала в виде одного байта. *fd* должен быть неблокирующим. Функция возвращает предыдущий такой файловый дескриптор.285286Значение `-1` отключает эту возможность; это начальное состояние. Это эквивалентно [`signal.set_wakeup_fd()`](https://python-all.ru/3.5/library/signal.html#signal.set_wakeup_fd) в Python, но без проверки ошибок. *fd* должен быть корректным файловым дескриптором. Функцию следует вызывать только из главного потока.287288Изменено в версии 3.5: В Windows функция теперь также поддерживает дескрипторы сокетов.289290## Классы исключений291292#### `PyObject* PyErr_NewException(const char *name, PyObject *base, PyObject *dict)`293294*Возвращаемое значение: новая ссылка.*295296Эта вспомогательная функция создаёт и возвращает новый класс исключений. Аргумент *name* должен быть именем нового исключения – C-строка вида `module.classname`. Аргументы *base* и *dict* обычно равны *NULL*. В результате создаётся объект класса, производный от [`Exception`](https://python-all.ru/3.5/library/exceptions.html#Exception) (доступен в C как `PyExc_Exception`).297298Атрибут `__module__` нового класса устанавливается в первую часть (до последней точки) аргумента *name*, а имя класса – в последнюю часть (после последней точки). Аргумент *base* можно использовать для указания альтернативных базовых классов; это может быть как один класс, так и кортеж классов. Аргумент *dict* можно использовать для указания словаря переменных и методов класса.299300#### `PyObject* PyErr_NewExceptionWithDoc(const char *name, const char *doc, PyObject *base, PyObject *dict)`301302*Возвращаемое значение: новая ссылка.*303304То же, что и [`PyErr_NewException()`](https://python-all.ru/3.5/c-api/exceptions.html#c.PyErr_NewException), с тем отличием, что новому классу исключений можно легко задать docstring: если *doc* не равно *NULL*, оно будет использоваться как строка документации для класса исключений.305306Новое в версии 3.2.307308## Объекты исключений309310#### `PyObject* PyException_GetTraceback(PyObject *ex)`311312*Возвращаемое значение: новая ссылка.*313314Возвращает новую ссылку на traceback, связанный с исключением, доступную из Python через `__traceback__`. Если связанный traceback отсутствует, возвращается *NULL*.315316#### `int PyException_SetTraceback(PyObject *ex, PyObject *tb)`317318Устанавливает traceback, связанный с исключением, в значение *tb*. Используйте `Py_None`, чтобы очистить его.319320#### `PyObject* PyException_GetContext(PyObject *ex)`321322Возвращает новую ссылку на контекст (другой экземпляр исключения, при обработке которого было возбуждено *ex*), связанный с исключением, доступный из Python через `__context__`. Если связанный контекст отсутствует, возвращается *NULL*.323324#### `void PyException_SetContext(PyObject *ex, PyObject *ctx)`325326Устанавливает контекст, связанный с исключением, в *ctx*. Используйте *NULL* для его очистки. Проверка типа на то, что *ctx* является экземпляром исключения, не выполняется. Функция забирает ссылку на *ctx*.327328#### `PyObject* PyException_GetCause(PyObject *ex)`329330Возвращает новую ссылку на причину (экземпляр исключения или [`None`](https://python-all.ru/3.5/library/constants.html#None), установленную `raise ... from ...`), связанную с исключением, как доступно из Python через `__cause__`.331332#### `void PyException_SetCause(PyObject *ex, PyObject *cause)`333334Устанавливает причину, связанную с исключением, в *cause*. Используйте *NULL* для её очистки. Проверка типа на то, что *cause* является экземпляром исключения или [`None`](https://python-all.ru/3.5/library/constants.html#None), не выполняется. Функция забирает ссылку на *cause*.335336Эта функция неявно устанавливает `__suppress_context__` в `True`.337338## Объекты исключений Unicode339340Следующие функции используются для создания и изменения исключений Unicode из C.341342#### `PyObject* PyUnicodeDecodeError_Create(const char *encoding, const char *object, Py_ssize_t length, Py_ssize_t start, Py_ssize_t end, const char *reason)`343344Создаёт объект [`UnicodeDecodeError`](https://python-all.ru/3.5/library/exceptions.html#UnicodeDecodeError) с атрибутами *encoding*, *object*, *length*, *start*, *end* и *reason*. *encoding* и *reason* – это строки в кодировке UTF-8.345346#### `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)`347348Создаёт объект [`UnicodeEncodeError`](https://python-all.ru/3.5/library/exceptions.html#UnicodeEncodeError) с атрибутами *encoding*, *object*, *length*, *start*, *end* и *reason*. *encoding* и *reason* – это строки в кодировке UTF-8.349350#### `PyObject* PyUnicodeTranslateError_Create(const Py_UNICODE *object, Py_ssize_t length, Py_ssize_t start, Py_ssize_t end, const char *reason)`351352Создает объект [`UnicodeTranslateError`](https://python-all.ru/3.5/library/exceptions.html#UnicodeTranslateError) с атрибутами *object*, *length*, *start*, *end* и *reason*. *reason* – это строка в кодировке UTF-8.353354#### `PyObject* PyUnicodeDecodeError_GetEncoding(PyObject *exc)`355356#### `PyObject* PyUnicodeEncodeError_GetEncoding(PyObject *exc)`357358Возвращает атрибут *encoding* указанного объекта исключения.359360#### `PyObject* PyUnicodeDecodeError_GetObject(PyObject *exc)`361362#### `PyObject* PyUnicodeEncodeError_GetObject(PyObject *exc)`363364#### `PyObject* PyUnicodeTranslateError_GetObject(PyObject *exc)`365366Возвращает атрибут *object* указанного объекта исключения.367368#### `int PyUnicodeDecodeError_GetStart(PyObject *exc, Py_ssize_t *start)`369370#### `int PyUnicodeEncodeError_GetStart(PyObject *exc, Py_ssize_t *start)`371372#### `int PyUnicodeTranslateError_GetStart(PyObject *exc, Py_ssize_t *start)`373374Получает атрибут *start* заданного объекта исключения и помещает его в *\*start*. *start* не должен быть *NULL*. Возвращает `0` в случае успеха, `-1` при неудаче.375376#### `int PyUnicodeDecodeError_SetStart(PyObject *exc, Py_ssize_t start)`377378#### `int PyUnicodeEncodeError_SetStart(PyObject *exc, Py_ssize_t start)`379380#### `int PyUnicodeTranslateError_SetStart(PyObject *exc, Py_ssize_t start)`381382Устанавливает атрибут *start* указанного объекта исключения в значение *start*. Возвращает `0` при успехе, `-1` при ошибке.383384#### `int PyUnicodeDecodeError_GetEnd(PyObject *exc, Py_ssize_t *end)`385386#### `int PyUnicodeEncodeError_GetEnd(PyObject *exc, Py_ssize_t *end)`387388#### `int PyUnicodeTranslateError_GetEnd(PyObject *exc, Py_ssize_t *end)`389390Получает атрибут *end* заданного объекта исключения и помещает его в *\*end*. *end* не должен быть *NULL*. Возвращает `0` в случае успеха, `-1` при неудаче.391392#### `int PyUnicodeDecodeError_SetEnd(PyObject *exc, Py_ssize_t end)`393394#### `int PyUnicodeEncodeError_SetEnd(PyObject *exc, Py_ssize_t end)`395396#### `int PyUnicodeTranslateError_SetEnd(PyObject *exc, Py_ssize_t end)`397398Устанавливает атрибут *end* указанного объекта исключения в *end*. Возвращает `0` в случае успеха, `-1` при ошибке.399400#### `PyObject* PyUnicodeDecodeError_GetReason(PyObject *exc)`401402#### `PyObject* PyUnicodeEncodeError_GetReason(PyObject *exc)`403404#### `PyObject* PyUnicodeTranslateError_GetReason(PyObject *exc)`405406Возвращает атрибут *reason* указанного объекта исключения.407408#### `int PyUnicodeDecodeError_SetReason(PyObject *exc, const char *reason)`409410#### `int PyUnicodeEncodeError_SetReason(PyObject *exc, const char *reason)`411412#### `int PyUnicodeTranslateError_SetReason(PyObject *exc, const char *reason)`413414Устанавливает атрибут *reason* указанного объекта исключения в значение *reason*. Возвращает `0` в случае успеха, `-1` в случае ошибки.415416## Управление рекурсией417418Эти две функции предоставляют способ выполнения безопасных рекурсивных вызовов на уровне C как в ядре, так и в модулях расширения. Они необходимы, если рекурсивный код не обязательно вызывает код Python (который автоматически отслеживает свою глубину рекурсии).419420#### `int Py_EnterRecursiveCall(const char *where)`421422Отмечает точку, в которой будет выполнен рекурсивный вызов на уровне C.423424Если определено `USE_STACKCHECK`, эта функция проверяет, не переполнился ли стек ОС с помощью [`PyOS_CheckStack()`](https://python-all.ru/3.5/c-api/sys.html#c.PyOS_CheckStack). Если это так, она устанавливает [`MemoryError`](https://python-all.ru/3.5/library/exceptions.html#MemoryError) и возвращает ненулевое значение.425426Затем функция проверяет, достигнут ли предел рекурсии. Если это так, устанавливается [`RecursionError`](https://python-all.ru/3.5/library/exceptions.html#RecursionError) и возвращается ненулевое значение. В противном случае возвращается ноль.427428*where* должна быть строкой, например `" in instance check"`, которая будет добавлена к [`RecursionError`](https://python-all.ru/3.5/library/exceptions.html#RecursionError) сообщению, вызванному ограничением глубины рекурсии.429430#### `void Py_LeaveRecursiveCall()`431432Завершает [`Py_EnterRecursiveCall()`](https://python-all.ru/3.5/c-api/exceptions.html#c.Py_EnterRecursiveCall). Должна вызываться один раз для каждого *успешного* вызова [`Py_EnterRecursiveCall()`](https://python-all.ru/3.5/c-api/exceptions.html#c.Py_EnterRecursiveCall).433434Для правильной реализации [`tp_repr`](https://python-all.ru/3.5/c-api/typeobj.html#c.PyTypeObject.tp_repr) для контейнерных типов требуется специальная обработка рекурсии. В дополнение к защите стека, [`tp_repr`](https://python-all.ru/3.5/c-api/typeobj.html#c.PyTypeObject.tp_repr) также необходимо отслеживать объекты для предотвращения циклов. Следующие две функции облегчают эту функциональность. По сути, это эквивалент [`reprlib.recursive_repr()`](https://python-all.ru/3.5/library/reprlib.html#reprlib.recursive_repr) на C.435436#### `int Py_ReprEnter(PyObject *object)`437438Вызывается в начале реализации [`tp_repr`](https://python-all.ru/3.5/c-api/typeobj.html#c.PyTypeObject.tp_repr) для обнаружения циклов.439440Если объект уже был обработан, функция возвращает положительное целое число. В этом случае реализация [`tp_repr`](https://python-all.ru/3.5/c-api/typeobj.html#c.PyTypeObject.tp_repr) должна вернуть строковый объект, указывающий на цикл. Например, объекты [`dict`](https://python-all.ru/3.5/library/stdtypes.html#dict) возвращают `{...}`, а объекты [`list`](https://python-all.ru/3.5/library/stdtypes.html#list) возвращают `[...]`.441442Функция возвращает отрицательное целое число, если достигнут предел рекурсии. В этом случае реализация [`tp_repr`](https://python-all.ru/3.5/c-api/typeobj.html#c.PyTypeObject.tp_repr) обычно должна возвращать `NULL`.443444В противном случае функция возвращает ноль, и реализация [`tp_repr`](https://python-all.ru/3.5/c-api/typeobj.html#c.PyTypeObject.tp_repr) может продолжить работу в обычном режиме.445446#### `void Py_ReprLeave(PyObject *object)`447448Завершает [`Py_ReprEnter()`](https://python-all.ru/3.5/c-api/exceptions.html#c.Py_ReprEnter). Должна вызываться один раз для каждого вызова [`Py_ReprEnter()`](https://python-all.ru/3.5/c-api/exceptions.html#c.Py_ReprEnter), которая возвращает ноль.449450## Стандартные исключения451452Все стандартные исключения Python доступны в виде глобальных переменных, имена которых образуются из `PyExc_` с добавлением имени исключения Python. Они имеют тип [`PyObject*`](https://python-all.ru/3.5/c-api/structures.html#c.PyObject); все они являются объектами-классами. Для полноты картины здесь приведены все переменные:453454| Имя в C | Имя в Python | Примечания |455| --- | --- | --- |456| `PyExc_BaseException` | [`BaseException`](https://python-all.ru/3.5/library/exceptions.html#BaseException) | (1) |457| `PyExc_Exception` | [`Exception`](https://python-all.ru/3.5/library/exceptions.html#Exception) | (1) |458| `PyExc_ArithmeticError` | [`ArithmeticError`](https://python-all.ru/3.5/library/exceptions.html#ArithmeticError) | (1) |459| `PyExc_AssertionError` | [`AssertionError`](https://python-all.ru/3.5/library/exceptions.html#AssertionError) | |460| `PyExc_AttributeError` | [`AttributeError`](https://python-all.ru/3.5/library/exceptions.html#AttributeError) | |461| `PyExc_BlockingIOError` | [`BlockingIOError`](https://python-all.ru/3.5/library/exceptions.html#BlockingIOError) | |462| `PyExc_BrokenPipeError` | [`BrokenPipeError`](https://python-all.ru/3.5/library/exceptions.html#BrokenPipeError) | |463| `PyExc_BufferError` | [`BufferError`](https://python-all.ru/3.5/library/exceptions.html#BufferError) | |464| `PyExc_ChildProcessError` | [`ChildProcessError`](https://python-all.ru/3.5/library/exceptions.html#ChildProcessError) | |465| `PyExc_ConnectionAbortedError` | [`ConnectionAbortedError`](https://python-all.ru/3.5/library/exceptions.html#ConnectionAbortedError) | |466| `PyExc_ConnectionError` | [`ConnectionError`](https://python-all.ru/3.5/library/exceptions.html#ConnectionError) | |467| `PyExc_ConnectionRefusedError` | [`ConnectionRefusedError`](https://python-all.ru/3.5/library/exceptions.html#ConnectionRefusedError) | |468| `PyExc_ConnectionResetError` | [`ConnectionResetError`](https://python-all.ru/3.5/library/exceptions.html#ConnectionResetError) | |469| `PyExc_EOFError` | [`EOFError`](https://python-all.ru/3.5/library/exceptions.html#EOFError) | |470| `PyExc_FileExistsError` | [`FileExistsError`](https://python-all.ru/3.5/library/exceptions.html#FileExistsError) | |471| `PyExc_FileNotFoundError` | [`FileNotFoundError`](https://python-all.ru/3.5/library/exceptions.html#FileNotFoundError) | |472| `PyExc_FloatingPointError` | [`FloatingPointError`](https://python-all.ru/3.5/library/exceptions.html#FloatingPointError) | |473| `PyExc_GeneratorExit` | [`GeneratorExit`](https://python-all.ru/3.5/library/exceptions.html#GeneratorExit) | |474| `PyExc_ImportError` | [`ImportError`](https://python-all.ru/3.5/library/exceptions.html#ImportError) | |475| `PyExc_IndentationError` | [`IndentationError`](https://python-all.ru/3.5/library/exceptions.html#IndentationError) | |476| `PyExc_IndexError` | [`IndexError`](https://python-all.ru/3.5/library/exceptions.html#IndexError) | |477| `PyExc_InterruptedError` | [`InterruptedError`](https://python-all.ru/3.5/library/exceptions.html#InterruptedError) | |478| `PyExc_IsADirectoryError` | [`IsADirectoryError`](https://python-all.ru/3.5/library/exceptions.html#IsADirectoryError) | |479| `PyExc_KeyError` | [`KeyError`](https://python-all.ru/3.5/library/exceptions.html#KeyError) | |480| `PyExc_KeyboardInterrupt` | [`KeyboardInterrupt`](https://python-all.ru/3.5/library/exceptions.html#KeyboardInterrupt) | |481| `PyExc_LookupError` | [`LookupError`](https://python-all.ru/3.5/library/exceptions.html#LookupError) | (1) |482| `PyExc_MemoryError` | [`MemoryError`](https://python-all.ru/3.5/library/exceptions.html#MemoryError) | |483| `PyExc_NameError` | [`NameError`](https://python-all.ru/3.5/library/exceptions.html#NameError) | |484| `PyExc_NotADirectoryError` | [`NotADirectoryError`](https://python-all.ru/3.5/library/exceptions.html#NotADirectoryError) | |485| `PyExc_NotImplementedError` | [`NotImplementedError`](https://python-all.ru/3.5/library/exceptions.html#NotImplementedError) | |486| `PyExc_OSError` | [`OSError`](https://python-all.ru/3.5/library/exceptions.html#OSError) | (1) |487| `PyExc_OverflowError` | [`OverflowError`](https://python-all.ru/3.5/library/exceptions.html#OverflowError) | |488| `PyExc_PermissionError` | [`PermissionError`](https://python-all.ru/3.5/library/exceptions.html#PermissionError) | |489| `PyExc_ProcessLookupError` | [`ProcessLookupError`](https://python-all.ru/3.5/library/exceptions.html#ProcessLookupError) | |490| `PyExc_RecursionError` | [`RecursionError`](https://python-all.ru/3.5/library/exceptions.html#RecursionError) | |491| `PyExc_ReferenceError` | [`ReferenceError`](https://python-all.ru/3.5/library/exceptions.html#ReferenceError) | (2) |492| `PyExc_RuntimeError` | [`RuntimeError`](https://python-all.ru/3.5/library/exceptions.html#RuntimeError) | |493| `PyExc_StopAsyncIteration` | [`StopAsyncIteration`](https://python-all.ru/3.5/library/exceptions.html#StopAsyncIteration) | |494| `PyExc_StopIteration` | [`StopIteration`](https://python-all.ru/3.5/library/exceptions.html#StopIteration) | |495| `PyExc_SyntaxError` | [`SyntaxError`](https://python-all.ru/3.5/library/exceptions.html#SyntaxError) | |496| `PyExc_SystemError` | [`SystemError`](https://python-all.ru/3.5/library/exceptions.html#SystemError) | |497| `PyExc_SystemExit` | [`SystemExit`](https://python-all.ru/3.5/library/exceptions.html#SystemExit) | |498| `PyExc_TabError` | [`TabError`](https://python-all.ru/3.5/library/exceptions.html#TabError) | |499| `PyExc_TimeoutError` | [`TimeoutError`](https://python-all.ru/3.5/library/exceptions.html#TimeoutError) | |500| `PyExc_TypeError` | [`TypeError`](https://python-all.ru/3.5/library/exceptions.html#TypeError) | |501| `PyExc_UnboundLocalError` | [`UnboundLocalError`](https://python-all.ru/3.5/library/exceptions.html#UnboundLocalError) | |502| `PyExc_UnicodeDecodeError` | [`UnicodeDecodeError`](https://python-all.ru/3.5/library/exceptions.html#UnicodeDecodeError) | |503| `PyExc_UnicodeEncodeError` | [`UnicodeEncodeError`](https://python-all.ru/3.5/library/exceptions.html#UnicodeEncodeError) | |504| `PyExc_UnicodeError` | [`UnicodeError`](https://python-all.ru/3.5/library/exceptions.html#UnicodeError) | |505| `PyExc_UnicodeTranslateError` | [`UnicodeTranslateError`](https://python-all.ru/3.5/library/exceptions.html#UnicodeTranslateError) | |506| `PyExc_ValueError` | [`ValueError`](https://python-all.ru/3.5/library/exceptions.html#ValueError) | |507| `PyExc_ZeroDivisionError` | [`ZeroDivisionError`](https://python-all.ru/3.5/library/exceptions.html#ZeroDivisionError) | |508509Новое в версии 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.5/c-api/exceptions.html).510511Новое в версии 3.5: `PyExc_StopAsyncIteration` и `PyExc_RecursionError`.512513Это псевдонимы для совместимости с `PyExc_OSError`:514515| Имя в C | Примечания |516| --- | --- |517| `PyExc_EnvironmentError` | |518| `PyExc_IOError` | |519| `PyExc_WindowsError` | (3) |520521Изменено в версии 3.3: Раньше эти псевдонимы были отдельными типами исключений.522523Примечания:5245251. Это базовый класс для других стандартных исключений.5262. То же самое, что и [`weakref.ReferenceError`](https://python-all.ru/3.5/library/weakref.html#weakref.ReferenceError).5273. Определено только в Windows; защитите код, использующий это, проверкой, что определён макрос препроцессора `MS_WINDOWS`.528529## Стандартные категории предупреждений530531Все стандартные категории предупреждений Python доступны в виде глобальных переменных, имена которых образуются из `PyExc_` с добавлением имени исключения Python. Они имеют тип [`PyObject*`](https://python-all.ru/3.5/c-api/structures.html#c.PyObject); все они являются объектами-классами. Для полноты картины здесь приведены все переменные:532533| Имя в C | Имя в Python | Примечания |534| --- | --- | --- |535| `PyExc_Warning` | [`Warning`](https://python-all.ru/3.5/library/exceptions.html#Warning) | (1) |536| `PyExc_BytesWarning` | [`BytesWarning`](https://python-all.ru/3.5/library/exceptions.html#BytesWarning) | |537| `PyExc_DeprecationWarning` | [`DeprecationWarning`](https://python-all.ru/3.5/library/exceptions.html#DeprecationWarning) | |538| `PyExc_FutureWarning` | [`FutureWarning`](https://python-all.ru/3.5/library/exceptions.html#FutureWarning) | |539| `PyExc_ImportWarning` | [`ImportWarning`](https://python-all.ru/3.5/library/exceptions.html#ImportWarning) | |540| `PyExc_PendingDeprecationWarning` | [`PendingDeprecationWarning`](https://python-all.ru/3.5/library/exceptions.html#PendingDeprecationWarning) | |541| `PyExc_ResourceWarning` | [`ResourceWarning`](https://python-all.ru/3.5/library/exceptions.html#ResourceWarning) | |542| `PyExc_RuntimeWarning` | [`RuntimeWarning`](https://python-all.ru/3.5/library/exceptions.html#RuntimeWarning) | |543| `PyExc_SyntaxWarning` | [`SyntaxWarning`](https://python-all.ru/3.5/library/exceptions.html#SyntaxWarning) | |544| `PyExc_UnicodeWarning` | [`UnicodeWarning`](https://python-all.ru/3.5/library/exceptions.html#UnicodeWarning) | |545| `PyExc_UserWarning` | [`UserWarning`](https://python-all.ru/3.5/library/exceptions.html#UserWarning) | |546547Новое в версии 3.2: `PyExc_ResourceWarning`.548549Примечания:5505511. Это базовый класс для других стандартных категорий предупреждений.552