异常处理

本章描述的函数可让你处理和引发 Python 异常。理解 Python 异常处理的一些基本知识很重要。它有点像 POSIX 的 errno 变量:有一个全局指示器(每个线程)表示发生的最后一个错误。大多数 C API 函数在成功时不会清除它,但会在失败时设置它以指示错误原因。大多数 C API 函数还会返回一个错误指示器,如果它们应该返回一个指针,通常是 NULL,如果它们返回一个整数,则是 -1(例外情况:PyArg_* 函数成功时返回 1,失败时返回 0)。

具体来说,错误指示器由三个对象指针组成:异常的类型、异常的值和回溯对象。如果未设置,这些指针中的任何一个都可以是 NULL(尽管某些组合是被禁止的,例如,如果异常类型为 NULL,则不能有非 NULL 回溯)。

当一个函数由于它调用的某个函数失败而必须失败时,它通常不设置错误指示器;它调用的函数已经设置了它。它负责处理错误并清除异常,或者在清理它所持有的任何资源(例如对象引用或内存分配)后返回;如果它没有准备好处理错误,则 *不应* 正常继续。如果由于错误而返回,则必须向调用者指示已设置错误。如果错误未处理或未仔细传播,则对 Python/C API 的其他调用可能无法按预期工作,并可能以神秘的方式失败。

注意

错误指示器 *不是* sys.exc_info() 的结果。前者对应于尚未捕获(因此仍在传播)的异常,而后者在捕获异常后(因此已停止传播)返回异常。

打印和清除

void PyErr_Clear()
稳定 ABI 的一部分。

清除错误指示器。如果未设置错误指示器,则没有效果。

void PyErr_PrintEx(int set_sys_last_vars)
稳定 ABI 的一部分。

将标准回溯打印到 sys.stderr 并清除错误指示器。 *除非* 错误是 SystemExit,在这种情况下,不打印回溯,并且 Python 进程将以 SystemExit 实例指定的错误代码退出。

**仅当** 设置了错误指示器时才调用此函数。否则会导致致命错误!

如果 *set_sys_last_vars* 非零,则变量 sys.last_exc 将设置为打印的异常。为了向后兼容,不推荐使用的变量 sys.last_typesys.last_valuesys.last_traceback 也分别设置为此异常的类型、值和回溯。

在 3.12 版本中更改: 添加了 sys.last_exc 的设置。

void PyErr_Print()
稳定 ABI 的一部分。

PyErr_PrintEx(1) 的别名。

void PyErr_WriteUnraisable(PyObject *obj)
稳定 ABI 的一部分。

使用当前异常和 *obj* 参数调用 sys.unraisablehook()

当设置了异常但解释器实际上无法引发该异常时,此实用函数会向 sys.stderr 打印警告消息。例如,当 __del__() 方法中发生异常时,会使用它。

调用该函数时使用一个参数 *obj*,该参数标识发生无法引发的异常的上下文。如果可能,*obj* 的 repr 将打印在警告消息中。如果 *obj* 为 NULL,则仅打印回溯。

调用此函数时必须设置异常。

在 3.4 版本中更改: 打印回溯。如果 *obj* 为 NULL,则仅打印回溯。

在 3.8 版本中更改: 使用 sys.unraisablehook()

void PyErr_FormatUnraisable(const char *format, ...)

类似于 PyErr_WriteUnraisable(),但是 *format* 和后续参数有助于格式化警告消息;它们与 PyUnicode_FromFormat() 中的含义和值相同。PyErr_WriteUnraisable(obj) 大致等效于 PyErr_FormatUnraisable("Exception ignored in: %R", obj)。如果 *format* 为 NULL,则仅打印回溯。

在 3.13 版本中添加。

void PyErr_DisplayException(PyObject *exc)
自 3.12 版本起,成为 稳定 ABI 的一部分。

exc 的标准回溯显示打印到 sys.stderr,包括链式异常和注释。

在 3.12 版本中添加。

引发异常

这些函数可帮助你设置当前线程的错误指示器。为方便起见,这些函数中的某些函数将始终返回一个 NULL 指针,以便在 return 语句中使用。

void PyErr_SetString(PyObject *type, const char *message)
稳定 ABI 的一部分。

这是设置错误指示器的最常用方法。第一个参数指定异常类型;它通常是标准异常之一,例如 PyExc_RuntimeError。你无需为其创建新的 强引用(例如,使用 Py_INCREF())。第二个参数是错误消息;它从 'utf-8' 解码。

void PyErr_SetObject(PyObject *type, PyObject *value)
稳定 ABI 的一部分。

