例外処理

この章で説明する関数を使うと、 Python の例外の処理や送出ができるようになります。 Python の例外処理の基本をいくらか理解することが大切です。例外は Unix errno 変数にやや似た機能を果たします: 発生した中で最も新しいエラーの (スレッド毎の) グローバルなインジケータがあります。実行に成功した場合にはほとんどの関数がこれをクリアしませんが、失敗したときにはエラーの原因を示すために設定します。ほとんどの関数はエラーインジケータも返し、通常は関数がポインタを返すことになっている場合は NULL であり、関数が整数を返す場合は -1 です。(例外: PyArg_*() 関数は実行に成功したときに 1 を返し、失敗したときに 0 を返します).

ある関数が呼び出した関数がいくつか失敗したために、その関数が失敗しなければならないとき、一般的にエラーインジケータを設定しません。呼び出した関数がすでに設定しています。エラーを処理して例外をクリアするか、あるいは (オブジェクト参照またはメモリ割り当てのような)それが持つどんなリソースも取り除いた後に戻るかのどちらか一方を行う責任があります。エラーを処理する準備をしていなければ、普通に続けるべきでは ありません 。エラーのために戻る場合は、エラーが設定されていると呼び出し元に知らせることが大切です。エラーが処理されていない場合または丁寧に伝えられている場合には、 Python/C APIのさらなる呼び出しは意図した通りには動かない可能性があり、不可解な形で失敗するかもしれません。

エラーインジケータは sys.exc_info() の結果に対応する三つのPythonオブジェクトからからなります。いろいろな方法でエラーインジケータとやりとりするためにAPI関数が存在します。各スレッドに別々のエラーインジケータがあります。

void PyErr_PrintEx(int set_sys_last_vars)

sys.stderr へ標準トレースバックをプリントし、エラーインジケータをクリアします。エラーインジケータが設定されているときにだけ、この関数を呼び出してください。(それ以外の場合、致命的なエラーを引き起こすでしょう!)

set_sys_last_vars が非ゼロであれば、 sys.last_type, sys.last_value, sys.last_traceback 変数が、表示される例外のタイプ、値、トレースバックそれぞれに反映されます。

void PyErr_Print()

PyErr_PrintEx(1) のエイリアス.

PyObject* PyErr_Occurred()

エラーインジケータが設定されているかテストします。設定されている場合は、例外の (PyErr_Set*() 関数の一つあるいは PyErr_Restore() への最も新しい呼び出しに対する第一引数)を返します。設定されていない場合は NULL を返します。あなたは戻り値への参照を持っていませんので、それに Py_DECREF() する必要はありません。

注釈

戻り値を特定の例外と比較しないでください。その代わり、下に示す PyErr_ExceptionMatches() を使ってください。(比較は簡単に失敗するでしょう。なぜなら、例外はクラスではなくインスタンスかもしれないし、あるいは、クラス例外の場合は期待される例外のサブクラスかもしれないからです。)

int PyErr_ExceptionMatches(PyObject *exc)

PyErr_GivenExceptionMatches(PyErr_Occurred(), exc) と同じ。例外が実際に設定されたときにだけ、これを呼び出だすべきです。例外が発生していないならば、メモリアクセス違反が起きるでしょう。

int PyErr_GivenExceptionMatches(PyObject *given, PyObject *exc)

given 例外が exc の例外と一致するなら真を返します。これは exc がクラスオブジェクトである場合も真を返します。これは given がサブクラスのインスタンスであるときも真を返します。 exc がタプルならば、タプル内(と再帰的にサブタプル内)のすべての例外が一致するか調べられます。

void PyErr_NormalizeException(PyObject**exc, PyObject**val, PyObject**tb)

ある状況では、以下の PyErr_Fetch() が返す値は “正規化されていない” 可能性があります。つまり、 *exc はクラスオブジェクトだが *val は同じクラスのインスタンスではないという意味です。この関数はそのような場合にそのクラスをインスタンス化するために使われます。その値がすでに正規化されている場合は何も起きません。遅延正規化はパフォーマンスを改善するために実装されています。

