例外処理
********

この章で説明する関数を使うと、 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)

   標準のトレースバックを "sys.stderr" に出力し、エラーインジケータを
   クリアします。 ただし、エラーが "SystemExit" **である場合を除いて**
   です。 その場合、トレースバックは出力されず、 Python プロセスは
   "SystemExit" インスタンスで指定されたエラーコードで終了します。

   エラーインジケータが設定されているときに **だけ**、この関数を呼び出
   してください。 それ以外の場合、致命的なエラーを引き起こすでしょう!

   *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()" に似ていますが、 *filenameObject* が *NULL*
   でない場合に、 *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" を発生させるために便利な関数です。 "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。

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* は例外のメッセ
   ージ文字列としてセットされます。 *name* と *path* はどちらも "NULL"
   にしてよく、それぞれ "ImportError" の "name" 属性と "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_Warning" は "PyExc_Exception" のサブクラスです。 デフォルト
   の警告カテゴリは "PyExc_RuntimeWarning" です。 標準の Python 警告カ
   テゴリは、 標準警告カテゴリ で名前が列挙されているグローバル変数と
   して利用可能です。

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

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

   "PyErr_SetImportError()" とよく似ていますが、この関数は送出する例外
   として、 "ImportError" のサブクラスを指定できます。

   バージョン 3.6 で追加.

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)

   "PyErr_WarnExplicitObject()" に似ていますが、 *message* と *module*
   が 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 で追加.

int PyErr_ResourceWarning(PyObject *source, Py_ssize_t stack_level, const char *format, ...)

   "PyErr_WarnFormat()" に似た関数で、*category* は "ResourceWarning"
   であり、 *source* は "warnings.WarningMessage()" に渡されます。

   バージョン 3.6 で追加.


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

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_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文字列でなけれ
   ばならない。 *base* と *dict* 引数は通常 *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 を設定できます。 *doc* が *NULL* で無い場合、それが例外ク
   ラスの 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* に格納
   します。*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)

   渡された例外オブジェクトの *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* に格納しま
   す。*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)

   渡された例外オブジェクトの *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_ModuleNotFoundError"               | "ModuleNotFoundError"             |            |
+-------------------------------------------+-----------------------------------+------------+
| "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_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名                                   | 注釈       |
|=======================================|============|
| "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. これは別の標準警告カテゴリのためのベースクラスです。