此函数与 PyErr_SetString() 类似,但允许你为异常的“值”指定任意 Python 对象。

PyObject *PyErr_Format(PyObject *exception, const char *format, ...)
返回值:始终为 NULL。属于 稳定 ABI 的一部分。

此函数设置错误指示器并返回 NULLexception 应该是一个 Python 异常类。format 和后续参数有助于格式化错误消息;它们具有与 PyUnicode_FromFormat() 中相同的含义和值。format 是一个 ASCII 编码的字符串。

PyObject *PyErr_FormatV(PyObject *exception, const char *format, va_list vargs)
返回值:始终为 NULL。 自 3.5 版本起,属于 稳定 ABI 的一部分。

PyErr_Format() 相同,但接受一个 va_list 参数而不是可变数量的参数。

在 3.5 版本中添加。

void PyErr_SetNone(PyObject *type)
稳定 ABI 的一部分。

这是 PyErr_SetObject(type, Py_None) 的简写。

int PyErr_BadArgument()
稳定 ABI 的一部分。

这是 PyErr_SetString(PyExc_TypeError, message) 的简写,其中 message 指示使用非法参数调用了内置操作。它主要用于内部使用。

PyObject *PyErr_NoMemory()
返回值:始终为 NULL。属于 稳定 ABI 的一部分。

这是 PyErr_SetNone(PyExc_MemoryError) 的简写;它返回 NULL,因此对象分配函数可以在内存耗尽时写入 return PyErr_NoMemory();

PyObject *PyErr_SetFromErrno(PyObject *type)
返回值:始终为 NULL。属于 稳定 ABI 的一部分。

当 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)
返回值:始终为 NULL。属于 稳定 ABI 的一部分。

PyErr_SetFromErrno() 类似,但额外行为是,如果 filenameObject 不是 NULL,则将其作为第三个参数传递给 type 的构造函数。对于 OSError 异常,这用于定义异常实例的 filename 属性。

PyObject *PyErr_SetFromErrnoWithFilenameObjects(PyObject *type, PyObject *filenameObject, PyObject *filenameObject2)
返回值:始终为 NULL。 自 3.7 版本起,属于 稳定 ABI 的一部分。

PyErr_SetFromErrnoWithFilenameObject() 类似,但采用第二个文件名对象,用于在采用两个文件名的函数失败时引发错误。

在 3.4 版本中添加。

PyObject *PyErr_SetFromErrnoWithFilename(PyObject *type, const char *filename)
返回值:始终为 NULL。属于 稳定 ABI 的一部分。

PyErr_SetFromErrnoWithFilenameObject() 类似,但文件名以 C 字符串的形式给出。filename 是从 文件系统编码和错误处理程序解码的。

PyObject *PyErr_SetFromWindowsErr(int ierr)
返回值:始终为 NULL。自 3.7 版本起,在 Windows 上属于 稳定 ABI 的一部分。

这是一个便捷函数,用于引发 OSError 异常。 如果使用 ierr0 调用,则会使用调用 GetLastError() 返回的错误代码。 它会调用 Win32 函数 FormatMessage() 来检索由 ierrGetLastError() 给出的错误代码的 Windows 描述,然后它会构造一个 OSError 对象,该对象的 winerror 属性设置为错误代码,strerror 属性设置为相应的错误消息(从 FormatMessage() 获取),然后调用 PyErr_SetObject(PyExc_OSError, object)。 此函数始终返回 NULL

可用性:Windows。

PyObject *PyErr_SetExcFromWindowsErr(PyObject *type, int ierr)
返回值:始终为 NULL。自 3.7 版本起,在 Windows 上属于 稳定 ABI 的一部分。

类似于 PyErr_SetFromWindowsErr(),但多了一个参数,用于指定要引发的异常类型。

可用性:Windows。

PyObject *PyErr_SetFromWindowsErrWithFilename(int ierr, const char *filename)
返回值:始终为 NULL。自 3.7 版本起,在 Windows 上属于 稳定 ABI 的一部分。

类似于 PyErr_SetFromWindowsErr(),但增加了额外的行为:如果 filename 不是 NULL,则会从文件系统编码 ( os.fsdecode() ) 中解码它,并将其作为第三个参数传递给 OSError 的构造函数,用于定义异常实例的 filename 属性。

可用性:Windows。

PyObject *PyErr_SetExcFromWindowsErrWithFilenameObject(PyObject *type, int ierr, PyObject *filename)
返回值:始终为 NULL。自 3.7 版本起,在 Windows 上属于 稳定 ABI 的一部分。

