4. 例外の取り扱い
この章で記述される関数は、あなたにPythonの例外を扱わせて、
そして例外を起こさせてくれる。Pythonの例外処理の基礎をいくつか
理解することが重要である。
それはいくぶんUnixのerrno変数のように働く:
起こった最後のエラーの(スレッドごとの)大域的な指示子がある。
たいていの関数は成功のときにこれを消さないが、
失敗のときにそれがエラーの原因を指すように設定する。
たいていの関数はまたエラーの指示子を返す。それは通常は、
関数がポインタを返すものとされているのであればNULL、
もしくは整数を返すのであれば-1である
(例外: PyArg_Parse*()関数は成功には1を、
失敗には0を返す)。
呼び出したいくつかの関数が失敗したために、ある関数が失敗しなければ
ならないときは、その関数は一般にエラーの指示子を設定しない。
それが呼び出した関数が既に設定しているからだ。
エラーの指示子は、
Python変数sys.exc_type, sys.exc_valueと
sys.exc_tracebackに対応する3つのPythonオブジェクトから
構成される。様々な方法でエラー指示子とやりとりするために
API関数が存在する。それぞれのスレッドに対して独立したエラー
指示子がある。
- void PyErr_Print ()
-
sys.stderrへ標準のトレースバックを表示して、エラー指示子を消す。
エラー指示子が設定されているときにだけこの関数を呼ぶこと
(さもなければ致命的なエラーをもたらすだろう)。
- PyObject* PyErr_Occurred ()
-
Return value:
Borrowed reference.
エラー指示子が設定されているか検査する。もし設定されていれば、
例外型(type)
(PyErr_Set*()関数の1つもしくはPyErr_Restore()
への最後の呼び出しに対する第1引数)を返す。
もし設定されていなければ、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がタプルであれば、
タプル中の例外全てについて(そしてサブタプルのなかを再帰的に)
合うものを検索される。
もしgivenがNULLであれば、メモリアクセス違反が起こるだろう。
- 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)
-
エラー指示子をアドレスを渡された3個の変数に取り出す。
もしエラー指示子が設定されていなければ、3個の変数全てを
NULLに設定する。もし指示子が設定されていれば、それは
取り除かれて、あなたは取り出したそれぞれのオブジェクトへの
参照を所有する。
型オブジェクトがNULLでないときでも、その値とトレースバック
オブジェクトはNULLであるかもしれない。
注意:
この関数は通常は例外を処理する必要があるコード、もしくは
エラー指示子を一時的に保存して元に戻す必要のあるコードに
使用されるだけである。
- void PyErr_Restore (PyObject *type, PyObject *value, PyObject *traceback)
-
3個のオブジェクトからエラー指示子を設定する。
もしエラー指示子が既に設定されていれば、初めにそれが取り除かれる。
もしオブジェクトがNULLであれば、エラー指示子は取り除かれる。
NULLのtypeとNULLでないvalueもしくはtracebackを渡さないこと。
例外の型(type)は文字列もしくはクラスであるべきである。
もしそれがクラスであれば、値(value)はそのクラスのインスタンスで
あるべきである。無効な例外の型(type)や値(value)を渡してはならない。
(これらの規則を破ると後でささいな問題を引き起こすだろう)。
この呼び出しによって、それぞれのオブジェクトへの参照は奪われる。
つまり、あなたは呼び出しの前にそれぞれのオブジェクトへの参照を
所有していなければならなく、そして呼び出しの後はもはやあなたは
これらの参照を所有していない
(もしあなたがこれを理解していないのであれば、この関数を
使ってはならない。注意しておく)。
注:この関数は、通常は
エラー指示子を一時的に保存して元に戻す必要のあるコードに
使用されるだけである。
- void PyErr_SetString (PyObject *type, char *message)
-
これはエラー指示子を設定する最も普通の方法である。
第1引数は例外の型を指定する。それは普通は標準例外の1つ、例えば
PyExc_RuntimeErrorである。その参照回数を増やす必要はない。
第2引数はエラーメッセージである。それは文字列オブジェクトに変換される。
- void PyErr_SetObject (PyObject *type, PyObject *value)
-
この関数はPyErr_SetString()に似ているが、
例外の``値(value)''として任意のPythonオブジェクトを指定させてくれる。
そのオブジェクトの参照回数を増やす必要はない。
- PyObject* PyErr_Format (PyObject *exception,
const char *format, ...)
-
Return value:
Always NULL.
この関数はprintf形式の書式文字列を使ってエラー指示子を設定する。
第1引数は例外の型を、第2引数は例外への書式文字列である。
後続のどの引数もC言語ライブラリのvsprintf()関数に
よって出力へと変換される。
PyErr_Format()によって内部的に使われるバッファは
500バイトの長さである。呼び出し側はフォーマットされた出力が
バッファをあふれないことを保証する責任がある。
- 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)"を
手早く書くためのものである。
この関数は、メモリを使い果したときに、オブジェクトを割り当てる
関数が"return PyErr_NoMemory();"と書くことができるよう
NULLを返す。
- PyObject* PyErr_SetFromErrno (PyObject *type)
-
Return value:
Always NULL.
これはCライブラリ関数の関数がエラーを返し、C言語の変数errnoを
設定したときに例外を起こすための、便宜的な関数である。
その関数は、1番目のアイテムが整数のerrnoの値で、
2番目のアイテムが
(strerror()から取得した)
対応するエラーメッセージであるタプルオブジェクトを構築して、
"PyErr_SetObject(type, object)"を呼び出す。
Unixでは、errnoの値が
中断されたシステムコールを意味するEINTRであるとき、
この関数はPyErr_CheckSignals()を呼び出す。
そして、もしその関数がエラー指示子を設定したのであれば、
エラー指示子をそれに設定したままにしておく。
この関数は常にNULLを返すので、システムコール周りのラッパー
関数は、システムコールがエラーを返したときに、
"return PyErr_SetFromErrno();"と書くことができる。
- void PyErr_BadInternalCall ()
-
これは"PyErr_SetString(PyExc_TypeError, message)"を
手早く書くためのものである。ここで、messageは
内部操作(例えばPython/C API関数など)が不正な引数とともに
起動されたことを示す。
たいていは内部で使用するためである。
- int PyErr_CheckSignals ()
-
この関数はPythonのシグナル処理と相互作用する。
それはプロセスにシグナルが送られたか検査して、もしそうであれば
対応するシグナルハンドラを起動する。
もしsignalモジュールが
利用可能であれば、この関数はPythonで書かれたシグナルハンドラを起動する
ことができる。全ての場合で、SIGINTに対する
デフォルトの結果は、
KeyboardInterrupt例外を起こすことである。
もし例外が起こされたら、エラー指示子が設定されて、その関数は
1を返す。
そうでなければ関数は0を返す。もしエラー指示子が以前に設定された場合、
それは取り消されるかもしれないし、取り消されないかもしれない。
- void PyErr_SetInterrupt ()
-
この関数は廃止予定である。
これはSIGINTシグナルが到着した影響を
シミュレートする --
次にPyErr_CheckSignals()が呼び出されたときに、
KeyboardInterruptが起こされる。
この関数はインタープリタのロックを保持せずに呼び出されてもよい。
- 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引数はクラスの変数とメソッドの辞書を指定するために
使うことができる。
Subsections