异常处理

本章描述的函数将允许你处理和引发 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 将在警告消息中打印。如果 objNULL,则只打印追溯。

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

版本 3.4 中已更改: 打印追溯。如果 objNULL,则只打印追溯。

版本 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)。如果 formatNULL,则只打印追溯。

在 3.13 版本加入。

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

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

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 的一部分。

这是一个方便的函数,用于引发 ImportErrormsg 将设置为异常的消息字符串。namepath(两者都可以是 NULL)将分别设置为 ImportErrornamepath 属性。

在 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 参数是警告类别(见下文)或 NULLmessage 参数是一个 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() 的直接包装;有关更多信息,请参阅该处。moduleregistry 参数可以设置为 NULL 以获得那里描述的默认效果。

在 3.4 版本加入。

int PyErr_WarnExplicit(PyObject *category, const char *message, const char *filename, int lineno, const char *module, PyObject *registry)
作为 稳定 ABI 的一部分。

类似于 PyErr_WarnExplicitObject(),不同之处在于 messagemodule 是 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(),但 categoryResourceWarning,并且它将 source 传递给 warnings.WarningMessage

在 3.6 版本加入。

查询错误指示符

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

测试错误指示符是否已设置。如果已设置,则返回异常 type(上次调用 PyErr_Set* 函数之一或 PyErr_Restore() 的第一个参数)。如果未设置,则返回 NULL。你未拥有返回值的引用,因此无需 Py_DECREF() 它。

调用者必须具有 已附加的线程状态

备注

不要将返回值与特定异常进行比较;请改用 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 的引用,该引用必须是一个有效的异常。

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)

备注

此函数是异步信号安全的。它可以在没有附加线程状态的情况下和从 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。此函数从不更改错误指示器。

备注

此函数是异步信号安全的。它可以在没有附加线程状态的情况下和从 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 参数必须是新异常的名称,一个形式为 module.classname 的 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() 相同,不同之处在于可以轻松地为新异常类提供文档字符串:如果 docNULL,它将用作异常类的文档字符串。

在 3.2 版本加入。

int PyExceptionClass_Check(PyObject *ob)

如果 ob 是一个异常类,则返回非零值,否则返回零。此函数始终成功。

const char *PyExceptionClass_Name(PyObject *ob)
自 3.8 版本以来,作为稳定 ABI 的一部分。

返回异常类 obtp_name

异常对象

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 的一部分。

返回与异常关联的原因(由 raise ... from ... 设置的异常实例或 None)作为新引用,可通过 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 的一部分。

创建一个 UnicodeDecodeError 对象,其属性包括 encoding, object, length, start, endreasonencodingreason 是 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