类似于 PyErr_SetExcFromWindowsErr(),但增加了额外的行为:如果 filename 不是 NULL,则会将其作为第三个参数传递给 OSError 的构造函数,用于定义异常实例的 filename 属性。

可用性:Windows。

PyObject *PyErr_SetExcFromWindowsErrWithFilenameObjects(PyObject *type, int ierr, PyObject *filename, PyObject *filename2)
返回值:始终为 NULL。自 3.7 版本起,在 Windows 上属于 稳定 ABI 的一部分。

类似于 PyErr_SetExcFromWindowsErrWithFilenameObject(),但接受第二个文件名对象。

可用性:Windows。

在 3.4 版本中添加。

PyObject *PyErr_SetExcFromWindowsErrWithFilename(PyObject *type, int ierr, const char *filename)
返回值:始终为 NULL。自 3.7 版本起,在 Windows 上属于 稳定 ABI 的一部分。

类似于 PyErr_SetFromWindowsErrWithFilename(),但多了一个参数,用于指定要引发的异常类型。

可用性:Windows。

PyObject *PyErr_SetImportError(PyObject *msg, PyObject *name, PyObject *path)
返回值:始终为 NULL。 自 3.7 版本起,属于 稳定 ABI 的一部分。

这是一个便捷函数,用于引发 ImportError 异常。 msg 将被设置为异常的消息字符串。 namepath 都可以为 NULL,它们将被设置为 ImportError 的相应 namepath 属性。

3.3 版本中新增。

PyObject *PyErr_SetImportErrorSubclass(PyObject *exception, PyObject *msg, PyObject *name, PyObject *path)
返回值:始终为 NULL。自 3.6 版本起成为 稳定 ABI 的一部分。

PyErr_SetImportError() 非常相似,但此函数允许指定要引发的 ImportError 的子类。

3.6 版本中新增。

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)
自 3.7 版本起,属于 稳定 ABI 的一部分。

类似于 PyErr_SyntaxLocationObject(),但 *filename* 是从文件系统编码和错误处理程序解码的字节字符串。

在 3.2 版本中添加。

void PyErr_SyntaxLocation(const char *filename, int lineno)
稳定 ABI 的一部分。

类似于 PyErr_SyntaxLocationEx(),但省略了 *col_offset* 参数。

void PyErr_BadInternalCall()
稳定 ABI 的一部分。

这是 PyErr_SetString(PyExc_SystemError, message) 的简写,其中 *message* 指示内部操作(例如,Python/C API 函数)被使用非法参数调用。它主要用于内部使用。

发出警告

使用这些函数从 C 代码中发出警告。它们镜像了 Python warnings 模块导出的类似函数。它们通常将警告消息打印到 *sys.stderr*;但是,用户也可能已指定将警告转换为错误,在这种情况下,它们将引发异常。函数也可能由于警告机制的问题而引发异常。如果没有引发异常,则返回值为 0;如果引发异常,则返回值为 -1。(无法确定是否实际打印了警告消息,也无法确定异常的原因;这是故意的。)如果引发异常,则调用者应执行其正常的异常处理(例如,Py_DECREF() 拥有的引用并返回错误值)。

int PyErr_WarnEx(PyObject *category, const char *message, Py_ssize_t stack_level)
稳定 ABI 的一部分。

发出警告消息。*category* 参数是警告类别(请参见下文)或 NULL;*message* 参数是一个 UTF-8 编码的字符串。*stack_level* 是一个正数,表示堆栈帧的数量;警告将从该堆栈帧中当前执行的代码行发出。*stack_level* 为 1 是调用 PyErr_WarnEx() 的函数,2 是该函数上面的函数,依此类推。

警告类别必须是 PyExc_Warning 的子类;PyExc_WarningPyExc_Exception 的子类;默认警告类别是 PyExc_RuntimeWarning。标准的 Python 警告类别作为全局变量可用,其名称在 标准警告类别 中枚举。

有关警告控制的信息,请参阅 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)
稳定 ABI 的一部分。

类似于 PyErr_WarnExplicitObject(),除了 *message* 和 *module* 是 UTF-8 编码的字符串,而 *filename* 是从文件系统编码和错误处理程序解码的。

int PyErr_WarnFormat(PyObject *category, Py_ssize_t stack_level, const char *format, ...)
稳定 ABI 的一部分。

PyErr_WarnEx() 类似的函数,但使用 PyUnicode_FromFormat() 来格式化警告消息。*format* 是一个 ASCII 编码的字符串。

在 3.2 版本中添加。

