例外処理

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

具体的には、エラーインジケータは3つのオブジェクトポインタから構成されます: 例外型、例外値、トレースバックオブジェクトです。 これらのポインタは設定されない場合は NULL でもかまいません (ただし、禁止されている組み合わせもあります。例えば、例外型が NULL の場合は、非 NULL なトレースバックはありません)。

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

注釈

エラー識別子は sys.exc_info() の結果 ではありません。エラー識別子はまだ捕捉されていない例外 (したがってまだ伝播します) に対応しているのに対し、 sys.exc_info() の結果は捕捉された後の例外を返します (したがってもう伝播しません)。

出力とクリア

void PyErr_Clear()

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

void PyErr_PrintEx(int set_sys_last_vars)

Print a standard traceback to sys.stderr and clear the error indicator. Call this function only when the error indicator is set. (Otherwise it will cause a fatal error!)

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

void PyErr_Print()

PyErr_PrintEx(1) のエイリアスです。

void PyErr_WriteUnraisable(PyObject *obj)

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

発生させられない例外が起きたコンテキストを指し示す単一の引数 obj で関数が呼び出されます。 可能な場合は、 obj の repr 文字列が警告メッセージに出力されます。

例外の送出

以下の関数は、現在のスレッドのエラーインジケータを設定する助けになります。 return 文で使うのに都合が良いように、いくつかの関数は常に NULL ポインタを返します。

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, ...)
Return value: Always NULL.

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

PyObject* PyErr_FormatV(PyObject *exception, const char *format, va_list vargs)
Return value: Always NULL.

PyErr_Format() と同じですが、可変長引数の代わりに va_list 引数を受け取ります。

バージョン 3.5 で追加.

void PyErr_SetNone(PyObject *type)

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

int PyErr_BadArgument()

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

PyObject* PyErr_NoMemory()
Return value: Always NULL.

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

PyObject* PyErr_SetFromErrno(PyObject *type)
Return value: Always NULL.

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 のコンストラクタに第三引数として渡すというふるまいが追加されています。 OSError 例外の場合では、 filenameObject が例外インスタンスの filename 属性を定義するのに使われます。

PyObject* PyErr_SetFromErrnoWithFilenameObjects(PyObject *type, PyObject *filenameObject, PyObject *filenameObject2)

PyErr_SetFromErrnoWithFilenameObject() に似てますが、ファイル名を2つ取る関数が失敗したときに例外を送出するために、2つ目のファイル名オブジェクトを受け取ります。

バージョン 3.4 で追加.

PyObject* PyErr_SetFromErrnoWithFilename(PyObject *type, const char *filename)
Return value: Always NULL.

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

PyObject* PyErr_SetFromWindowsErr(int ierr)
Return value: Always NULL.

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

PyObject* PyErr_SetExcFromWindowsErr(PyObject *type, int ierr)
Return value: Always NULL.

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

PyObject* PyErr_SetFromWindowsErrWithFilename(int ierr, const char *filename)
Return value: Always NULL.

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

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

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

PyObject* PyErr_SetExcFromWindowsErrWithFilenameObjects(PyObject *type, int ierr, PyObject *filename, PyObject *filename2)

PyErr_SetExcFromWindowsErrWithFilenameObject() に似てますが、2つ目のファイル名オブジェクトを受け取ります。 利用可能範囲: Windows。

バージョン 3.4 で追加.

PyObject* PyErr_SetExcFromWindowsErrWithFilename(PyObject *type, int ierr, const char *filename)
Return value: Always NULL.

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

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

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

バージョン 3.3 で追加.

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)

PyErr_SyntaxLocationObject() と似ていますが、 filename はファイルシステムのエンコーディングでデコードされた (os.fsdecode()) バイト文字列です。

バージョン 3.2 で追加.

void PyErr_SyntaxLocation(const char *filename, int lineno)

PyErr_SyntaxLocationEx() と似ていますが、 col_offset 引数が除去されています。

void PyErr_BadInternalCall()

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)

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

警告カテゴリは 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)