如果 UnicodeError.object 是一个空序列,则结果 start0。否则,它将被裁剪到 [0, len(object) - 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

备注

虽然传递负的 start 不会引发异常,但相应的 getter 不会将其视为相对偏移。

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

如果 UnicodeError.object 是一个空序列,则结果 end0。否则,它将被裁剪到 [1, len(object)]

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 级别调用的点。

然后函数检查是否达到栈限制。如果是,则设置 RecursionError 并返回非零值。否则,返回零。

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

3.9 版本变更: 此函数现在也可在 Limited API 中使用。

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

结束一次 Py_EnterRecursiveCall()。对于每次 成功 调用 Py_EnterRecursiveCall(),都必须调用一次。

3.9 版本变更: 此函数现在也可在 Limited 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 名称

PyObject *PyExc_BaseException
作为 稳定 ABI 的一部分。

BaseException

PyObject *PyExc_BaseExceptionGroup
自 3.11 版本起成为 稳定 ABI 的一部分。

BaseExceptionGroup

PyObject *PyExc_Exception
作为 稳定 ABI 的一部分。

Exception

PyObject *PyExc_ArithmeticError
作为 稳定 ABI 的一部分。

ArithmeticError

PyObject *PyExc_AssertionError
作为 稳定 ABI 的一部分。

AssertionError

PyObject *PyExc_AttributeError
作为 稳定 ABI 的一部分。

AttributeError

PyObject *PyExc_BlockingIOError
自 3.7 版本起成为 稳定ABI 的一部分。

BlockingIOError

PyObject *PyExc_BrokenPipeError
自 3.7 版本起成为 稳定ABI 的一部分。

BrokenPipeError

PyObject *PyExc_BufferError
作为 稳定 ABI 的一部分。

BufferError

PyObject *PyExc_ChildProcessError
自 3.7 版本起成为 稳定ABI 的一部分。

ChildProcessError

PyObject *PyExc_ConnectionAbortedError
自 3.7 版本起成为 稳定ABI 的一部分。

ConnectionAbortedError

PyObject *PyExc_ConnectionError
自 3.7 版本起成为 稳定ABI 的一部分。

ConnectionError

PyObject *PyExc_ConnectionRefusedError
自 3.7 版本起成为 稳定ABI 的一部分。

ConnectionRefusedError

PyObject *PyExc_ConnectionResetError
自 3.7 版本起成为 稳定ABI 的一部分。

ConnectionResetError

PyObject *PyExc_EOFError
作为 稳定 ABI 的一部分。

EOFError

PyObject *PyExc_FileExistsError
自 3.7 版本起成为 稳定ABI 的一部分。

FileExistsError

PyObject *PyExc_FileNotFoundError
自 3.7 版本起成为 稳定ABI 的一部分。

FileNotFoundError

PyObject *PyExc_FloatingPointError
作为 稳定 ABI 的一部分。

FloatingPointError

PyObject *PyExc_GeneratorExit
作为 稳定 ABI 的一部分。

GeneratorExit

PyObject *PyExc_ImportError
作为 稳定 ABI 的一部分。

ImportError

PyObject *PyExc_IndentationError
作为 稳定 ABI 的一部分。

IndentationError

PyObject *PyExc_IndexError
作为 稳定 ABI 的一部分。

IndexError

PyObject *PyExc_InterruptedError
自 3.7 版本起成为 稳定ABI 的一部分。

InterruptedError

PyObject *PyExc_IsADirectoryError
自 3.7 版本起成为 稳定ABI 的一部分。

IsADirectoryError

PyObject *PyExc_KeyError
作为 稳定 ABI 的一部分。

KeyError

PyObject *PyExc_KeyboardInterrupt
作为 稳定 ABI 的一部分。

KeyboardInterrupt

PyObject *PyExc_LookupError
作为 稳定 ABI 的一部分。

LookupError

PyObject *PyExc_MemoryError
作为 稳定 ABI 的一部分。

MemoryError

PyObject *PyExc_ModuleNotFoundError
自 3.6 版本起成为 稳定 ABI 的一部分。

ModuleNotFoundError

PyObject *PyExc_NameError
作为 稳定 ABI 的一部分。

NameError

PyObject *PyExc_NotADirectoryError
自 3.7 版本起成为 稳定ABI 的一部分。

NotADirectoryError

PyObject *PyExc_NotImplementedError
作为 稳定 ABI 的一部分。

NotImplementedError

PyObject *PyExc_OSError
作为 稳定 ABI 的一部分。

OSError

PyObject *PyExc_OverflowError
作为 稳定 ABI 的一部分。

OverflowError

PyObject *PyExc_PermissionError
自 3.7 版本起成为 稳定ABI 的一部分。

PermissionError

PyObject *PyExc_ProcessLookupError
自 3.7 版本起成为 稳定ABI 的一部分。

ProcessLookupError

PyObject *PyExc_PythonFinalizationError

PythonFinalizationError

PyObject *PyExc_RecursionError
自 3.7 版本起成为 稳定ABI 的一部分。

RecursionError

PyObject *PyExc_ReferenceError
作为 稳定 ABI 的一部分。

ReferenceError

PyObject *PyExc_RuntimeError
作为 稳定 ABI 的一部分。

RuntimeError

PyObject *PyExc_StopAsyncIteration
自 3.7 版本起成为 稳定ABI 的一部分。

StopAsyncIteration

PyObject *PyExc_StopIteration
作为 稳定 ABI 的一部分。

StopIteration

PyObject *PyExc_SyntaxError
作为 稳定 ABI 的一部分。

SyntaxError

PyObject *PyExc_SystemError
作为 稳定 ABI 的一部分。

SystemError

PyObject *PyExc_SystemExit
作为 稳定 ABI 的一部分。

SystemExit

PyObject *PyExc_TabError
作为 稳定 ABI 的一部分。

TabError

PyObject *PyExc_TimeoutError
自 3.7 版本起成为 稳定ABI 的一部分。

TimeoutError

PyObject *PyExc_TypeError
作为 稳定 ABI 的一部分。

TypeError

PyObject *PyExc_UnboundLocalError
作为 稳定 ABI 的一部分。

UnboundLocalError

PyObject *PyExc_UnicodeDecodeError
作为 稳定 ABI 的一部分。

UnicodeDecodeError

PyObject *PyExc_UnicodeEncodeError
作为 稳定 ABI 的一部分。

UnicodeEncodeError

PyObject *PyExc_UnicodeError
作为 稳定 ABI 的一部分。

UnicodeError

PyObject *PyExc_UnicodeTranslateError
作为 稳定 ABI 的一部分。

UnicodeTranslateError

PyObject *PyExc_ValueError
作为 稳定 ABI 的一部分。

ValueError

PyObject *PyExc_ZeroDivisionError
作为 稳定 ABI 的一部分。

ZeroDivisionError

3.6 版本加入: PyExc_ModuleNotFoundError

3.11 版本加入: PyExc_BaseExceptionGroup

OSError 别名

以下是 PyExc_OSError 的兼容性别名。

3.3 版本中的变化:这些别名曾是独立的异常类型。

C 名称

Python 名称

备注

PyObject *PyExc_EnvironmentError
作为 稳定 ABI 的一部分。

OSError

PyObject *PyExc_IOError
作为 稳定 ABI 的一部分。

OSError

PyObject *PyExc_WindowsError
自 3.7 版本起,成为 Windows 上 稳定 ABI 的一部分。

OSError

[win]

备注

[win]

PyExc_WindowsError 仅在 Windows 上定义;通过测试预处理器宏 MS_WINDOWS 是否已定义来保护使用此代码。

警告类型

C 名称

Python 名称

PyObject *PyExc_Warning
作为 稳定 ABI 的一部分。

警告

PyObject *PyExc_BytesWarning
作为 稳定 ABI 的一部分。

BytesWarning

PyObject *PyExc_DeprecationWarning
作为 稳定 ABI 的一部分。

DeprecationWarning

PyObject *PyExc_EncodingWarning
自 3.10 版本以来,作为 稳定 ABI 的一部分。

EncodingWarning

PyObject *PyExc_FutureWarning
作为 稳定 ABI 的一部分。

FutureWarning

PyObject *PyExc_ImportWarning
作为 稳定 ABI 的一部分。

ImportWarning

PyObject *PyExc_PendingDeprecationWarning
作为 稳定 ABI 的一部分。

PendingDeprecationWarning

PyObject *PyExc_ResourceWarning
自 3.7 版本起成为 稳定ABI 的一部分。

ResourceWarning

PyObject *PyExc_RuntimeWarning
作为 稳定 ABI 的一部分。

RuntimeWarning

PyObject *PyExc_SyntaxWarning
作为 稳定 ABI 的一部分。

SyntaxWarning

PyObject *PyExc_UnicodeWarning
作为 稳定 ABI 的一部分。

UnicodeWarning

PyObject *PyExc_UserWarning
作为 稳定 ABI 的一部分。

UserWarning

3.2 版本新增:PyExc_ResourceWarning

3.10 版本新增:PyExc_EncodingWarning