int PyErr_ResourceWarning(PyObject *source, Py_ssize_t stack_level, const char *format, ...)
自 3.6 版本起,属于 稳定 ABI 的一部分。

PyErr_WarnFormat() 类似的函数,但 *category* 为 ResourceWarning,并将 *source* 传递给 warnings.WarningMessage

3.6 版本中新增。

查询错误指示器

PyObject *PyErr_Occurred()
返回值:借用引用。 稳定 ABI 的一部分。

测试是否设置了错误指示器。如果已设置,则返回异常类型(上次调用 PyErr_Set* 函数之一或 PyErr_Restore() 的第一个参数)。如果未设置,则返回 NULL。您不拥有返回值的引用,因此您不需要对其进行 Py_DECREF()

调用者必须持有 GIL。

注意

不要将返回值与特定的异常进行比较;请改用 PyErr_ExceptionMatches(),如下所示。(比较很容易失败,因为在类异常的情况下,该异常可能是实例而不是类,或者它可能是预期异常的子类。)

int PyErr_ExceptionMatches(PyObject *exc)
稳定 ABI 的一部分。

等同于 PyErr_GivenExceptionMatches(PyErr_Occurred(), exc)。 仅当实际设置了异常时才应调用此方法;如果未引发异常,则会发生内存访问冲突。

int PyErr_GivenExceptionMatches(PyObject *given, PyObject *exc)
稳定 ABI 的一部分。

如果 given 异常与 exc 中的异常类型匹配,则返回 true。如果 exc 是一个类对象,则当 given 是子类的实例时,此方法也返回 true。如果 exc 是一个元组,则会在元组(以及子元组中递归地)中搜索所有异常类型以查找匹配项。

PyObject *PyErr_GetRaisedException(void)
返回值:新引用。 自 3.12 版本起,成为 稳定 ABI 的一部分。

返回当前正在引发的异常,同时清除错误指示器。如果未设置错误指示器,则返回 NULL

此函数由需要捕获异常的代码或需要临时保存和恢复错误指示器的代码使用。

例如

{
   PyObject *exc = PyErr_GetRaisedException();

   /* ... code that might produce other errors ... */

   PyErr_SetRaisedException(exc);
}

另请参阅

PyErr_GetHandledException(),以保存当前正在处理的异常。

在 3.12 版本中添加。

void PyErr_SetRaisedException(PyObject *exc)
自 3.12 版本起,成为 稳定 ABI 的一部分。

exc 设置为当前正在引发的异常,如果设置了异常,则清除现有异常。

警告

此调用会窃取对 exc 的引用,exc 必须是有效的异常。

在 3.12 版本中添加。

void PyErr_Fetch(PyObject **ptype, PyObject **pvalue, PyObject **ptraceback)
稳定 ABI 的一部分。

自 3.12 版本起已弃用: 请改用 PyErr_GetRaisedException()

将错误指示器检索到传递了地址的三个变量中。如果未设置错误指示器,则将所有三个变量设置为 NULL。如果已设置,则会清除它,并且您拥有检索到的每个对象的引用。即使类型对象不为 NULL,值和回溯对象也可能为 NULL

注意

此函数通常仅由需要捕获异常或临时保存和恢复错误指示器的遗留代码使用。

例如

{
   PyObject *type, *value, *traceback;
   PyErr_Fetch(&type, &value, &traceback);

   /* ... code that might produce other errors ... */

   PyErr_Restore(type, value, traceback);
}
void PyErr_Restore(PyObject *type, PyObject *value, PyObject *traceback)
稳定 ABI 的一部分。

自 3.12 版本起已弃用: 请改用 PyErr_SetRaisedException()

从三个对象 typevaluetraceback 设置错误指示器,如果设置了异常,则清除现有异常。如果对象为 NULL,则清除错误指示器。请勿传递 NULL 类型和非 NULL 值或回溯。异常类型应为类。请勿传递无效的异常类型或值。(违反这些规则会在以后导致微妙的问题。)此调用会删除对每个对象的引用:您必须在调用之前拥有对每个对象的引用,并且在调用之后您不再拥有这些引用。(如果您不明白这一点,请不要使用此函数。我警告过您了。)

注意

此函数通常仅由需要临时保存和恢复错误指示器的遗留代码使用。使用 PyErr_Fetch() 保存当前错误指示器。

void PyErr_NormalizeException(PyObject **exc, PyObject **val, PyObject **tb)
稳定 ABI 的一部分。

自 3.12 版本起已弃用: 请改用 PyErr_GetRaisedException(),以避免任何可能的反规范化。