void PyErr_Clear()

エラーインジケータをクリアします。エラーインジケータが設定されていないならば、効果はありません。

void PyErr_Fetch(PyObject **ptype, PyObject **pvalue, PyObject **ptraceback)

エラーインジケータをアドレスを渡す三つの変数の中へ取り出します。エラーインジケータが設定されていない場合は、三つすべての変数を NULL に設定します。エラーインジケータが設定されている場合はクリアされ、あなたは取り出されたそれぞれのオブジェクトへの参照を持つことになります。型オブジェクトが NULL でないときでさえ、その値とトレースバックオブジェクトは NULL かもしれません。

注釈

通常、この関数は例外を扱う必要のあるコードあるいはエラーインジケータを一時的に保存して元に戻す必要のあるコードによってのみ使用されます。

void PyErr_Restore(PyObject *type, PyObject *value, PyObject *traceback)

三つのオブジェクトからエラーインジケータを設定します。エラーインジケータがすでに設定されている場合は、最初にクリアされます。オブジェクトが NULL ならば、エラーインジケータがクリアされます。 NULL のtypeと非 NULL のvalueあるいは tracebackを渡してはいけません。例外の型(type)はクラスであるべきです。無効な例外の型(type)あるいは値(value)を渡してはいけません。 (これらの規則を破ると後で気付きにくい問題の原因となるでしょう。) この呼び出しはそれぞれのオブジェクトへの参照を取り除きます: あなたは呼び出しの前にそれぞれのオブジェクトへの参照を持たなければならないのであり、また呼び出しの後にはもはやこれらの参照を持っていません。 (これを理解していない場合は、この関数を使ってはいけません。注意しておきます。)

注釈

通常この関数はエラーインジケータを一時的に保存し元に戻す必要のあるコードによってのみに使われます。現在の例外状態を保存するためには PyErr_Fetch() を使ってください。

void PyErr_GetExcInfo(PyObject **ptype, PyObject **pvalue, PyObject **ptraceback)

sys.exc_info() で得られる例外情報を取得します。 これは既に捕まえた例外を参照しているもので、新たに送出された例外への参照は持っていません。 新しい3つのオブジェクトへの参照を返しますが、その中には NULL があるかもしれません。 この関数は例外情報の状態を変更しません。

注釈

この関数は、通常は例外を扱うコードでは使用されません。 正確に言うと、これは例外の状態を一時的に保存し、元に戻す必要があるコードで使用することができます。 例外の状態を元に戻す、もしくはクリアするには PyErr_SetExcInfo() を使ってください。

バージョン 3.3 で追加.

void PyErr_SetExcInfo(PyObject *type, PyObject *value, PyObject *traceback)

sys.exc_info() で得られる例外情報を設定します。 これは既に捕まえた例外を参照しているもので、新たに送出された例外への参照は持っていません。 この関数は引数への参照を盗みます。 例外の状態をクリアしたい場合は、3 つ全ての引数に NULL を渡してください。 3 つの引数についての一般的な規則は、 PyErr_Restore() を参照してください。

注釈

この関数は、通常は例外を扱うコードでは使用されません。 正確に言うと、これは例外の状態を一時的に保存し、元に戻す必要があるコードで使用することができます。 例外の状態を取得するには PyErr_SetExcInfo() を使ってください。

バージョン 3.3 で追加.

void PyErr_SetString(PyObject *type, const char *message)

これはエラーインジケータを設定するための最も一般的な方法です。第一引数は例外の型を指定します。通常は標準例外の一つ、例えば PyExc_RuntimeError です。その参照カウントを増加させる必要はありません。第二引数はエラーメッセージで、 'utf-8‘ からデコードされます。

void PyErr_SetObject(PyObject *type, PyObject *value)

この関数は PyErr_SetString() に似ていますが、例外の”値(value)”として任意のPythonオブジェクトを指定することができます。

PyObject* PyErr_Format(PyObject *exception, const char *format, ...)

