新スタイルの型を定義する構造体: PyTypeObject 構造体は、おそらく Python オブジェクトシステムの中で最も重要な構造体の1つでしょう。型オブジェクトは PyObject_*() 系や PyType_*() 系の関数で扱えますが、ほとんどの Python アプリケーションにとって、さして面白みのある機能を提供しません。 型オブジェクトはオブジェクトがどのように振舞うかを決める基盤ですから、 インタプリタ自体や新たな型を定義する拡張モジュールでは非常に重要な存在です。
型オブジェクトは標準の型 (standard type) に比べるとかなり大きな構造体です。 各型オブジェクトは多くの値を保持しており、そのほとんどは C 関数へのポインタで、 それぞれの関数はその型の機能の小さい部分を実装しています。 この節では、型オブジェクトの各フィールドについて詳細を説明します。 各フィールドは、構造体内で出現する順番に説明されています。
Typedefs: unaryfunc, binaryfunc, ternaryfunc, inquiry, coercion, intargfunc, intintargfunc, intobjargproc, intintobjargproc, objobjargproc, destructor, freefunc, printfunc, getattrfunc, getattrofunc, setattrfunc, setattrofunc, cmpfunc, reprfunc, hashfunc
PyTypeObject の構造体定義は Include/object.h で見つけられるはずです。参照の手間を省くために、ここでは定義を繰り返します:
typedef struct _typeobject {
PyObject_VAR_HEAD
char *tp_name; /* For printing, in format "<module>.<name>" */
int tp_basicsize, tp_itemsize; /* For allocation */
/* Methods to implement standard operations */
destructor tp_dealloc;
printfunc tp_print;
getattrfunc tp_getattr;
setattrfunc tp_setattr;
cmpfunc tp_compare;
reprfunc tp_repr;
/* Method suites for standard classes */
PyNumberMethods *tp_as_number;
PySequenceMethods *tp_as_sequence;
PyMappingMethods *tp_as_mapping;
/* More standard operations (here for binary compatibility) */
hashfunc tp_hash;
ternaryfunc tp_call;
reprfunc tp_str;
getattrofunc tp_getattro;
setattrofunc tp_setattro;
/* Functions to access object as input/output buffer */
PyBufferProcs *tp_as_buffer;
/* Flags to define presence of optional/expanded features */
long tp_flags;
char *tp_doc; /* Documentation string */
/* Assigned meaning in release 2.0 */
/* call function for all accessible objects */
traverseproc tp_traverse;
/* delete references to contained objects */
inquiry tp_clear;
/* Assigned meaning in release 2.1 */
/* rich comparisons */
richcmpfunc tp_richcompare;
/* weak reference enabler */
long tp_weaklistoffset;
/* Added in release 2.2 */
/* Iterators */
getiterfunc tp_iter;
iternextfunc tp_iternext;
/* Attribute descriptor and subclassing stuff */
struct PyMethodDef *tp_methods;
struct PyMemberDef *tp_members;
struct PyGetSetDef *tp_getset;
struct _typeobject *tp_base;
PyObject *tp_dict;
descrgetfunc tp_descr_get;
descrsetfunc tp_descr_set;
long tp_dictoffset;
initproc tp_init;
allocfunc tp_alloc;
newfunc tp_new;
freefunc tp_free; /* Low-level free-memory routine */
inquiry tp_is_gc; /* For PyObject_IS_GC */
PyObject *tp_bases;
PyObject *tp_mro; /* method resolution order */
PyObject *tp_cache;
PyObject *tp_subclasses;
PyObject *tp_weaklist;
} PyTypeObject;
型オブジェクト構造体は PyVarObject 構造体を拡張したものです。 ob_size フィールドは、(通常 class 文が呼び出す type_new() で生成される) 動的な型に使います。 PyType_Type (メタタイプ) は tp_itemsize を初期化するので注意してください。すなわち、 インスタンス (つまり型オブジェクト) には ob_size フィールドがなければ なりません 。
これらのフィールドはマクロ Py_TRACE_REFS が定義されている場合のみ 存在します。 PyObject_HEAD_INIT マクロを使うと、フィールドを NULL に初期化します。静的にメモリ確保されているオブジェクトでは、これらの フィールドは常に NULL のままです。動的にメモリ確保されるオブジェクトの 場合、これら二つのフィールドは、ヒープ上の 全ての 存続中のオブジェクト からなる二重リンクリストでオブジェクトをリンクする際に使われます。 このことは様々なデバッグ目的に利用できます; 現状では、環境変数 PYTHONDUMPREFS が設定されているときに、プログラムの実行終了時点で 存続しているオブジェクトを出力するのが唯一の用例です。
サブタイプはこのフィールドを継承しません。
型オブジェクトの参照カウントで、 PyObject_HEAD_INIT はこの値を 1 に初期化します。静的にメモリ確保された型オブジェクトでは、型のインスタンス (ob_type が該当する型を指しているオブジェクト) は参照をカウントする 対象には なりません 。 動的にメモリ確保される型オブジェクトの場合、インスタンスは参照カウントの 対象に なります 。
サブタイプはこのフィールドを継承しません。
バージョン 2.5 で変更: このフィールドは以前は int でした。 この変更により、 64bit システムを正しくサポートするには修正が必要になります。
型自体の型、別の言い方をするとメタタイプです。 PyObject_HEAD_INIT マクロで初期化され、通常は &PyType_Type になります。しかし、(少なくとも) Windows で利用できる動的ロード可能な拡張モジュールでは、コンパイラは 有効な初期化ではないと文句をつけます。そこで、ならわしとして、 PyObject_HEAD_INIT には NULL を渡して初期化しておき、 他の操作を行う前にモジュールの初期化関数で明示的にこのフィールドを初期化することになっています。この操作は以下のように行います:
Foo_Type.ob_type = &PyType_Type;
上の操作は、該当する型のいかなるインスタンス生成よりも前にしておかねばなりません。 PyType_Ready() は ob_type が NULL かどうか調べ、 NULL の場合には初期化します: Python 2.2 では、 &PyType_Type にセットします; in Python 2.2.1 およびそれ以降では基底クラスの ob_type フィールドに初期化します。 ob_type が非ゼロの場合、 PyType_Ready() はこのフィールドを変更しません。
Python 2.2 では、サブタイプはこのフィールドを継承しません。 2.2.1 と 2.3 以降では、サブタイプはこのフィールドを継承します。
静的にメモリ確保されている型オブジェクトの場合、このフィールドはゼロに初期化されます。動的にメモリ確保されている型オブジェクトの 場合、このフィールドは内部使用される特殊な意味を持ちます。
サブタイプはこのフィールドを継承しません。
型の名前が入っている NUL 終端された文字列へのポインタです。モジュールのグローバル変数としてアクセスできる型の場合、 この文字列は完全なモジュール名、ドット、そして型の名前と続く文字列になります; 組み込み型の場合、ただの型の名前です。 モジュールがあるパッケージのサブモジュールの場合、完全なパッケージ名が完全なモジュール名の一部になっています。例えば、パッケージ P 内のサブモジュール Q に入っているモジュール M 内で定義されている T は、 tp_name を "P.Q.M.T" に初期化します。
動的にメモリ確保される型オブジェクトの場合、このフィールドは単に型の名前になり、モジュール名は型の辞書内でキー '__module__' に対する値として明示的に保存されます。
静的にメモリ確保される型オブジェクトの場合、 tp_name フィールドにはドットが入っているはずです。最後のドットよりも前にある 部分文字列全体は __module__ 属性として、またドットよりも後ろにある部分は __name__ 属性としてアクセスできます。
ドットが入っていない場合、 tp_name フィールドの内容全てが __name__ 属性になり、 __module__ 属性は (前述のように型の辞書内で明示的にセットしないかぎり) 未定義になります。このため、こうした型オブジェクトは pickle 化できないことになります。
サブタイプはこのフィールドを継承しません。
これらのフィールドは、型インスタンスのバイトサイズを計算できるようにします。
型には二つの種類があります: 固定長インスタンスの型は、 tp_itemsize フィールドがゼロで、可変長インスタンスの方は tp_itemsize フィールドが非ゼロの値になります。固定長インスタンスの型の場合、全てのインスタンスは等しく tp_basicsize で与えられたサイズになります。
可変長インスタンスの型の場合、インスタンスには ob_size フィールドがなくてはならず、インスタンスのサイズは N をオブジェクトの “長さ” として、 tp_basicsize と N かける tp_itemsize の加算になります。N の値は通常、インスタンスの ob_size フィールドに記憶されます。ただし例外がいくつかあります: 例えば、長整数では負の値を ob_size に使って、インスタンスの表す値が負であることを示し、 N 自体は abs(ob_size) になります。また、 ob_size フィールドがあるからといって、必ずしもインスタンスが可変長であることを意味しません (例えば、 リスト型の構造体は固定長のインスタンスになるにもかかわらず、インスタンスにはちゃんと意味を持った ob_size フィールドがあります)。
基本サイズには、 PyObject_HEAD マクロまたは PyObject_VAR_HEAD マクロ (インスタンス構造体を宣言するのに使ったどちらかのマクロ) で宣言されているフィールドが入っています。さらに、 _ob_prev および _ob_next フィールドがある場合、これらのフィールドもサイズに加算されます。
従って、 tp_basicsize の正しい初期化パラメタを得るには、インスタンスデータのレイアウトを宣言するのに使う構造体に対して sizeof 演算子を使うしかありません。基本サイズには、GC ヘッダサイズは入っていません (これは Python 2.2 からの新しい仕様です; 2.1 や 2.0 では、GC ヘッダサイズは tp_basicsize に入っていました)。
これらのフィールドはサブタイプに別々に継承されます。 基底タイプが 0 でない tp_itemsize を持っていた場合、基底タイプの実装に依存しますが、 一般的にはサブタイプで別の 0 で無い値を tp_itemsize に設定するのは安全ではありません。
バイト整列 (alignment) に関する注釈: 変数の各要素を配置する際に特定のバイト整列が必要となる場合、 tp_basicsize の値に気をつけなければなりません。一例: 例えばある型が double の配列を実装しているとします。 tp_itemsize は sizeof(double) です。(double のバイト整列条件に従って) tp_basicsize が sizeof(double) の個数分のサイズになるようにするのはプログラマの責任です。
インスタンスのデストラクタ関数へのポインタです。この関数は (単量子 None や Ellipsis の場合のように) インスタンスが決してメモリ解放されない型で ない限り必ず定義しなければなりません。
デストラクタ関数は、 Py_DECREF() や Py_XDECREF() マクロで、 操作後の参照カウントがゼロになった際に呼び出されます。呼び出された時点では、 インスタンスはまだ存在しますが、インスタンスに対する参照は全くない状態です。 デストラクタ関数はインスタンスが保持している全ての参照を解放し、 インスタンスが確保している全てのメモリバッファを (バッファの確保時に使った 関数に対応するメモリ解放関数を使って) 解放し、最後に (かならず最後に行う 操作として) その型の tp_free 関数を呼び出します。 ある型がサブタイプを作成できない (Py_TPFLAGS_BASETYPE フラグがセットされていない) 場合、 tp_free の代わりにオブジェクトの メモリ解放関数 (deallocator) を直接呼び出してもかまいません。オブジェクトの メモリ解放関数は、インスタンスのメモリ確保を行う際に使った関数と同じ ファミリでなければなりません; インスタンスを PyObject_New() や PyObject_VarNew() でメモリ 確保した場合には、通常 PyObject_Del() を使い、 PyObject_GC_New() や PyObject_GC_NewVar() で確保した場合には PyObject_GC_Del() を使います。
サブタイプはこのフィールドを継承します。
オプションのフィールドで、インスタンスの出力 (print) を行う関数を 指すポインタです。
出力関数は、インスタンスが 実体のある (real) ファイルに出力される場合に のみ呼び出されます; (StringIO インスタンスのような) 擬似ファイルに 出力される場合には、インスタンスの tp_repr や tp_str が指す 関数が呼び出され、文字列への変換を行います。 また、 tp_print が NULL の場合にもこれらの関数が呼び出されます。 tp_repr や tp_str と異なる出力を生成するような tp_print は、決して型に実装してはなりません。
出力関数は PyObject_Print() と同じシグネチャ: int tp_print(PyObject *self, FILE *file, int flags) で呼び出されます。 self 引数は出力するインスタンスを指します。 file 引数は出力先となる標準入出力 (stdio) ファイルです。 flags 引数はフラグビットを組み合わせた値です。 現在定義されているフラグビットは Py_PRINT_RAW のみです。 Py_PRINT_RAW フラグビットがセットされていれば、 インスタンスは tp_str と同じ書式で出力されます。 Py_PRINT_RAW フラグビットがクリアならば、インスタンスは tp_repr と同じ書式で出力されます。この関数は、操作中にエラーが生じた場合、 -1 を返して例外状態をセットしなければなりません。
tp_print フィールドは撤廃されるかもしれません。いずれにせよ、 tp_print は定義せず、代わりに tp_repr や tp_str に頼って出力を行うようにしてください。
サブタイプはこのフィールドを継承します。
オプションのフィールドです。ポインタで、 get-attribute-string を行う関数を指します。
このフィールドは撤廃されています。このフィールドを定義する場合、 tp_getattro 関数と同じように動作し、属性名は Python 文字列 オブジェクトではなく C 文字列で指定するような関数を指すようにしなければなりません。シグネチャは PyObject_GetAttrString() と同じです。
このフィールドは tp_getattro と共にサブタイプに継承されます: すなわち、サブタイプの tp_getattr および tp_getattro が共に NULL の場合、サブタイプは基底タイプから tp_getattr と tp_getattro を一緒に継承します。
オプションのフィールドです。ポインタで、 set-attribute-string を行う関数を指します。
このフィールドは撤廃されています。このフィールドを定義する場合、 tp_setattro 関数と同じように動作し、属性名は Python 文字列 オブジェクトではなく C 文字列で指定するような関数を指すようにしなければなりません。シグネチャは PyObject_SetAttrString() と同じです。
このフィールドは tp_setattro と共にサブタイプに継承されます: すなわち、サブタイプの tp_setattr および tp_setattro が共に NULL の場合、サブタイプは基底タイプから tp_setattr と tp_setattro を一緒に継承します。
オプションのフィールドです。ポインタで、三値比較 (three-way comparison) を行う関数を指します。
シグネチャは PyObject_Compare() と同じです。この関数は self が other よりも大きければ 1, self と other の値が等しければ 0, self が other より小さければ -1 を返します。 この関数は、比較操作中にエラーが生じた場合、例外状態をセットして -1 を返さねばなりません。
このフィールドは tp_richcompare および tp_hash と共にサブタイプに継承されます: すなわち、サブタイプの tp_compare, tp_richcompare および tp_hash が共に NULL の場合、サブタイプは基底タイプから tp_compare, tp_richcompare, tp_hash の三つを一緒に継承します。
オプションのフィールドです。ポインタで、組み込み関数 repr() を実装している関数を指します。
シグネチャは PyObject_Repr() と同じです。この関数は文字列オブジェクトか Unicode オブジェクトを返さねば なりません。理想的には、この関数が返す文字列は、適切な環境で eval() に渡した場合、同じ値を持つオブジェクトになるような 文字列でなければなりません。不可能な場合には、オブジェクトの型と値から導出した内容の入った '<' から始まって '>' で終わる文字列を返さねばなりません。
このフィールドが設定されていない場合、 <%s object at %p> の形式をとる文字列が返されます。 %s は型の名前に、 %p はオブジェクトのメモリアドレスに置き換えられます。
サブタイプはこのフィールドを継承します。
数値プロトコルを実装した追加の構造体を指すポインタです。 これらのフィールドについては 数値オブジェクト構造体 で説明されています。
tp_as_number フィールドは継承されませんが、そこの含まれるフィールドが 個別に継承されます。
シーケンスプロトコルを実装した追加の構造体を指すポインタです。 これらのフィールドについては シーケンスオブジェクト構造体 で説明されています。
tp_as_sequence フィールドは継承されませんが、そこの含まれるフィールドが 個別に継承されます。
マッピングプロトコルを実装した追加の構造体を指すポインタです。 これらのフィールドについては マップ型オブジェクト構造体 で説明されています。
tp_as_mapping フィールドは継承されませんが、そこの含まれるフィールドが 個別に継承されます。
オプションのフィールドです。ポインタで、組み込み関数 hash() を実装している関数を指します。
シグネチャは PyObject_Hash() と同じです。この関数は C の long 型の値を返さねばなりません。通常時には -1 を戻り値にしてはなりません; ハッシュ値の計算中にエラーが生じた場合、 関数は例外をセットして -1 を返さねばなりません。
このフィールドは明示的に PyObject_HashNotImplemented() に設定することで、 親 type からのハッシュメソッドの継承をブロックすることができます。 これは Python レベルでの __hash__ = None と同等に解釈され、 isinstance(o, collections.Hashable) が正しく False を返すようになります。 逆もまた可能であることに注意してください - Python レベルで __hash__ = None を設定することで tp_hash スロットは PyObject_HashNotImplemented() に設定されます。
このフィールドが設定されていない場合、二つの可能性があります: tp_compare および tp_richcompare フィールドの両方が NULL の場合、オブジェクトのアドレスに基づいたデフォルトのハッシュ値が返されます; それ以外の場合、 TypeError が送出されます。
このフィールドは tp_compare および tp_richcompare と共にサブタイプに継承されます: すなわち、サブタイプの tp_compare, tp_richcompare および tp_hash が共に NULL の場合、サブタイプは基底タイプから tp_compare, tp_richcompare, tp_hash の三つを一緒に継承します。
オプションのフィールドです。ポインタで、オブジェクトの呼び出しを実装している 関数を指します。オブジェクトが呼び出し可能でない場合には NULL にしなければなりません。シグネチャは PyObject_Call() と同じです。
サブタイプはこのフィールドを継承します。
オプションのフィールドです。ポインタで、組み込みの演算 str() を実装している関数を指します。(str が型の一つになったため、 str() は str のコンストラクタを呼び出す ことに注意してください。このコンストラクタは実際の処理を行う上で PyObject_Str() を呼び出し、さらに PyObject_Str() がこのハンドラを呼び出すことになります。)
シグネチャは PyObject_Str() と同じです; この関数は文字列オブジェクトか Unicode オブジェクトを返さねばなりません。 また、この関数はオブジェクトを “分かりやすく (friendly)” 表現した文字列を返さねばなりません。というのは、この文字列は print 文で使われることになる表記だからです。
このフィールドが設定されていない場合、文字列表現を返すためには PyObject_Repr() が呼び出されます。
サブタイプはこのフィールドを継承します。
オプションのフィールドです。ポインタで、 get-attribute を実装している関数を指します。
シグネチャは PyObject_GetAttr() と同じです。 対する通常の属性検索を実装している PyObject_GenericGetAttr() をこのフィールドに設定しておくと往々にして便利です。
このフィールドは tp_getattr と共にサブタイプに継承されます: すなわち、サブタイプの tp_getattr および tp_getattro が共に NULL の場合、サブタイプは基底タイプから tp_getattr と tp_getattro を一緒に継承します。
オプションのフィールドです。ポインタで、 set-attribute を行う関数を指します。
シグネチャは PyObject_SetAttr() と同じです。 対する通常の属性設定を実装している PyObject_GenericSetAttr() をこのフィールドに設定しておくと往々にして便利です。
このフィールドは tp_setattr と共にサブタイプに継承されます: すなわち、サブタイプの tp_setattr および tp_setattro が共に NULL の場合、サブタイプは基底タイプから tp_setattr と tp_setattro を一緒に継承します。
バッファインタフェースを実装しているオブジェクトにのみ関連する、 一連のフィールド群が入った別の構造体を指すポインタです。 構造体内の各フィールドは バッファオブジェクト構造体 (buffer object structure) で説明します。
tp_as_buffer フィールド自体は継承されませんが、 フィールド内に入っているフィールドは個別に継承されます。
このフィールドは様々なフラグからなるビットマスクです。いくつかのフラグは、 特定の状況において変則的なセマンティクスが適用されることを示します; その他のフラグは、型オブジェクト (あるいは tp_as_number, tp_as_sequence, tp_as_mapping,および tp_as_buffer が参照している拡張機能構造体: extention structure) の特定のフィールドのうち、 過去から現在までずっと存在しているわけではないものが有効になっていることを示すために使われます; フラグビットがクリアであれば、フラグが保護しているフィールドにはアクセスしない代わりに、その値はゼロか NULL になっているとみなさなければなりません。
このフィールドの継承は複雑です。ほとんどのフラグビットは個別に継承されます。つまり、基底タイプであるフラグビットがセット されている場合、サブタイプはそのフラグビットを継承します。機能拡張のための構造体に関するフラグビットは、その機能拡張構造体 が継承されるときに限定して継承されます。すなわち、基底タイプのフラグビットの値は、機能拡張構造体へのポインタと一緒にサブタイプにコピーされます。 Py_TPFLAGS_HAVE_GC フラグビットは、 tp_traverse および tp_clear フィールドと合わせてコピーされます。すなわち、サブタイプの Py_TPFLAGS_HAVE_GC フラグビットがクリアで、かつ (Py_TPFLAGS_HAVE_RICHCOMPARE フラグビットの指定によって) tp_traverse および tp_clear フィールドがサブタイプ内に存在しており、かつ値が NULL の場合に基底タイプから値を継承します。
以下のビットマスクは現在定義されているものです; フラグは | 演算子で論理和を取って tp_flags フィールドの値にできます。 PyType_HasFeature() マクロは型とフラグ値、 tp および f をとり、 tp->tp_flags & f が非ゼロかどうか調べます。
このビットがセットされていれば、 tp_as_buffer が参照する PyBufferProcs 構造体には bf_getcharbuffer フィールドがあります。
このビットがセットされていれば、 tp_as_sequence が参照する PySequenceMethods 構造体には sq_contains フィールドがあります。
このビットは旧式のものです。このシンボルが指し示していたビットはもはや 使われていません。シンボルの現在の定義はゼロになっています。
このビットがセットされていれば、 tp_as_sequence が参照する PySequenceMethods 構造体、および tp_as_number が参照する PyNumberMethods 構造体には in-place 演算に関するフィールドが入っています。具体的に言うと、 PyNumberMethods 構造体はフィールド nb_inplace_add, nb_inplace_subtract, nb_inplace_multiply, nb_inplace_divide, nb_inplace_remainder, nb_inplace_power, nb_inplace_lshift, nb_inplace_rshift, nb_inplace_and, nb_inplace_xor,および nb_inplace_or を持つことになります; また、 PySequenceMethods 構造体はフィールド sq_inplace_concat および sq_inplace_repeat を持つことになります。
このビットがセットされていれば、 tp_as_number が参照する PyNumberMethods 構造体内で定義されている二項演算子および三項演算子は任意のオブジェクト型を非演算子にとるようになり、 必要に応じて引数の型変換を行います。このビットがクリアなら、演算子は全ての引数が現在のオブジェクト型と同じであるよう要求し、 演算の呼び出し側は演算に先立って型変換を行うものと想定します。対象となる演算子は nb_add, nb_subtract, nb_multiply, nb_divide, nb_remainder, nb_divmod, nb_power, nb_lshift, nb_rshift, nb_and, nb_xor,および nb_or です。
このビットがセットされていれば、型オブジェクトには tp_richcompare フィールド、そして tp_traverse および tp_clear フィールドがあります。
このビットがセットされていれば、構造体には tp_weaklistoffset フィールドが定義されています。 tp_weaklistoffset フィールドの 値がゼロより大きければ、この型のインスタンスは弱参照で参照できます。
このビットがセットされていれば、型オブジェクトには tp_iter および tp_iternext フィールドがあります。
このビットがセットされていれば、型オブジェクトは Python 2.2 以降で定義されている新たなフィールド: tp_methods, tp_members, tp_getset, tp_base, tp_dict, tp_descr_get, tp_descr_set, tp_dictoffset, tp_init, tp_alloc, tp_new, tp_free, tp_is_gc, tp_bases, tp_mro, tp_cache, tp_subclasses,および tp_weaklist があります。
型オブジェクト自体がヒープにメモリ確保される場合にセットされるビットです。型オブジェクト自体がヒープにメモリ確保される場合、インスタンスの ob_type フィールドは型オブジェクトへの参照とみなされます。この場合、新たなインスタンスを生成する度に型オブジェクトを INCREF し、インスタンスを解放するたびに DECREF します (サブタイプのインスタンスには適当されません; インスタンスが ob_type で参照している型だけが INCREF および DECREF されます)。
型を別の型の基底タイプとして使える場合にセットされるビットです。このビットがクリアならば、この型のサブタイプは生成できません (Java における “final” クラスに似たクラスになります)。
型オブジェクトが PyType_Ready() で完全に初期化されるとセットされるビットです。
PyType_Ready() による型オブジェクトの初期化処理中にセットされるビットです。
オブジェクトがガベージコレクション (GC) をサポートする場合にセットされるビットです。 このビットがセットされている場合、インスタンスは PyObject_GC_New() を使って生成し、 PyObject_GC_Del() を使って破壊しなければなりません。 詳しい情報は 循環参照ガベージコレクションをサポートする にあります。 このビットはまた、GC に関連するフィールド tp_traverse および tp_clear が型オブジェクト内に存在することを示します; しかし、これらのフィールドは Py_TPFLAGS_HAVE_GC がクリアでも Py_TPFLAGS_HAVE_RICHCOMPARE がセットされている場合には存在します。
型オブジェクトおよび拡張機能構造体の特定のフィールドの存在の有無に関連する全てのビットからなるビットマスクです。現状では、このビットマスクには以下のビット: Py_TPFLAGS_HAVE_GETCHARBUFFER, Py_TPFLAGS_HAVE_SEQUENCE_IN, Py_TPFLAGS_HAVE_INPLACEOPS, Py_TPFLAGS_HAVE_RICHCOMPARE, Py_TPFLAGS_HAVE_WEAKREFS, Py_TPFLAGS_HAVE_ITER,および Py_TPFLAGS_HAVE_CLASS が入っています。
オプションのフィールドです。ポインタで、この型オブジェクトの docstring を与える NUL 終端された C の文字列を指します。 この値は型オブジェクトと型のインスタンスにおける __doc__ 属性として公開されます。
サブタイプはこのフィールドを継承 しません 。
以下の三つのフィールドは、 Py_TPFLAGS_HAVE_RICHCOMPARE フラグビットがセットされている場合にのみ存在します。
オプションのフィールドです。ポインタで、ガベージコレクタのためのトラバーサル関数 (traversal function) を指します。 Py_TPFLAGS_HAVE_GC がセットされている 場合にのみ使われます。Pythonのガベージコレクションの枠組みに関する詳細は 循環参照ガベージコレクションをサポートする にあります。
tp_traverse ポインタは、ガベージコレクタが循環参照を見つけるために使われます。 tp_traverse 関数の典型的な実装は、インスタンスの各メンバのうち Pythonオブジェクトに対して Py_VISIT() を呼び出します。例えば、次のコードは thread 拡張モジュールの local_traverse() 関数になります:
static int
local_traverse(localobject *self, visitproc visit, void *arg)
{
Py_VISIT(self->args);
Py_VISIT(self->kw);
Py_VISIT(self->dict);
return 0;
}
Py_VISIT() が循環参照になる恐れのあるメンバにだけ呼び出されていることに注目してください。 self->key メンバもありますが、それは NULL か Python文字列なので、循環参照の一部になることはありません。
一方、メンバが循環参照の一部になり得ないと判っていても、デバッグ目的で巡回したい場合があるかもしれないので、 gc モジュールの get_reference() 関数は循環参照になり得ないメンバも返します。
Py_VISIT() は local_traverse() が visit と arg という決まった名前の引数を持つことを要求します。
このフィールドは tp_clear および Py_TPFLAGS_HAVE_GC フラグビットと一緒に継承されます: フラグビット、 tp_traverse,および tp_clear の値がサブタイプで全てゼロになっており、 かつ サブタイプで Py_TPFLAGS_HAVE_RICHCOMPARE フラグビットがセットされている場合に、基底タイプから値を継承します。
オプションのフィールドです。ポインタで、ガベージコレクタにおける消去関数 (clear function) を指します。 Py_TPFLAGS_HAVE_GC がセットされている場合にのみ使われます。
tp_clear メンバ関数はGCが見つけた循環しているゴミの循環参照を壊すために用いられます。システム内の全ての tp_clear 関数によって、全ての循環参照を破壊しなければなりません。 (訳注: ある型が tp_clear を実装しなくても全ての循環参照が破壊できるのであれば実装しなくても良い) これはとても繊細で、もし少しでも不確かな部分があるのであれば、 tp_clear 関数を提供するべきです。 例えば、タプルは tp_clear を実装しません。なぜなら、タプルだけで構成された循環参照がみつかることは無いからです。 したがって、タプル以外の型 tp_clear 関数たちが、タプルを含むどんな循環参照も破壊できる必要があります。 これは簡単に判ることでははありません。 tp_clear の実装を避ける良い理由はめったにありません。
tp_clear の実装は、次の実装のように、インスタンスの (Pythonオブジェクト)メンバに対する参照を捨てて、メンバに対するポインタ変数を NULL にセットするべきです:
static int
local_clear(localobject *self)
{
Py_CLEAR(self->key);
Py_CLEAR(self->args);
Py_CLEAR(self->kw);
Py_CLEAR(self->dict);
return 0;
}
参照のクリアはデリケートなので、 Py_CLEAR() マクロを使うべきです: ポインタを NULL にセットするまで、そのオブジェクトの参照カウントをデクリメントしてはいけません。 参照カウントのデクリメントすると、そのオブジェクトが破棄されるかもしれず、 (そのオブジェクトに関連付けられたファイナライザ、弱参照のコールバックにより) 任意のPythonコードの実行を含む後片付け処理が実行されるかもしれないからです。もしそういったコードが再び self を参照することがあれば、すでに 持っていたオブジェクトへのポインタは NULL になっているので、 self は所有していたオブジェクトをもう利用できないことを認識できます。 Py_CLEAR() マクロはその手続きを安全な順番で実行します。
tp_clear 関数の目的は参照カウントを破壊することなので、Python文字列や Python整数のような、循環参照になりえないオブジェクトをクリアする必要はありません。一方、全部の所有オブジェクトをクリアするようにし、 tp_dealloc 関数が tp_clear 関数を実行するようにすると実装が楽です。
Pythonのガベージコレクションの仕組みについての詳細は、 循環参照ガベージコレクションをサポートする にあります。
このフィールドは tp_traverse および Py_TPFLAGS_HAVE_GC フラグビットと一緒に継承されます: フラグビット、 tp_traverse,および tp_clear の値がサブタイプで全てゼロになっており、 かつ サブタイプで Py_TPFLAGS_HAVE_RICHCOMPARE フラグビットがセットされている場合に、基底タイプから値を継承します。
オプションのフィールドで、拡張比較関数 (rich comparison function) を指すポインタです。拡張比較関数のシグネチャは PyObject *tp_richcompare(PyObject *a, PyObject *b, int op) です。
この関数は、比較結果を返すべきです。(普通は Py_True か Py_False です。) 比較が未定義の場合は、 Py_NotImplemented を、それ以外のエラーが 発生した場合には例外状態をセットして NULL を返さねばなりません。
ノート
限られた種類の比較だけが可能 (例えば、 == と != が可能で < などが不可能) な型を実装したい場合、拡張比較関数で直接 TypeError を返します。
このフィールドは tp_compare および tp_hash と共にサブタイプに継承されます: すなわち、サブタイプの tp_compare, tp_richcompare および tp_hash が共に NULL の場合、サブタイプは基底タイプから tp_compare, tp_richcompare, tp_hash の三つを一緒に継承します。
tp_richcompare および PyObject_RichCompare() 関数の第三引数に使うための定数としては以下が定義されています:
定数 | 比較 |
---|---|
Py_LT | < |
Py_LE | <= |
Py_EQ | == |
Py_NE | != |
Py_GT | > |
Py_GE | >= |
次のフィールドは、 Py_TPFLAGS_HAVE_WEAKREFS フラグビットがセットされている場合にのみ存在します。
型のインスタンスが弱参照可能な場合、このフィールドはゼロよりも大きな数になり、 インスタンス構造体における弱参照リストの先頭を示すオフセットが入ります (GC ヘッダがある場合には無視します); このオフセット値は PyObject_ClearWeakRefs() および PyWeakref_*() 関数が利用します。インスタンス構造体には、 NULL に初期化された PyObject* 型の フィールドが入っていなければなりません。
このフィールドを tp_weaklist と混同しないようにしてください; tp_weaklist は型オブジェクト自体の弱参照リストの先頭です。
サブタイプはこのフィールドを継承しますが、以下の規則があるので読んでください。サブタイプはこのオフセット値をオーバライドできます; 従って、 サブタイプでは弱参照リストの先頭が基底タイプとは異なる場合があります。リストの先頭は常に tp_weaklistoffset で 分かるはずなので、このことは問題にはならないはずです。
class 文で定義された型に __slots__ 宣言が全くなく、かつ基底タイプが弱参照可能でない場合、 その型を弱参照可能にするには弱参照リストの先頭を表すスロットをインスタンスデータレイアウト構造体に追加し、スロットのオフセットを tp_weaklistoffset に設定します。
型の __slots__ 宣言中に __weakref__ という名前の スロットが入っている場合、スロットはその型のインスタンスにおける弱参照リストの先頭を表すスロットになり、スロットのオフセットが型の tp_weaklistoffset に入ります。
型の __slots__ 宣言に __weakref__ という名のスロット が入っていない場合、その型は基底タイプから tp_weaklistoffset を継承します。
次の二つのフィールドは、 Py_TPFLAGS_HAVE_ITER フラグビットがセットされている場合にのみ存在します。
オプションの変数で、そのオブジェクトのイテレータを返す関数へのポインタです。 この値が存在することは、通常この型のインスタンスがイテレート可能であることを 示しています。(しかし、シーケンスはこの関数がなくてもイテレート可能ですし、 旧スタイルクラスのインスタンスは __iter__() メソッドを定義していなくても この関数を持っています)
この関数は PyObject_GetIter() と同じシグネチャを持っています。
サブタイプはこのフィールドを継承します。
オプションのフィールドで、イテレータにおいて次の要素を返す関数への ポインタです。 イテレータの要素がなくなると、この関数は NULL を返さなければなりません。 StopIteration 例外は設定してもしなくても良いです。 その他のエラーが発生したときも、 NULL を返さなければなりません。 このフィールドがあると、通常この型のインスタンスがイテレータであることを示します (ただし、旧スタイルのインスタンスでは、たとえ next() メソッドが 定義されていなくても常にこの関数を持っています)。
イテレータ型では、 tp_iter 関数も定義していなければならず、 tp_iter は (新たなイテレータインスタンスではなく) イテレータインスタンス自体を返さねばなりません。
この関数のシグネチャは PyIter_Next() と同じです。
サブタイプはこのフィールドを継承します。
次の tp_weaklist までのフィールドは、 Py_TPFLAGS_HAVE_CLASS フラグビットがセットされている場合にのみ存在します。
オプションのフィールドです。ポインタで、この型の正規 (regular) のメソッドを宣言している PyMethodDef 構造体からなる、 NULL で終端された静的な配列を指します。
配列の各要素ごとに、メソッドデスクリプタの入ったエントリが型辞書 (下記の tp_dict 参照) に追加されます。
サブタイプはこのフィールドを継承しません (メソッドは別個のメカニズムで継承されています)。
オプションのフィールドです。ポインタで、型の正規 (regular) のデータメンバ (フィールドおよびスロット) を 宣言している PyMemberDef 構造体からなる、 NULL で終端された静的な配列を指します。
配列の各要素ごとに、メンバデスクリプタの入ったエントリが型辞書 (下記の tp_dict 参照) に追加されます。
サブタイプはこのフィールドを継承しません (メンバは別個のメカニズムで継承されています)。
オプションのフィールドです。ポインタで、インスタンスの算出属性 (computed attribute) を 宣言している PyGetSetDef 構造体からなる、 NULL で終端された静的な配列を指します。
配列の各要素ごとに、getset デスクリプタの入ったエントリが型辞書 (下記の tp_dict 参照) に追加されます。
サブタイプはこのフィールドを継承しません (算出属性は別個のメカニズムで継承されています)。
Docs for PyGetSetDef (XXX belong elsewhere):
typedef PyObject *(* getter)(PyObject *, void *);
typedef int (*setter)(PyObject *, PyObject *, void *);
typedef struct PyGetSetDef {
char *name; /* 属性名 */
getter get; /* 属性の get を行う C 関数 */
setter set; /* 属性の set を行う C 関数 */
char *doc; /* オプションの docstring */
void *closure; /* オプションの get/set 関数用追加データ */
} PyGetSetDef;
オプションのフィールドです。ポインタで、型に関するプロパティを継承する基底タイプへのポインタです。このフィールドのレベルでは、単継承 (single inheritance) だけがサポートされています; 多重継承はメタタイプの呼び出しによる動的な型オブジェクトの生成を必要とします。
(当たり前ですが) サブタイプはこのフィールドを継承しません。しかし、このフィールドのデフォルト値は (Python プログラマは object 型として知っている) &PyBaseObject_Type になります。 .
型の辞書は PyType_Ready() によってこのフィールドに収められます。
このフィールドは通常、 PyType_Ready() を呼び出す前に NULL に初期化しておかねばなりません; あるいは、型の初期属性の入った 辞書で初期化しておいてもかまいません。 PyType_Ready() が型をひとたび初期化すると、型の新たな属性をこの辞書に追加できるのは、 属性が (__add__() のような) オーバロード用演算でないときだけです。
サブタイプはこのフィールドを継承しません (が、この辞書内で定義されている属性は異なるメカニズムで継承されます)。
オプションのフィールドです。ポインタで、 “デスクリプタ get” 関数を指します。
関数のシグネチャは次のとおりです。
PyObject * tp_descr_get(PyObject *self, PyObject *obj, PyObject *type);
XXX blah, blah.
サブタイプはこのフィールドを継承します。
オプションのフィールドです。ポインタで、 “デスクリプタ set” 関数を指します。
関数のシグネチャは次のとおりです。
int tp_descr_set(PyObject *self, PyObject *obj, PyObject *value);
サブタイプはこのフィールドを継承します。
XXX blah, blah.
型のインスタンスにインスタンス変数の入った辞書がある場合、このフィールドは非ゼロの値になり、型のインスタンスデータ構造体 におけるインスタンス変数辞書へのオフセットが入ります; このオフセット値は PyObject_GenericGetAttr() が使います。
このフィールドを tp_dict と混同しないでください; tp_dict は型オブジェクト自体の属性のための辞書です。
このフィールドの値がゼロより大きければ、値はインスタンス構造体の先頭からの オフセットを表します。値がゼロより小さければ、インスタンス構造体の 末尾 からのオフセットを表します。負のオフセットを使うコストは比較的高くつくので、 インスタンス構造体に可変長の部分があるときのみ使うべきです。 例えば、 str や tuple のサブタイプにインスタンス辞書を 追加する場合には、負のオフセットを使います。 この場合、たとえ辞書が基本のオブジェクトレイアウトに含まれていなくても、 tp_basicsize フィールドは追加された辞書を考慮にいれなければ ならないので注意してください。ポインタサイズが 4 バイトのシステムでは、 構造体の最後尾に辞書が宣言されていることを示す場合、 tp_dictoffset を -4 にしなければなりません。
tp_dictoffset が負の場合、インスタンスにおける実際の辞書の オフセットは以下のようにして計算されます:
dictoffset = tp_basicsize + abs(ob_size)*tp_itemsize + tp_dictoffset
if dictoffset is not aligned on sizeof(void*):
round up to sizeof(void*)
ここで、 tp_basicsize, tp_itemsize および tp_dictoffset は型オブジェクトから取り出され、 ob_size はインスタンスから取り出されます。 長整数は符号を記憶するのに ob_size の符号を使うため、 ob_size は絶対値を使います。(この計算を自分で行う必要はまったくありません; _PyObject_GetDictPtr() がやってくれます。)
サブタイプはこのフィールドを継承しますが、以下の規則があるので読んでください。 サブタイプはこのオフセット値をオーバライドできます; 従って、サブタイプでは辞書のオフセットが基底タイプとは異なる場合があります。 辞書へのオフセット常に tp_dictoffset で分かるはずなので、 このことは問題にはならないはずです。
class 文で定義された型に __slots__ 宣言がなく、 かつ基底タイプの全てにインスタンス変数辞書がない場合、辞書のスロットを インスタンスデータレイアウト構造体に追加し、 スロットのオフセットを tp_dictoffset に設定します。
class 文で定義された型に __slots__ 宣言がある場合、 この型は基底タイプから tp_dictoffset を継承します。
(__dict__ という名前のスロットを __slots__ 宣言に 追加しても、期待どおりの効果は得られず、単に混乱を招くだけになります。 とはいえ、これは将来 __weakref__ のように追加されるはずです。)
オプションのフィールドです。ポインタで、インスタンス初期化関数を指します。
この関数はクラスにおける __init__() メソッドに対応します。 __init__() と同様、 __init__() を呼び出さずにインスタンスを作成できます。また、 __init__() を再度呼び出してインスタンスの再初期化もできます。
関数のシグネチャは
int tp_init(PyObject *self, PyObject *args, PyObject *kwds)
です。
self 引数は初期化するインスタンスです; args および kwds 引数は、 __init__() を呼び出す際の固定引数およびキーワード引数です。
tp_init 関数のフィールドが NULL でない場合、型の呼び出しで普通にインスタンスを生成する際に、型の tp_new がインスタンスを返した後に tp_init が呼び出されます。 tp_new が元の型のサブタイプでない別の型を返す場合、 tp_init は全く呼び出されません; tp_new が元の型のサブタイプのインスタンスを返す場合、サブタイプの tp_init が呼び出されます。 (VERSION NOTE: ここに書かれている内容は、Python 2.2.1 以降での実装に関するものです。Python 2.2 では、 tp_init は NULL でない限り tp_new が返す全ての オブジェクトに対して常に呼び出されます。) not NULL.)
サブタイプはこのフィールドを継承します。
オプションのフィールドです。ポインタで、インスタンスのメモリ確保関数を指します。
関数のシグネチャは
PyObject *tp_alloc(PyTypeObject *self, Py_ssize_t nitems)
です。
この関数の目的は、メモリ確保をメモリ初期化から分離することにあります。この関数は、インスタンス用の的確なサイズを持ち、適切にバイト整列 され、ゼロで初期化され、ただし ob_refcnt を 1 にセットされ、 ob_type が型引数 (type argument) にセットされているようなメモリブロックを返さねばなりません。型の tp_itemsize がゼロでない場合、オブジェクトの ob_size フィールドは nitems に初期化され、確保されるメモリブロックの長さは tp_basicsize + nitems *tp_itemsize を sizeof(void*) の倍数で丸めた値になるはずです; それ以外の場合、 nitems の値は使われず、メモリブロックの長さは tp_basicsize になるはずです。
この関数をインスタンス初期化の他のどの処理にも、追加でメモリ確保をする場合でさえ使ってはなりません; そうした処理は tp_new で行わねばなりません。
静的なサブタイプはこのフィールドを継承しますが、動的なサブタイプ (class 文で生成するサブタイプ) の場合は継承しません; 後者の場合、このフィールドは常に PyType_GenericAlloc() にセットされ、標準のヒープ上メモリ確保戦略が強制されます。 静的に定義する型の場合でも、 PyType_GenericAlloc() を推奨します。
オプションのフィールドです。ポインタで、インスタンス生成関数を指します。
このフィールドが NULL を指している型では、型を呼び出して新たなインスタンスを生成できません; こうした型では、おそらくファクトリ 関数のように、インスタンスを生成する他の方法があるはずです。
関数のシグネチャは
PyObject *tp_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds)
です。
引数 subtype は生成するオブジェクトの型です; args および kwds 引数は、型を呼び出すときの 固定引数およびキーワード引数です。サブタイプは tp_new 関数を呼び出すときに使う型と等価というわけではないので注意してください; tp_new 関数を呼び出すときに使う型 (と無関係ではない) サブタイプのこともあります。
tp_new 関数は subtype->tp_alloc(subtype, nitems) を呼び出してオブジェクトのメモリ領域を確保し、初期化で本当に必要とされる処理だけを行います。省略したり繰り返したりしても問題のない 初期化処理は tp_init ハンドラ内に配置しなければなりません。経験則からいうと、変更不能な型の場合、初期化は全て tp_new で行い、変更可能な型の場合はほとんどの初期化を tp_init に回すべきです。
サブタイプはこのフィールドを継承します。例外として、 tp_base が NULL か &PyBaseObject_Type になっている静的な型では継承しません。後者が例外になっているのは、旧式の拡張型が Python 2.2 でリンクされたときに呼び出し可能オブジェクトにならないようにするための予防措置です。
オプションのフィールドです。ポインタで、インスタンスのメモリ解放関数を指します。
この関数のシグネチャは少し変更されています; Python 2.2 および 2.2.1 では、シグネチャは destructor
void tp_free(PyObject *)
でしたが、 Python 2.3 以降では、シグネチャは freefunc:
void tp_free(void *)
になっています。
両方のバージョンと互換性のある初期値は _PyObject_Del です。 _PyObject_Del の定義は Python 2.3 で適切に対応できるよう変更されました。
静的なサブタイプはこのフィールドを継承しますが、動的なサブタイプ (class 文で生成するサブタイプ) の場合は継承しません; 後者の場合、このフィールドには PyType_GenericAlloc() と Py_TPFLAGS_HAVE_GC フラグビットの値に対応させるのにふさわしいメモリ解放関数がセットされます。
オプションのフィールドです。ポインタで、ガベージコレクタから呼び出される関数を指します。
ガベージコレクタは、オブジェクトがガベージとして収集可能かどうかを知る必要があります。これを知るには、通常はオブジェクトの型の tp_flags フィールドを見て、 Py_TPFLAGS_HAVE_GC フラグビットを調べるだけで十分です。しかし、静的なメモリ確保と動的なメモリ確保が混じっているインスタンスを持つような型や、 静的にメモリ確保されたインスタンスは収集できません。こうした型では、このフィールドに関数を定義しなければなりません; 関数はインスタンスが収集可能の場合には 1 を、収集不能の場合には 0 を返さねばなりません。シグネチャは
int tp_is_gc(PyObject *self)
です。
(上記のような型の例は、型オブジェクト自体です。メタタイプ PyType_Type は、型のメモリ確保が静的か動的かを 区別するためにこの関数を定義しています。)
サブタイプはこのフィールドを継承します。 (VERSION NOTE: Python 2.2 では、このフィールドは継承されませんでした。 2.2.1 以降のバージョンから継承されるようになりました。)
基底型からなるタプルです。
class 文で生成されたクラスの場合このフィールドがセットされます。静的に定義されている型の場合には、このフィールドは NULL になります。
このフィールドは継承されません。
基底クラス群を展開した集合が入っているタプルです。集合は該当する型自体からはじまり、 object で終わります。メソッド解決順 (Method Resolution Order) の順に並んでいます。
このフィールドは継承されません; フィールドの値は PyType_Ready() で毎回計算されます。
残りのフィールドは、機能テスト用のマクロである COUNT_ALLOCS が定義されている場合のみ利用でき、内部で使用するためだけのものです。 これらのフィールドについて記述するのは単に完全性のためです。サブタイプはこれらのフィールドを継承しません。
メモリ確保の回数です。
メモリ解放の回数です。
同時にメモリ確保できる最大オブジェクト数です。
tp_allocs フィールドが非ゼロの、(リンクリストの) 次の型オブジェクトを指すポインタです。
また、 Python のガベージコレクションでは、 tp_dealloc を呼び出すのはオブジェクトを生成したスレッドだけではなく、任意の Python スレッドかもしれないという点にも注意して下さい。 (オブジェクトが循環参照の一部の場合、任意のスレッドのガベージコレクション によって解放されてしまうかもしれません)。Python API 側からみれば、 tp_dealloc を呼び出すスレッドはグローバルインタプリタロック (GIL: Global Interpreter Lock) を獲得するので、これは問題ではありません。 しかしながら、削除されようとしているオブジェクトが何らかの C や C++ ライブラリ由来のオブジェクトを削除する場合、 tp_dealloc を 呼び出すスレッドのオブジェクトを削除することで、ライブラリの仮定している何らかの規約に違反しないように気を付ける必要があります。
拡張型で数値型プロトコルを実装するために使われる関数群へのポインタを保持するために使われる構造体です。 以下のほとんどすべての関数は 数値型プロトコル (number protocol) で解説されている似た名前の関数から利用されます。
以下は構造体の定義です。
typedef struct {
binaryfunc nb_add;
binaryfunc nb_subtract;
binaryfunc nb_multiply;
binaryfunc nb_divide;
binaryfunc nb_remainder;
binaryfunc nb_divmod;
ternaryfunc nb_power;
unaryfunc nb_negative;
unaryfunc nb_positive;
unaryfunc nb_absolute;
inquiry nb_nonzero; /* Used by PyObject_IsTrue */
unaryfunc nb_invert;
binaryfunc nb_lshift;
binaryfunc nb_rshift;
binaryfunc nb_and;
binaryfunc nb_xor;
binaryfunc nb_or;
coercion nb_coerce; /* Used by the coerce() function */
unaryfunc nb_int;
unaryfunc nb_long;
unaryfunc nb_float;
unaryfunc nb_oct;
unaryfunc nb_hex;
/* Added in release 2.0 */
binaryfunc nb_inplace_add;
binaryfunc nb_inplace_subtract;
binaryfunc nb_inplace_multiply;
binaryfunc nb_inplace_divide;
binaryfunc nb_inplace_remainder;
ternaryfunc nb_inplace_power;
binaryfunc nb_inplace_lshift;
binaryfunc nb_inplace_rshift;
binaryfunc nb_inplace_and;
binaryfunc nb_inplace_xor;
binaryfunc nb_inplace_or;
/* Added in release 2.2 */
binaryfunc nb_floor_divide;
binaryfunc nb_true_divide;
binaryfunc nb_inplace_floor_divide;
binaryfunc nb_inplace_true_divide;
/* Added in release 2.5 */
unaryfunc nb_index;
} PyNumberMethods;
2引数および3引数の関数は、 Py_TPFLAGS_CHECKTYPES フラグによっては、 異なる種類の引数を受け取るかもしれません。
Py_TPFLAGS_CHECKTYPES がセットされていない場合、関数の引数は オブジェクトの型であることが保証されます。呼び出し側は nb_coerce メンバで指定されている型強制メソッドを呼び出して引数を変換する責任があります。
この関数は PyNumber_CoerceEx() から利用され、同じシグネチャを持ちます。 最初の引数は定義された型のオブジェクトを指すポインタでなければなりません。 共通の “大きな” 型への変換が可能であれば、この関数はポインタを変換後の オブジェクトへの新しい参照へ置き換えて、 0 を返します。 変換ができないなら、この関数は 1 を返します。 エラーが設定荒れた場合は、 -1 を返します。
Py_TPFLAGS_CHECKTYPES フラグがセットされている場合、2引数および 3引数関数はすべてのオペランドの型をチェクし、必要な変換を行わなければなりません。 (少なくとも、オペランドのうち1つは定義している型のものです) これは推奨された方式です。 Python 3.0 では型強制は完全に取り除かれています。
与えられたオペランドに対して操作が定義されていな場合は、2引数および3引数関数は Py_NotImplemented を返さなければなりません。 その他のエラーが発生した場合は、例外を設定して NULL を返さなければなりません。
拡張型でマップ型プロトコルを実装するために使われる関数群へのポインタを保持するために使われる構造体です。 以下の3つのメンバを持っています。
この関数は PyMapping_Length() や PyObject_Size() から利用され、それらと同じシグネチャを持っています。 オブジェクトが定義された長さを持たない場合は、このスロットは NULL に設定されることがあります。
この関数は PyObject_GetItem() から利用され、同じシグネチャを持っています。 このスロットは PyMapping_Check() が 1 を返すためには 必要で、そうでなければ NULL の場合があります。
この関数は PyObject_SetItem() から利用され、同じシグネチャを持っています。 もしこのスロットが NULL なら、このオブジェクトはアイテムの代入をサポートしません。
拡張型でシーケンス型プロトコルを実装するために使われる関数群への ポインタを保持するために使われる構造体です。
この関数は PySequence_Size() や PyObject_Size() から利用され、それらと同じシグネチャを持っています。
この関数は PySequence_Concat() から利用され、同じシグネチャを持っています。 また、 + 演算からも、 tp_as_number.nb_add スロットによる 数値加算を試したあとに利用されます。
この関数は PySequence_Repeat() から利用され、同じシグネチャを持っています。 また、 * 演算からも、 tp_as_number.nb_mul スロットによる 数値乗算を試したあとに利用されます。
この関数は PySequence_GetItem() から利用され、同じシグネチャを持っています。 このスロットは PySequence_Check() が 1 を返すためには埋めなければならず、 それ以外の場合は NULL の可能性があります。
負のインデックスは次のように処理されます: sq_length スロットが 埋められていれば、それを呼び出してシーケンスの長さから正のインデックスを 計算し、 sq_item に渡します。 sq_length が NULL の場合は、インデックスはそのままこの関数に渡されます。
この関数は PySequence_SetItem() から利用され、同じシグネチャを持っています。 このスロットはオブジェクトが要素の代入をサポートしていない場合は NULL かもしれません。
この関数は PySequence_Contains() から利用され、同じシグネチャを持っています。 このスロットは NULL の場合があり、その時 PySequence_Contains() はシンプルにマッチするオブジェクトを見つけるまでシーケンスを巡回します。
この関数は PySequence_InPlaceConcat() から利用され、同じシグネチャを持っています。 この関数は最初のオペランドを修正してそれを返すべきです。
この関数は PySequence_InPlaceRepeat() から利用され、同じシグネチャを持っています。 この関数は最初のオペランドを修正してそれを返すべきです。
バッファインタフェースは、あるオブジェクトの内部データを一連のデータチャンク (chunk) として見せるモデルを外部から利用できるようにします。 各チャンクはポインタ/データ長からなるペアで指定します。チャンクはセグメント(segment) と呼ばれ、 メモリ内に不連続的に配置されるものと想定されています。
バッファインタフェースを利用できるようにしたくないオブジェクトでは、 PyTypeObject 構造体の tp_as_buffer メンバを NULL にしなくてはなりません。利用できるようにする場合、 tp_as_buffer は PyBufferProcs 構造体を指さねばなりません。
ノート
PyTypeObject 構造体の tp_flags メンバの値を 0 でなく Py_TPFLAGS_DEFAULT にしておくことがとても重要です。この設定は、 PyBufferProcs 構造体に bf_getcharbuffer スロットが入っていることを Python ランタイムに教えます。 Python の古いバージョンには bf_getcharbuffer メンバが存在しないので、古い拡張モジュールを使おうとしている新しいバージョンの Python インタプリタは、このメンバがあるかどうかテストしてから使えるようにする必要があるのです。
バッファプロトコルの実装を定義している関数群へのポインタを保持するのに使われる構造体です。
最初のスロットは bf_getreadbuffer で、 getreadbufferproc 型です。このスロットが NULL の場合、オブジェクトは内部データの読み出しをサポートしません。そのような仕様には意味がないので、 実装を行う側はこのスロットに値を埋めるはずですが、呼び出し側では非 NULL の値かどうかきちんと調べておくべきです。
次のスロットは bf_getwritebuffer で、 getwritebufferproc 型です。オブジェクトが返すバッファに対して書き込みを許可しない場合はこのスロットを NULL にできます。
第三のスロットは bf_getsegcount で、 getsegcountproc 型です。このスロットは NULL であってはならず、オブジェクトにいくつセグメントが入っているかを呼び出し側に教えるために使われます。 PyString_Type や PyBuffer_Type オブジェクトのような単純なオブジェクトには単一のセグメントしか入っていません。
最後のスロットは bf_getcharbuffer で、 getcharbufferproc です。オブジェクトの PyTypeObject 構造体における tp_flags フィールドに、 Py_TPFLAGS_HAVE_GETCHARBUFFER ビットフラグがセットされている場合にのみ、このスロットが存在することになります。 このスロットの使用に先立って、呼び出し側は PyType_HasFeature() を使ってスロットが存在するか調べねばなりません。 フラグが立っていても、 bf_getcharbuffer は NULL のときもあり、 NULL はオブジェクトの内容を 8 ビット文字列 として利用できないことを示します。このスロットに入る関数も、オブジェクトの内容を 8 ビット文字列に 変換できない場合に例外を送出することがあります。例えば、オブジェクトが浮動小数点数を保持するように設定されたアレイの場合、呼び出し側が bf_getcharbuffer を使って 8 ビット文字列としてデータを取り出そうとすると例外を送出するようにできます。 この、内部バッファを “テキスト” として取り出すという概念は、本質的にはバイナリで、文字ベースの内容を持ったオブジェクト間の区別に使われます。
ノート
現在のポリシでは、文字 (character) はマルチバイト文字でもかまわないと決めているように思われます。従って、サイズ N のバッファが N 個のキャラクタからなるとはかぎらないことになります。
型構造体中のフラグビットで、 bf_getcharbuffer スロットが既知の値になっていることを示します。このフラグビットがセット されていたとしても、オブジェクトがバッファインタフェースをサポートしていることや、 bf_getcharbuffer スロットが NULL でないことを示すわけではありません。
*ptrptr の中の読み出し可能なバッファセグメントへのポインタを返します。この関数は例外を送出してもよく、送出する場合には -1 を返さねばなりません。 segment に渡す値はゼロまたは正の値で、 bf_getsegcount スロット関数が返すセグメント数よりも必ず小さな値でなければなりません。成功すると、セグメントのサイズを返し、 *ptrptr を そのセグメントを指すポインタ値にセットします。
読み出し可能なバッファセグメントへのポインタを *ptrptr に返し、セグメントの長さを関数の戻り値として返します。エラーによる例外の場合には -1 を -1 を返さねばなりません。オブジェクトが呼び出し専用バッファしかサポートしていない場合には TypeError を、 segment が存在しないセグメントを指している場合には SystemError を送出しなければなりません。