在某些情况下,下面 PyErr_Fetch() 返回的值可能是“未规范化的”,这意味着 *exc 是一个类对象,但 *val 不是同一个类的实例。在这种情况下,可以使用此函数实例化该类。如果值已经规范化,则不会发生任何事情。延迟规范化的实现是为了提高性能。

注意

此函数不会隐式设置异常值上的 __traceback__ 属性。如果需要适当地设置回溯,则需要以下附加代码段

if (tb != NULL) {
  PyException_SetTraceback(val, tb);
}
PyObject *PyErr_GetHandledException(void)
自 3.11 版本起,属于 稳定 ABI 的一部分。

检索活动的异常实例,如同 sys.exception() 返回的结果。 这指的是已经被捕获的异常,而不是刚刚引发的异常。 返回一个指向该异常的新引用,或者返回 NULL。 不会修改解释器的异常状态。

注意

此函数通常不被想要处理异常的代码使用。相反,当代码需要临时保存和恢复异常状态时可以使用它。 使用 PyErr_SetHandledException() 来恢复或清除异常状态。

在 3.11 版本中添加。

void PyErr_SetHandledException(PyObject *exc)
自 3.11 版本起,属于 稳定 ABI 的一部分。

设置活动异常,如同 sys.exception() 所知。 这指的是已经被捕获的异常,而不是刚刚引发的异常。 要清除异常状态,请传递 NULL

注意

此函数通常不被想要处理异常的代码使用。相反,当代码需要临时保存和恢复异常状态时可以使用它。 使用 PyErr_GetHandledException() 来获取异常状态。

在 3.11 版本中添加。

void PyErr_GetExcInfo(PyObject **ptype, PyObject **pvalue, PyObject **ptraceback)
自 3.7 版本起,属于 稳定 ABI 的一部分。

检索异常信息的旧式表示,如同 sys.exc_info() 所知。 这指的是已经被捕获的异常,而不是刚刚引发的异常。 返回指向这三个对象的新引用,其中任何一个都可能为 NULL。 不会修改异常信息状态。 保留此函数是为了向后兼容。 建议使用 PyErr_GetHandledException()

注意

此函数通常不被想要处理异常的代码使用。相反,当代码需要临时保存和恢复异常状态时可以使用它。 使用 PyErr_SetExcInfo() 来恢复或清除异常状态。

3.3 版本中新增。

void PyErr_SetExcInfo(PyObject *type, PyObject *value, PyObject *traceback)
自 3.7 版本起,属于 稳定 ABI 的一部分。

设置异常信息,如同 sys.exc_info() 所知。 这指的是已经被捕获的异常,而不是刚刚引发的异常。 此函数会盗用参数的引用。 要清除异常状态,请为所有三个参数传递 NULL。 保留此函数是为了向后兼容。 建议使用 PyErr_SetHandledException()

注意

此函数通常不被想要处理异常的代码使用。相反,当代码需要临时保存和恢复异常状态时可以使用它。 使用 PyErr_GetExcInfo() 来读取异常状态。

3.3 版本中新增。

在 3.11 版本中变更: typetraceback 参数不再使用,可以为 NULL。 解释器现在从异常实例(value 参数)派生它们。 该函数仍然盗用所有三个参数的引用。

信号处理

int PyErr_CheckSignals()
稳定 ABI 的一部分。

此函数与 Python 的信号处理进行交互。

如果该函数是从主线程和主 Python 解释器下调用的,它会检查是否已向进程发送信号,如果是,则调用相应的信号处理程序。 如果支持 signal 模块,则可以调用用 Python 编写的信号处理程序。

该函数会尝试处理所有挂起的信号,然后返回 0。 但是,如果 Python 信号处理程序引发异常,则会设置错误指示器,并且该函数会立即返回 -1 (以便可能尚未处理其他挂起的信号:它们将在下次调用 PyErr_CheckSignals() 时被处理)。

如果该函数是从非主线程或非主 Python 解释器下调用的,则它什么也不做并返回 0

此函数可由长时间运行的 C 代码调用,该代码希望用户请求(例如通过按 Ctrl-C)可中断。

注意

SIGINT 的默认 Python 信号处理程序会引发 KeyboardInterrupt 异常。

void PyErr_SetInterrupt()
稳定 ABI 的一部分。

模拟 SIGINT 信号到达的效果。 这等效于 PyErr_SetInterruptEx(SIGINT)

注意

此函数是异步信号安全的。 它可以在没有 GIL 的情况下从 C 信号处理程序调用。