この関数はエラーインジケータを設定し NULL を返します。 exception はPython例外クラスであるべきです。 format と以降の引数はエラーメッセージを作るためのもので, PyString_FromFormat() の引数と同じ意味を持っています。 format は ASCII エンコードされた文字列です。

void PyErr_SetNone(PyObject *type)

これは PyErr_SetObject(type, Py_None) を省略したものです。

int PyErr_BadArgument()

これは PyErr_SetString(PyExc_TypeError, message) を省略したもので、ここで message は組み込み操作が不正な引数で呼び出されたということを表しています。主に内部で使用するためのものです。

PyObject* PyErr_NoMemory()

これは PyErr_SetNone(PyExc_MemoryError) を省略したもので、 NULL を返します。したがって、メモリ不足になったとき、オブジェクト割り当て関数は return PyErr_NoMemory(); と書くことができます。

PyObject* PyErr_SetFromErrno(PyObject *type)

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)

PyErr_SetFromErrno() に似ていますが、 filenameObjectNULL でない場合にそれを type のコンストラクタに第三引数として渡す、というふるまいが追加されています。 IOErrorOSError のような例外の場合では、これが例外インスタンスの filename 属性を定義するために使われます。

PyObject* PyErr_SetFromErrnoWithFilename(PyObject *type, const char *filename)

PyErr_SetFromErrnoWithFilenameObject() と似ていますが、ファイル名は C 文字列として与えられます。 filename はファイルシステムのエンコーディング (sys.getfilesystemencoding()) でデコードされます。

PyObject* PyErr_SetFromWindowsErr(int ierr)

これは WindowsError を発生させるために便利な関数です。 0ierr とともに呼び出された場合、 GetLastError() が返すエラーコードが代りに使われます。 ierr あるいは GetLastError() によって与えられるエラーコードのWindows用の説明を取り出すために、Win32関数 FormatMessage() を呼び出します。それから、第一要素が ierr 値で第二要素が(FormatMessage() から得られる) 対応するエラーメッセージであるタプルオブジェクトを構成します。そして、 PyErr_SetObject(PyExc_WindowsError, object) を呼び出します。この関数は常に NULL を返します。利用可能範囲: Windows。

PyObject* PyErr_SetExcFromWindowsErr(PyObject *type, int ierr)

PyErr_SetFromWindowsErr() に似ていますが、送出する例外の型を指定する引数が追加されています。 利用可能範囲: Windows。

PyObject* PyErr_SetFromWindowsErrWithFilenameObject(int ierr, PyObject *filenameObject)

PyErr_SetFromWindowsErr() に似ていますが、 filenameObjectNULL でない場合には WindowsError のコンストラクタに第三引数として渡されるというふるまいが追加されています。 利用可能範囲: Windows。

PyObject* PyErr_SetFromWindowsErrWithFilename(int ierr, const char *filename)

PyErr_SetFromWindowsErrWithFilenameObject() と似ていますが、ファイル名は C 文字列として与えられます。 filename はファイルシステムのエンコーディング (sys.getfilesystemencoding()) でデコードされます。 利用可能範囲: Windows。

PyObject* PyErr_SetExcFromWindowsErrWithFilenameObject(PyObject *type, int ierr, PyObject *filename)

:c:func:`PyErr_SetFromWindowsErrWithFilenameObject ` に似ていますが、送出する例外の型を指定する引数が追加されています。 利用可能範囲: Windows。

PyObject* PyErr_SetExcFromWindowsErrWithFilename(PyObject *type, int ierr, const char *filename)

PyErr_SetFromWindowsErrWithFilename() に似ていますが、送出する例外の型を指定する引数が追加されています。利用可能範囲: Windows。

PyObject* PyErr_SetImportError(PyObject *msg, PyObject *name, PyObject *path)

ImportError を簡単に送出するための関数です。 msg は例外のメッセージ文字列としてセットされます。 namepath はどちらも NULL にしてよく、それぞれ ImportErrorname 属性と path 属性としてセットされます。

バージョン 3.3 で追加.

void PyErr_SyntaxLocationEx(char *filename, int lineno, int col_offset)