PyErr_WarnExplicitObject() に似ていますが、 messagemodule が UTF-8 エンコードされた文字列であるところが異なり、 filename はファイルシステムのエンコーディング (os.fsdecode()) でデコードされます。

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

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

バージョン 3.2 で追加.

エラーインジケータの問い合わせ

PyObject* PyErr_Occurred()
Return value: Borrowed reference.

エラーインジケータが設定されているかテストします。設定されている場合は、例外の (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)

例外 givenexc の例外型と適合する場合に真を返します。 exc がクラスオブジェクトである場合も、 given がサブクラスのインスタンスであるときに真を返します。 exc がタプルの場合は、タプルにある (およびそのサブタプルに再帰的にある) すべての例外型が適合するか調べられます。

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

エラーインジケータをアドレスを渡す三つの変数の中へ取り出します。エラーインジケータが設定されていない場合は、三つすべての変数を 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)

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

注釈

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

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

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

注釈

この関数は例外値に暗黙的に __traceback__ 属性を設定 しません 。 トレースバックを適切に設定する必要がある場合は、次の追加のコード片が必要です:

if (tb != NULL) {
  PyException_SetTraceback(val, tb);
}
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_GetExcInfo() を使ってください。

バージョン 3.3 で追加.

シグナルハンドリング

int PyErr_CheckSignals()

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

void PyErr_SetInterrupt()

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

int PySignal_SetWakeupFd(int fd)

このユーティリティ関数は、シグナルを受け取ったときにシグナル番号をバイトとして書き込むファイル記述子を指定します。 fd はノンブロッキングでなければなりません。 この関数は、1つ前のファイル記述子を返します。

-1 を渡すと、この機能を無効にします; これが初期状態です。 この関数は Python の signal.set_wakeup_fd() と同等ですが、どんなエラーチェックも行いません。 fd は有効なファイル記述子であるべきです。 この関数はメインスレッドからのみ呼び出されるべきです。

バージョン 3.5 で変更: Windowsで、この関数はソケットハンドルをサポートするようになりました。

例外クラス

PyObject* PyErr_NewException(const char *name, PyObject *base, PyObject *dict)
Return value: New reference.

このユーティリティ関数は新しい例外クラスを作成して返します。 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)
Return value: New reference.

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

バージョン 3.2 で追加.

例外オブジェクト

PyObject* PyException_GetTraceback(PyObject *ex)
Return value: New reference.

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)

例外に関係する原因に cause をセットします。 クリアするには NULL を使用してください。 cause が例外インスタンスか None のどちらかであることを確かめる型チェックは行われません。 これは 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(const char *where)

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

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

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

where" in instance check" のような文字列にして、再帰の深さの限界に達したことで送出される RecursionError のメッセージに連結できるようにすべきです。

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_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_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 (2)
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_BlockingIOErrorPyExc_BrokenPipeErrorPyExc_ChildProcessErrorPyExc_ConnectionErrorPyExc_ConnectionAbortedErrorPyExc_ConnectionRefusedErrorPyExc_ConnectionResetErrorPyExc_FileExistsErrorPyExc_FileNotFoundErrorPyExc_InterruptedErrorPyExc_IsADirectoryErrorPyExc_NotADirectoryErrorPyExc_PermissionErrorPyExc_ProcessLookupErrorPyExc_TimeoutErrorPEP 3151 により導入されました。

バージョン 3.5 で追加: PyExc_StopAsyncIteration および PyExc_RecursionError

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

C名 注釈
PyExc_EnvironmentError  
PyExc_IOError  
PyExc_WindowsError (3)

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

注釈:

  1. これは別の標準例外のためのベースクラスです。
  2. これは weakref.ReferenceError と同じです。
  3. Windowsでのみ定義されています。プリプロセッサマクロ MS_WINDOWS が定義されているかテストすることで、これを使うコードを保護してください。

標準警告カテゴリ

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

C名 Python名 注釈
PyExc_Warning Warning (1)
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.

注釈:

  1. これは別の標準警告カテゴリのためのベースクラスです。