### ナビゲーション

- 索引
- モジュール |
- 次へ |
- 前へ |
- Python 2.6ja2 documentation »
- Python/C API リファレンスマニュアル »

# 例外処理

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

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

エラーインジケータは Python変数 `sys.exc_type`, `sys.exc_value` および `sys.exc_traceback` に対応する三つの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`()
  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)

  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_SetString`(PyObject *type, const char *message)

  これはエラーインジケータを設定するための最も一般的な方法です。第一引数は例外の型を指定します。通常は標準例外の一つ、例えば `PyExc_RuntimeError` です。その参照カウントを増加させる必要はありません。第二引数はエラーメッセージで、文字列オブジェクトへ変換されます。

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 は文字列であるべきであり、 `printf()` に似た書式化コードを含んでいます。書式化コードの前の `幅.精度(width.precision)` は解析されますが、幅の部分は無視されます。

  書式文字 | 型 | コメント
  --- | --- | ---
  `%%` | n/a | リテラルの % 文字。
  `%c` | int | 一文字. Cのintで表現される。
  `%d` | int | `printf("%d")` と完全に同じ。
  `%u` | unsigned int | `printf("%u")` と完全に同じ。
  `%ld` | long | `printf("%ld")` と完全に同じ。
  `%lu` | unsigned long | `printf("%lu")` と完全に同じ。
  `%zd` | Py_ssize_t | `printf("%zd")` と完全に同じ。
  `%zu` | size_t | `printf("%zu")` と完全に同じ.
  `%i` | int | `printf("%i")` と完全に同じ。
  `%x` | int | `printf("%x")` と完全に同じ。
  `%s` | char* | NULL終端の C の文字配列。
  `%p` | void* | C ポインタの16進表現。プラットフォームのprintfによらず、必ずリテラル `0x` が頭につくことが保証されるという以外、 `printf("%p")` とほぼ同じ。

  認識できない書式化文字があると書式化文字列の残りすべてがそのまま結果の文字列へコピーされ、余分の引数はどれも捨てられます。

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_SetFromErrnoWithFilename`(PyObject *type, const char *filename)
  Return value: Always NULL.

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

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

  これは `WindowsError` を発生させるために便利な関数です。 `0` の ierr とともに呼び出された場合、 `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。

  バージョン 2.3 で追加.

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

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

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

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

  バージョン 2.3 で追加.

void `PyErr_BadInternalCall`()

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

int `PyErr_WarnEx`(PyObject *category, char *message, int stacklevel)

  警告メッセージを出します。 category 引数は警告カテゴリ(以下を参照) かまたは NULL で、 message 引数はメッセージ文字列です。 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_Warning` は `PyExc_Exception` のサブクラスです。その他の警告カテゴリは `PyExc_Warning` のサブクラスです。

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

int `PyErr_Warn`(PyObject *category, char *message)

  警告メッセージを出します。 category 引数は警告カテゴリ(以下を参照) かまたは NULL で、 message 引数はメッセージ文字列です。警告は、 `PyErr_WarnEx()` を stacklevel に 1 を指定した時と同じく、 `PyErr_Warn()` を呼び出した関数から発行されます。

  非推奨; `PyErr_WarnEx()` を使って下さい。

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

  すべての警告の属性を明示的に制御した警告メッセージを出します。これはPython関数 `warnings.warn_explicit()` の直接的なラッパで、さらに情報を得るにはそちらを参照してください。そこに説明されているデフォルトの効果を得るために、 module と registry 引数は NULL に設定することができます。

int `PyErr_WarnPy3k`(char *message, int stacklevel)

  Issue a `DeprecationWarning` with the given message and stacklevel if the `Py_Py3kWarningFlag` flag is enabled. `Py_Py3kWarningFlag` フラグが有効な場合、与えられた message と stacklevel に応じて `DeprecationWarning` を発生させます。

  バージョン 2.6 で追加.

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)
  Return value: New reference.

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

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

void `PyErr_WriteUnraisable`(PyObject *obj)

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

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

## 再帰の管理

これら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 回呼び出さなければなりません。

## 標準例外

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

C名 | Python名 | 注記
--- | --- | ---
`PyExc_BaseException` | `BaseException` | (1), (4)
`PyExc_Exception` | `Exception` | (1)
`PyExc_StandardError` | `StandardError` | (1)
`PyExc_ArithmeticError` | `ArithmeticError` | (1)
`PyExc_LookupError` | `LookupError` | (1)
`PyExc_AssertionError` | `AssertionError` |
`PyExc_AttributeError` | `AttributeError` |
`PyExc_EOFError` | `EOFError` |
`PyExc_EnvironmentError` | `EnvironmentError` | (1)
`PyExc_FloatingPointError` | `FloatingPointError` |
`PyExc_IOError` | `IOError` |
`PyExc_ImportError` | `ImportError` |
`PyExc_IndexError` | `IndexError` |
`PyExc_KeyError` | `KeyError` |
`PyExc_KeyboardInterrupt` | `KeyboardInterrupt` |
`PyExc_MemoryError` | `MemoryError` |
`PyExc_NameError` | `NameError` |
`PyExc_NotImplementedError` | `NotImplementedError` |
`PyExc_OSError` | `OSError` |
`PyExc_OverflowError` | `OverflowError` |
`PyExc_ReferenceError` | `ReferenceError` | (2)
`PyExc_RuntimeError` | `RuntimeError` |
`PyExc_SyntaxError` | `SyntaxError` |
`PyExc_SystemError` | `SystemError` |
`PyExc_SystemExit` | `SystemExit` |
`PyExc_TypeError` | `TypeError` |
`PyExc_ValueError` | `ValueError` |
`PyExc_WindowsError` | `WindowsError` | (3)
`PyExc_ZeroDivisionError` | `ZeroDivisionError` |

注記:

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

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

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

4. バージョン 2.5 で追加.

## 文字列例外の廃止

Pythonへ組み込まれるすべての例外あるいは標準ライブラリに提供されている例外は、 `BaseException` から導出されています。

インタプリタで既存のコードが変更なしで動作するように、文字列例外は今でもサポートされています。しかし、これも将来のリリースで変更されるでしょう。

### ナビゲーション

- 索引
- モジュール |
- 次へ |
- 前へ |
- Python 2.6ja2 documentation »
- Python/C API リファレンスマニュアル »