現在の例外のファイル、行、オフセットの情報をセットします。 現在の例外が SyntaxError でない場合は、例外を表示するサブシステムが、例外が SyntaxError であると思えるように属性を追加します。 filename はファイルシステムのエンコーディング (sys.getfilesystemencoding()) でデコードされます。

バージョン 3.2 で追加.

void PyErr_SyntaxLocation(char *filename, int lineno)

Like PyErr_SyntaxLocationEx(), but the col_offset parameter is omitted.

void PyErr_BadInternalCall()

PyErr_SetString(PyExc_SystemError, message) を省略したものです。ここで message は内部操作(例えば、Python/C API関数)が不正な引数とともに呼び出されたということを示しています。主に内部で使用するためのものです。

int PyErr_WarnEx(PyObject *category, char *message, int stack_level)

警告メッセージを出します。 category 引数は警告カテゴリ(以下を参照) かまたは NULL で、 message 引数は UTF-8 エンコードされた文字列です。 stacklevel はフレームの数を示す正の整数です; 警告はそのスタックフレームの中の実行している行から発行されます。 stacklevel が1だと、 PyErr_WarnEx() が、2だとその上の関数が、Warningの発行元になります。

この関数は通常警告メッセージを sys.stderr へプリントします。けれども、ユーザが警告をエラーへ変更するように指定することも可能です。そのような場合には、これは例外を発生させます。警告機構がもつ問題のためにその関数が例外を発生させるということも可能です。(実装ではその厄介な仕事を行うために warnings モジュールをインポートします)。例外が発生させられなければ、戻り値は 0 です。あるいは、例外が発生させられると -1 です。(警告メッセージが実際にプリントされるかどうかを決定することはできず、また何がその例外の原因なのかを決定することもできない。これは意図的なものです。)例外が発生した場合、呼び出し元は通常の例外処理を行います(例えば、 Py_DECREF() は参照を持っており、エラー値を返します)。

警告カテゴリは Warning のサブクラスでなければならない。デフォルト警告カテゴリは RuntimeWarning です。標準Python警告カテゴリは PyExc_ にPython例外名が続く名前のグローバル変数を用いて変更できます。これらは型 PyObject* を持ち、すべてクラスオブジェクトです。それらの名前は PyExc_Warning, PyExc_UserWarning, PyExc_UnicodeWarning, PyExc_DeprecationWarning, PyExc_SyntaxWarning, PyExc_RuntimeWarning, PyExc_FutureWarning です。 PyExc_WarningPyExc_Exception のサブクラスです。その他の警告カテゴリは PyExc_Warning のサブクラスです。

警告をコントロールするための情報については、 warnings モジュールのドキュメンテーションとコマンドライン・ドキュメンテーションの -W オプションを参照してください。警告コントロールのためのC APIはありません。

int PyErr_WarnExplicit(PyObject *category, const char *message, const char *filename, int lineno, const char *module, PyObject *registry)

すべての警告の属性を明示的に制御した警告メッセージを出します。これはPython関数 warnings.warn_explicit() の直接的なラッパで、さらに情報を得るにはそちらを参照してください。そこに説明されているデフォルトの効果を得るために、 moduleregistry 引数は NULL に設定することができます。 messagemodule は UTF-8 エンコードされた文字列で、 filename はファイルシステムエンコーディング (sys.getfilesystemencoding()) からデコードされます。

int PyErr_WarnFormat(PyObject *category, Py_ssize_t stack_level, const char *format, ...)

PyErr_WarnEx() に似たような関数ですが、警告メッセージをフォーマットするのに PyUnicode_FromFormat() を使用します。 format は ASCII にエンコードされた文字列です。

バージョン 3.2 で追加.

int PyErr_CheckSignals()