int PyErr_SetInterruptEx(int signum)
自 3.10 版本起,属于 稳定 ABI 的一部分。

模拟信号到达的效果。 下次调用 PyErr_CheckSignals() 时,将调用给定信号编号的 Python 信号处理程序。

此函数可由 C 代码调用,该代码设置自己的信号处理程序,并希望在请求中断时(例如,当用户按下 Ctrl-C 以中断操作时)按预期调用 Python 信号处理程序。

如果给定的信号未被 Python 处理(它被设置为 signal.SIG_DFLsignal.SIG_IGN),则它将被忽略。

如果 signum 超出允许的信号编号范围,则返回 -1。 否则,返回 0。 此函数永远不会更改错误指示器。

注意

此函数是异步信号安全的。 它可以在没有 GIL 的情况下从 C 信号处理程序调用。

在 3.10 版本中添加。

int PySignal_SetWakeupFd(int fd)

此实用函数指定一个文件描述符,每当收到信号时,信号编号都会以单个字节的形式写入其中。 fd 必须是非阻塞的。 它返回之前的此类文件描述符。

-1 将禁用此功能;这是初始状态。 这等效于 Python 中的 signal.set_wakeup_fd(),但没有任何错误检查。 fd 应为有效的文件描述符。 该函数应仅从主线程调用。

在 3.5 版本中变更: 在 Windows 上,该函数现在还支持套接字句柄。

异常类

PyObject *PyErr_NewException(const char *name, PyObject *base, PyObject *dict)
返回值:新的引用。属于 稳定 ABI 的一部分。

此实用函数创建并返回一个新的异常类。name 参数必须是新异常的名称,一个 C 字符串,格式为 模块名.类名basedict 参数通常为 NULL。这将创建一个从 Exception(在 C 中可访问为 PyExc_Exception)派生的类对象。

新类的 __module__ 属性设置为 name 参数的第一部分(直到最后一个点),类名设置为最后一部分(在最后一个点之后)。base 参数可用于指定备用的基类;它可以是一个类或一个类元组。dict 参数可用于指定类变量和方法的字典。

PyObject *PyErr_NewExceptionWithDoc(const char *name, const char *doc, PyObject *base, PyObject *dict)
返回值:新的引用。属于 稳定 ABI 的一部分。

PyErr_NewException() 相同,只是可以很容易地为新的异常类提供文档字符串:如果 doc 不是 NULL,它将用作异常类的文档字符串。

在 3.2 版本中添加。

异常对象

PyObject *PyException_GetTraceback(PyObject *ex)
返回值:新的引用。属于 稳定 ABI 的一部分。

返回与异常关联的回溯作为新的引用,如同通过 Python 的 __traceback__ 属性可访问的那样。如果没有关联的回溯,则返回 NULL

int PyException_SetTraceback(PyObject *ex, PyObject *tb)
稳定 ABI 的一部分。

将与异常关联的回溯设置为 tb。使用 Py_None 清除它。

PyObject *PyException_GetContext(PyObject *ex)
返回值:新的引用。属于 稳定 ABI 的一部分。

返回与异常关联的上下文(另一个异常实例,在其处理期间引发了 ex)作为新的引用,如同通过 Python 的 __context__ 属性可访问的那样。如果没有关联的上下文,则返回 NULL

void PyException_SetContext(PyObject *ex, PyObject *ctx)
稳定 ABI 的一部分。

将与异常关联的上下文设置为 ctx。使用 NULL 清除它。没有类型检查来确保 ctx 是异常实例。这会窃取对 ctx 的引用。

PyObject *PyException_GetCause(PyObject *ex)
返回值:新的引用。属于 稳定 ABI 的一部分。

返回与异常关联的原因(异常实例或 None,由 raise ... from ... 设置)作为新的引用,如同通过 Python 的 __cause__ 属性可访问的那样。

void PyException_SetCause(PyObject *ex, PyObject *cause)
稳定 ABI 的一部分。

将与异常关联的原因设置为 cause。使用 NULL 清除它。没有类型检查来确保 cause 是异常实例或 None。这会窃取对 cause 的引用。

此函数将 __suppress_context__ 属性隐式设置为 True

PyObject *PyException_GetArgs(PyObject *ex)
返回值:新引用。 自 3.12 版本起,成为 稳定 ABI 的一部分。

返回异常 exargs

void PyException_SetArgs(PyObject *ex, PyObject *args)
自 3.12 版本起,成为 稳定 ABI 的一部分。

将异常 exargs 设置为 args

PyObject *PyUnstable_Exc_PrepReraiseStar(PyObject *orig, PyObject *excs)
这是一个不稳定的 API。它可能会在次要版本中更改,恕不另行通知。

