異常處理

本章描述的函式可讓你處理和引發 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.

備註