この関数はPythonのシグナル処理とやりとりすることができます。シグナルがそのプロセスへ送られたかどうかチェックし、そうならば対応するシグナルハンドラを呼び出します。 signal モジュールがサポートされている場合は、これはPythonで書かれたシグナルハンドラを呼び出せます。すべての場合で、 SIGINT のデフォルトの効果は KeyboardInterrupt 例外を発生させることです。例外が発生した場合、エラーインジケータが設定され、関数は -1 を返します。そうでなければ、関数は 0 を返します。エラーインジケータが以前に設定されている場合は、それがクリアされるかどうかわからない。

void PyErr_SetInterrupt()

この関数は廃止されています。 SIGINT シグナルが到達した影響をシミュレートします — 次に PyErr_CheckSignals() が呼ばれるとき、 KeyboardInterrupt は送出されるでしょう。インタプリタロックを保持することなく呼び出すことができます。

int PySignal_SetWakeupFd(int fd)

このユーティリティ関数は、シグナルを受信したときに '\0' バイトを書き込むファイルディスクリプタを指定します。戻り値は、それまで設定されていたファイルディスクリプタです。 -1 はこの機能を無効にします。これは初期状態です。これは Python の signal.set_wakeup_fd() と同じものですが、エラーチェックを行ないません。 fd は有効なファイルディスクリプタであるべきです。この関数の呼び出しはメインスレッドのみから行われるべきです。

PyObject* PyErr_NewException(char *name, PyObject *base, PyObject *dict)

このユーティリティ関数は新しい例外クラスを作成して返します。 name 引数は新しい例外の名前、 module.classname 形式の C文字列でなければならない。 basedict 引数は通常 NULL です。これはすべての例外のためのルート、組み込み名 Exception (Cでは PyExc_Exception としてアクセス可能)をルートとして派生したクラスオブジェクトを作成します。

新しいクラスの __module__ 属性は name 引数の前半部分(最後のドットまで)に設定され、クラス名は後半部分(最後のドットの後)に設定されます。 base 引数は代わりのベースクラスを指定するために使えます; 一つのクラスでも、クラスのタプルでも構いません。 dict 引数はクラス変数とメソッドの辞書を指定するために使えます。

PyObject* PyErr_NewExceptionWithDoc(char *name, char *doc, PyObject *base, PyObject *dict)

PyErr_NewException() とほぼ同じですが、新しい例外クラスに簡単に docstring を設定できます。 docNULL で無い場合、それが例外クラスの docstring になります。

バージョン 3.2 で追加.

void PyErr_WriteUnraisable(PyObject *obj)

例外が設定されているがインタプリタが実際に例外を発生させることができないときに、このユーティリティ関数は警告メッセージを sys.stderr へプリントします。例えば、例外が __del__() メソッドで発生したときに使われます。

発生させられない例外が生じたコンテキストを特定するための一つの引数 obj とともに関数が呼び出されます。 obj のreprが警告メッセージにプリントされるでしょう。

例外オブジェクト

PyObject* PyException_GetTraceback(PyObject *ex)

Python で __traceback__ 属性からアクセスできるものと同じ、例外に関する traceback の新しい参照を返します。 関係する traceback が無い場合は、 NULL を返します。

int PyException_SetTraceback(PyObject *ex, PyObject *tb)

その例外に関する traceback に tb をセットします。 クリアするには Py_None を使用してください。

PyObject* PyException_GetContext(PyObject *ex)

Python で __context__ 属性からアクセスできるものと同じ、例外に関するコンテキスト (ex が送出されたときに処理していた別の例外インスタンス) の新しい参照を返します。 関係するコンテキストが無い場合は、 NULL を返します。

void PyException_SetContext(PyObject *ex, PyObject *ctx)

例外に関するコンテキストに ctx をセットします。 クリアするには NULL を使用してください。 ctx が例外インスタンスかどうかを確かめる型チェックは行われません。 これは ctx への参照を盗みます。

PyObject* PyException_GetCause(PyObject *ex)

Python で __cause__ 属性からアクセスできるものと同じ、例外に関する原因 (raise ... from ... によってセットされる例外インスタンス、もしくは None) の新しい参照を返します。

void PyException_SetCause(PyObject *ex, PyObject *cause)