实现解释器对 except* 部分的实现。orig 是捕获的原始异常,excs 是需要引发的异常列表。此列表包含 orig 中未处理的部分(如果有),以及从 except* 子句引发的异常(因此它们具有与 orig 不同的回溯),以及重新引发的异常(与 orig 具有相同的回溯)。返回最终需要重新引发的 ExceptionGroup,如果没有什么需要重新引发,则返回 None

在 3.12 版本中添加。

Unicode 异常对象

以下函数用于从 C 创建和修改 Unicode 异常。

PyObject *PyUnicodeDecodeError_Create(const char *encoding, const char *object, Py_ssize_t length, Py_ssize_t start, Py_ssize_t end, const char *reason)
返回值:新的引用。属于 稳定 ABI 的一部分。

创建一个具有属性 encodingobjectlengthstartendreasonUnicodeDecodeError 对象。encodingreason 是 UTF-8 编码的字符串。

PyObject *PyUnicodeDecodeError_GetEncoding(PyObject *exc)
PyObject *PyUnicodeEncodeError_GetEncoding(PyObject *exc)
返回值:新的引用。属于 稳定 ABI 的一部分。

返回给定异常对象的 encoding 属性。

PyObject *PyUnicodeDecodeError_GetObject(PyObject *exc)
PyObject *PyUnicodeEncodeError_GetObject(PyObject *exc)
PyObject *PyUnicodeTranslateError_GetObject(PyObject *exc)
返回值:新的引用。属于 稳定 ABI 的一部分。

返回给定异常对象的 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)
稳定 ABI 的一部分。

获取给定异常对象的 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)
稳定 ABI 的一部分。

将给定异常对象的 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)
稳定 ABI 的一部分。

获取给定异常对象的 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)
稳定 ABI 的一部分。

将给定异常对象的 end 属性设置为 end。成功时返回 0,失败时返回 -1

PyObject *PyUnicodeDecodeError_GetReason(PyObject *exc)
PyObject *PyUnicodeEncodeError_GetReason(PyObject *exc)
PyObject *PyUnicodeTranslateError_GetReason(PyObject *exc)
返回值:新的引用。属于 稳定 ABI 的一部分。

返回给定异常对象的 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)
稳定 ABI 的一部分。

将给定异常对象的 reason 属性设置为 reason。成功时返回 0,失败时返回 -1

递归控制

这两个函数提供了一种在 C 级别执行安全递归调用的方法,无论是在核心代码还是在扩展模块中。如果递归代码不一定调用 Python 代码(它会自动跟踪其递归深度),则需要它们。它们对于 tp_call 实现也是不需要的,因为 调用协议 会处理递归。

int Py_EnterRecursiveCall(const char *where)
自 3.9 版本以来成为 稳定 ABI 的一部分。

标记即将执行 C 级别递归调用的点。

如果定义了 USE_STACKCHECK,此函数会使用 PyOS_CheckStack() 检查操作系统堆栈是否溢出。 如果是这种情况,它会设置一个 MemoryError 并返回一个非零值。

然后,该函数会检查是否达到递归限制。 如果是这种情况,则会设置一个 RecursionError 并返回一个非零值。 否则,返回零。

where 应该是一个 UTF-8 编码的字符串,例如 " in instance check",以便将其连接到由递归深度限制引起的 RecursionError 消息。

在 3.9 版本中更改: 此函数现在也可在 有限 API 中使用。

void Py_LeaveRecursiveCall(void)
自 3.9 版本以来成为 稳定 ABI 的一部分。

结束一个 Py_EnterRecursiveCall()。必须为每次成功调用 Py_EnterRecursiveCall() 调用一次。

在 3.9 版本中更改: 此函数现在也可在 有限 API 中使用。

为容器类型正确实现 tp_repr 需要特殊的递归处理。除了保护堆栈之外,tp_repr 还需要跟踪对象以防止循环。以下两个函数有助于实现此功能。 实际上,这些是 reprlib.recursive_repr() 的 C 等价物。

int Py_ReprEnter(PyObject *object)
稳定 ABI 的一部分。

tp_repr 实现的开头调用,以检测循环。

如果该对象已被处理,该函数会返回一个正整数。在这种情况下,tp_repr 实现应返回一个指示循环的字符串对象。例如,dict 对象返回 {...},而 list 对象返回 [...]

如果达到递归限制,该函数将返回一个负整数。在这种情况下,tp_repr 实现通常应返回 NULL

