异常处理

本章描述的函数将允许您处理和引发 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_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 的便捷函数。如果以 0ierr 调用,则使用调用 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,它们将分别被设置为 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 的一部分。

测试错误指示器是否已设置。如果已设置,则返回异常类型(对最后一次调用 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 的一部分。

如果给定异常与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

注意

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

例如

{
   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

此函数可以由想要被用户请求(例如通过按 Ctrl-C)中断的长时间运行的 C 代码调用。

注意

默认的 Python 信号处理程序 SIGINT 会引发 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 参数必须是新异常的名称,一个形如 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 版本中添加。

异常对象

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

使用属性encodingobjectlengthstartendreason创建一个UnicodeDecodeError对象。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_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

说明