异常处理¶
本章描述的函数将允许你处理和引发 Python 异常。理解 Python 异常处理的一些基础知识很重要。它有点像 POSIX 的 errno
变量:有一个全局指标(每个线程)指示最后发生的错误。大多数 C API 函数在成功时不会清除它,但会在失败时设置它以指示错误的原因。大多数 C API 函数也会返回一个错误指示符,如果它们应该返回一个指针,通常是 NULL
,或者如果它们返回一个整数,则是 -1
(例外:PyArg_*
函数成功时返回 1
,失败时返回 0
)。
具体来说,错误指示符由三个对象指针组成:异常的类型、异常的值和追溯对象。如果未设置,这些指针中的任何一个都可以是 NULL
(尽管某些组合是被禁止的,例如,如果异常类型是 NULL
,则不能有非 NULL
的追溯)。
当一个函数必须失败因为它调用的某个函数失败时,它通常不会设置错误指示符;它调用的函数已经设置了它。它负责处理错误并清除异常,或者在清理它所持有的任何资源(例如对象引用或内存分配)后返回;如果它未准备好处理错误,它不应正常继续。如果因错误而返回,重要的是要向调用者指示已设置了错误。如果错误未被处理或仔细传播,对 Python/C API 的额外调用可能不会按预期行为,并可能以神秘的方式失败。
备注
错误指示符 不是 sys.exc_info()
的结果。前者对应于尚未捕获(因此仍在传播)的异常,而后者在捕获异常(因此已停止传播)后返回异常。
打印和清除¶
-
void PyErr_PrintEx(int set_sys_last_vars)¶
- 作为 稳定 ABI 的一部分。
向
sys.stderr
打印标准追溯并清除错误指示符。 除非 错误是SystemExit
,在这种情况下不会打印追溯,Python 进程将以SystemExit
实例指定的错误代码退出。仅当 错误指示符已设置时才调用此函数。否则将导致致命错误!
如果 set_sys_last_vars 非零,则变量
sys.last_exc
将设置为打印的异常。为了向后兼容,已弃用的变量sys.last_type
、sys.last_value
和sys.last_traceback
也分别设置为此异常的类型、值和追溯。版本 3.12 中已更改: 添加了
sys.last_exc
的设置。
-
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 版本加入。
引发异常¶
这些函数有助于设置当前线程的错误指示符。为方便起见,其中一些函数将始终返回一个 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 的一部分。
此函数设置错误指示符并返回
NULL
。exception 应该是 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 版本加入。
-
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
。如果调用时 ierr 为0
,则使用调用GetLastError()
返回的错误代码。它调用 Win32 函数FormatMessage()
来检索由 ierr 或GetLastError()
给出的错误代码的 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 将设置为异常的消息字符串。name 和 path(两者都可以是NULL
)将分别设置为ImportError
的name
和path
属性。在 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 参数。
发出警告¶
使用这些函数从 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_Warning
是PyExc_Exception
的子类;默认警告类别是PyExc_RuntimeWarning
。标准 Python 警告类别作为全局变量可用,其名称在 警告类型 中列出。
-
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 的一部分。
测试错误指示符是否已设置。如果已设置,则返回异常 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()
。根据三个对象 type、value 和 traceback 设置错误指示符,如果已设置现有异常,则清除它。如果对象为
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 版本变更:
type
和traceback
参数不再使用,可以为 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_DFL
或signal.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 字符串。base 和 dict 参数通常为NULL
。这会创建一个派生自Exception
(在 C 中可访问为PyExc_Exception
)的类对象。新类的
__module__
属性被设置为 name 参数的第一部分(直到最后一个点),类名被设置为最后一部分(最后一个点之后)。base 参数可用于指定备用基类;它可以是单个类或类的元组。dict 参数可用于指定类变量和方法的字典。
异常对象¶
-
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
。
-
void PyException_SetArgs(PyObject *ex, PyObject *args)¶
- 自 3.12 版本起成为 稳定 ABI 的一部分。
将异常 ex 的
args
设置为 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, end 和 reason。encoding 和 reason 是 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
是一个空序列,则结果 start 为0
。否则,它将被裁剪到[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
是一个空序列,则结果 end 为0
。否则,它将被裁剪到[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
。
递归控制¶
这两个函数提供了一种在 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 名称 |
---|---|
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 引入的。
3.5 版本加入: PyExc_StopAsyncIteration
和 PyExc_RecursionError
。
3.6 版本加入: PyExc_ModuleNotFoundError
。
3.11 版本加入: PyExc_BaseExceptionGroup
。
OSError 别名¶
以下是 PyExc_OSError
的兼容性别名。
3.3 版本中的变化:这些别名曾是独立的异常类型。
C 名称 |
Python 名称 |
备注 |
---|---|---|
备注
PyExc_WindowsError
仅在 Windows 上定义;通过测试预处理器宏 MS_WINDOWS
是否已定义来保护使用此代码。
警告类型¶
C 名称 |
Python 名称 |
---|---|
3.2 版本新增:PyExc_ResourceWarning
。
3.10 版本新增:PyExc_EncodingWarning
。