否则,该函数返回零,并且 tp_repr 的实现可以正常继续。

void Py_ReprLeave(PyObject *object)
稳定 ABI 的一部分。

结束一个 Py_ReprEnter() 调用。 对于每个返回零的 Py_ReprEnter() 调用,必须调用一次此函数。

标准异常

所有标准的 Python 异常都以全局变量的形式提供,其名称为 PyExc_ 后跟 Python 异常名称。它们的类型为 PyObject*;它们都是类对象。为了完整起见,这里列出了所有变量。

C 名称

Python 名称

备注

PyExc_BaseException

BaseException

[1]

PyExc_Exception

Exception

[1]

PyExc_ArithmeticError

ArithmeticError

[1]

PyExc_AssertionError

AssertionError

PyExc_AttributeError

AttributeError

PyExc_BlockingIOError

BlockingIOError

PyExc_BrokenPipeError

BrokenPipeError

PyExc_BufferError

BufferError

PyExc_ChildProcessError

ChildProcessError

PyExc_ConnectionAbortedError

ConnectionAbortedError

PyExc_ConnectionError

ConnectionError

PyExc_ConnectionRefusedError

ConnectionRefusedError

PyExc_ConnectionResetError

ConnectionResetError

PyExc_EOFError

EOFError

PyExc_FileExistsError

FileExistsError

PyExc_FileNotFoundError

FileNotFoundError

PyExc_FloatingPointError

FloatingPointError

PyExc_GeneratorExit

GeneratorExit

PyExc_ImportError

ImportError

PyExc_IndentationError

IndentationError

PyExc_IndexError

IndexError

PyExc_InterruptedError

InterruptedError

PyExc_IsADirectoryError

IsADirectoryError

PyExc_KeyError

KeyError

PyExc_KeyboardInterrupt

KeyboardInterrupt

PyExc_LookupError

LookupError

[1]

PyExc_MemoryError

MemoryError

PyExc_ModuleNotFoundError

ModuleNotFoundError

PyExc_NameError

NameError

PyExc_NotADirectoryError

NotADirectoryError

PyExc_NotImplementedError

NotImplementedError

PyExc_OSError

OSError

[1]

PyExc_OverflowError

OverflowError

PyExc_PermissionError

PermissionError

PyExc_ProcessLookupError

ProcessLookupError

PyExc_PythonFinalizationError

PythonFinalizationError

PyExc_RecursionError

RecursionError

PyExc_ReferenceError

ReferenceError

PyExc_RuntimeError

RuntimeError

PyExc_StopAsyncIteration

StopAsyncIteration

PyExc_StopIteration

StopIteration

PyExc_SyntaxError

SyntaxError

PyExc_SystemError

SystemError

PyExc_SystemExit

SystemExit

PyExc_TabError

TabError

PyExc_TimeoutError

TimeoutError

PyExc_TypeError

TypeError

PyExc_UnboundLocalError

UnboundLocalError

PyExc_UnicodeDecodeError

UnicodeDecodeError

PyExc_UnicodeEncodeError

UnicodeEncodeError

PyExc_UnicodeError

UnicodeError

PyExc_UnicodeTranslateError

UnicodeTranslateError

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_ProcessLookupErrorPyExc_TimeoutError 是根据 PEP 3151 引入的。

3.5 版本新增: PyExc_StopAsyncIterationPyExc_RecursionError.

3.6 版本新增: PyExc_ModuleNotFoundError.

这些是 PyExc_OSError 的兼容性别名

C 名称

备注

PyExc_EnvironmentError

PyExc_IOError

PyExc_WindowsError

[2]

在 3.3 版本中更改: 这些别名曾经是单独的异常类型。

备注

标准警告类别

所有标准的 Python 警告类别都以全局变量的形式提供,其名称为 PyExc_ 后跟 Python 异常名称。它们的类型为 PyObject*;它们都是类对象。为了完整起见,这里列出了所有变量。

C 名称

Python 名称

备注

PyExc_Warning

警告

[3]

PyExc_BytesWarning

BytesWarning

PyExc_DeprecationWarning

DeprecationWarning

PyExc_FutureWarning

FutureWarning

PyExc_ImportWarning

ImportWarning

PyExc_PendingDeprecationWarning

PendingDeprecationWarning

PyExc_ResourceWarning

ResourceWarning

PyExc_RuntimeWarning

RuntimeWarning

PyExc_SyntaxWarning

SyntaxWarning

PyExc_UnicodeWarning

UnicodeWarning

PyExc_UserWarning

UserWarning

3.2 版本新增: PyExc_ResourceWarning.

备注