Set the cause associated with the exception to cause. Use NULL to clear it. There is no type check to make sure that cause is either an exception instance or None. This steals a reference to cause.

この関数によって暗黙的に __suppress_context__True がセットされます。

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)

encoding, object, length, start, end, reason 属性をもった UnicodeDecodeError オブジェクトを作成します。 encoding および reason は UTF-8 エンコードされた文字列です。

PyObject* PyUnicodeEncodeError_Create(const char *encoding, const Py_UNICODE *object, Py_ssize_t length, Py_ssize_t start, Py_ssize_t end, const char *reason)

encoding, object, length, start, end, reason 属性を持った UnicodeEncodeError オブジェクトを作成します。 encoding および reason は UTF-8 エンコードされた文字列です。

PyObject* PyUnicodeTranslateError_Create(const Py_UNICODE *object, Py_ssize_t length, Py_ssize_t start, Py_ssize_t end, const char *reason)

object, length, start, end, reason 属性を持った UnicodeTranslateError オブジェクトを作成します。 reason は UTF-8 エンコードされた文字列です。

PyObject* PyUnicodeDecodeError_GetEncoding(PyObject *exc)
PyObject* PyUnicodeEncodeError_GetEncoding(PyObject *exc)

与えられた例外オブジェクトの encoding 属性を返します。

PyObject* PyUnicodeDecodeError_GetObject(PyObject *exc)
PyObject* PyUnicodeEncodeError_GetObject(PyObject *exc)
PyObject* PyUnicodeTranslateError_GetObject(PyObject *exc)

与えられた例外オブジェクトの 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)

渡された例外オブジェクトから start 属性を取得して *start に格納します。 startNULL であってはなりません。成功したら 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)

渡された例外オブジェクトの 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)

渡された例外オブジェクトから end 属性を取得して *end に格納します。 endNULL であってはなりません。成功したら 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)

渡された例外オブジェクトの end 属性を end に設定します。成功したら 0 を、失敗したら -1 を返します。

PyObject* PyUnicodeDecodeError_GetReason(PyObject *exc)
PyObject* PyUnicodeEncodeError_GetReason(PyObject *exc)
PyObject* PyUnicodeTranslateError_GetReason(PyObject *exc)

渡された例外オブジェクトの 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)

渡された例外オブジェクトの reason 属性を reason に設定します。成功したら 0 を、失敗したら -1 を返します。

再帰の管理

これら2つの関数は C レベルの再帰呼び出しを安全に実行する方法を、コアモジュールにも拡張モジュールにも提供します。再帰を使ったコードが必ずしも Python コードを実行するわけではない場合 (Python コードは再帰の深さを自動的に追跡します)、これらの関数が必要となります。

int Py_EnterRecursiveCall(char *where)

C レベルの再帰呼び出しをしようとしているところに印を付けます。

USE_STACKCHECK が定義されている場合、 OS のスタックがオーバーフローがしたかどうかを PyOS_CheckStack() を使ってチェックします。もしオーバーフローしているなら、 MemoryError をセットしゼロでない値を返します。

次にこの関数は再帰の上限に達していないかをチェックします。上限に達している場合、 RuntimeError をセットしゼロでない値を返します。そうでない場合はゼロを返します。

再帰の深さの上限に達して送出される RuntimeError のメッセージに連結できるよう where" in instance check" のような文字列にしてください。

void Py_LeaveRecursiveCall()

Py_EnterRecursiveCall() を終了させます。 Py_EnterRecursiveCall()成功した 呼び出しに対し 1 回呼ばなければなりません。

コンテナ型に対し tp_repr を適切に実装するには、特殊な再帰の処理が求められます。 スタックの防護に加え、 tp_repr は循環処理を避けるためにオブジェクトを辿っていく必要があります。 次の 2 つの関数はその機能を容易にします。 実質的には、これらは reprlib.recursive_repr() と同等な C の実装です。

int Py_ReprEnter(PyObject *object)

循環処理を検知するために、 tp_repr の実装の先頭で呼び出します。

