異常處理¶
本章描述的函式可讓你處理和引發 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 的一部分。
測試是否設定了錯誤指示器。如果已設定,則返回異常型別(上次呼叫
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()
。從三個物件 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)
。注意
此函式是非同步訊號安全的。 它可以在沒有 GIL 的情況下從 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
。 此函式永遠不會更改錯誤指示器。注意
此函式是非同步訊號安全的。 它可以在沒有 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 字串,格式為
模組名.類名
。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 的一部分。
返回與異常關聯的原因(異常例項或
None
,由raise ... from ...
設定)作為新的引用,如同透過 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 的一部分。
建立一個具有屬性 encoding、object、length、start、end 和 reason 的
UnicodeDecodeError
物件。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
。
-
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
。
遞迴控制¶
這兩個函式提供了一種在 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 名稱 |
備註 |
---|---|---|
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
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
.
這些是 PyExc_OSError
的相容性別名
C 名稱 |
備註 |
---|---|
|
|
|
|
|
在 3.3 版本中更改: 這些別名曾經是單獨的異常型別。
備註
標準警告類別¶
所有標準的 Python 警告類別都以全域性變數的形式提供,其名稱為 PyExc_
後跟 Python 異常名稱。它們的型別為 PyObject*;它們都是類物件。為了完整起見,這裡列出了所有變數。
C 名稱 |
Python 名稱 |
備註 |
---|---|---|
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
3.2 版本新增: PyExc_ResourceWarning
.
備註
這是其他標準警告類別的基類。