そのオブジェクトが既に処理されたものだった場合、この関数は正の整数を返します。 その場合、 tp_repr の実装は、循環を示す文字列オブジェクトを返すべきです。 例えば、 dict オブジェクトは {...} を返しますし、 list オブジェクトは [...] を返します。

再帰回数の上限に達した場合は、この関数は負の整数を返します。 この場合、 tp_repr の実装は一般的には NULL を返すべきです。

それ以外の場合は、関数はゼロを返し、 tp_repr の実装は通常どおり処理を続けてかまいません。

void Py_ReprLeave(PyObject *object)

Py_ReprEnter() を終了させます。 0 を返した Py_ReprEnter() の呼び出しに対し 1 回呼ばなければなりません。

標準例外

PyExc_ の後ろにPythonの例外名が続く名前をもつグローバル変数として、すべての標準Python例外が利用可能です。これらは型 PyObject* を持ち、すべてクラスオブジェクトです。完璧を期するために、すべての変数を以下に列挙します:

C名

Python名

注釈

PyExc_BaseException BaseException (1)
PyExc_Exception Exception (1)
PyExc_ArithmeticError ArithmeticError (1)
PyExc_LookupError LookupError (1)
PyExc_AssertionError AssertionError  
PyExc_AttributeError AttributeError  

PyExc_EOFError

BlockingIOError  
PyExc_BrokenPipeError BrokenPipeError  
PyExc_ChildProcessError ChildProcessError  
PyExc_ConnectionError ConnectionError  
PyExc_ConnectionAbortedError ConnectionAbortedError  
PyExc_ConnectionRefusedError ConnectionRefusedError  
PyExc_ConnectionResetError ConnectionResetError  
PyExc_FileExistsError FileExistsError  
PyExc_FileNotFoundError FileNotFoundError  
PyExc_EOFError EOFError  
PyExc_FloatingPointError FloatingPointError  
PyExc_ImportError ImportError  
PyExc_IndexError IndexError  
PyExc_InterruptedError InterruptedError  
PyExc_IsADirectoryError IsADirectoryError  
PyExc_KeyError KeyError  
PyExc_KeyboardInterrupt KeyboardInterrupt  
PyExc_MemoryError MemoryError  
PyExc_NameError NameError  
PyExc_NotADirectoryError NotADirectoryError  
PyExc_NotImplementedError NotImplementedError  
PyExc_OSError OSError (1)
PyExc_OverflowError OverflowError  
PyExc_PermissionError PermissionError  
PyExc_ProcessLookupError ProcessLookupError  
PyExc_ReferenceError ReferenceError (2)
PyExc_RuntimeError RuntimeError  
PyExc_SyntaxError SyntaxError  
PyExc_SystemError SystemError  
PyExc_TimeoutError TimeoutError  
PyExc_SystemExit SystemExit  
PyExc_TypeError TypeError  
PyExc_ValueError ValueError  
PyExc_ZeroDivisionError ZeroDivisionError  

バージョン 3.3 で追加: PyExc_BlockingIOErrorPyExc_BrokenPipeErrorPyExc_ChildProcessErrorPyExc_ConnectionErrorPyExc_ConnectionAbortedErrorPyExc_ConnectionRefusedErrorPyExc_ConnectionResetErrorPyExc_FileExistsErrorPyExc_FileNotFoundErrorPyExc_InterruptedErrorPyExc_IsADirectoryErrorPyExc_NotADirectoryErrorPyExc_PermissionErrorPyExc_ProcessLookupErrorPyExc_TimeoutErrorPEP 3151 により導入されました。

これらは互換性のある PyExc_OSError のエイリアスです:

C名

注釈

PyExc_EnvironmentError  
PyExc_IOError  
PyExc_WindowsError (3)

バージョン 3.3 で変更: これらのエイリアスは例外の種類を分けるために使われます。

ノート:

  1. これは別の標準例外のためのベースクラスです。

  2. これは weakref.ReferenceError と同じです。

  3. Windowsでのみ定義されています。プリプロセッサマクロ MS_WINDOWS が定義されているかテストすることで、これを使うコードを保護してください。