モジュールオブジェクト (module object)

PyTypeObject PyModule_Type

この PyTypeObject のインスタンスは Python のモジュールオブジェクト型を表現します。このオブジェクトは、Python プログラムには types.ModuleType として公開されています。

int PyModule_Check(PyObject *p)

p がモジュールオブジェクトかモジュールオブジェクトのサブタイプであるときに真を返します。

int PyModule_CheckExact(PyObject *p)

p がモジュールオブジェクトで、かつモジュールオブジェクトのサブタイプでないときに真を返します。 PyModule_Type.

PyObject* PyModule_NewObject(PyObject *name)

__name__ 属性に name が設定された新しいモジュールオブジェクトを返します。 モジュールの __name__, __doc__, __package__, __loader__ 属性に値が入っています (__name__ 以外は全て None です); __file__ 属性に値を入れるのは呼び出し側の責任です。

バージョン 3.3 で追加.

バージョン 3.4 で変更: __package____loader__None に設定されます。

PyObject* PyModule_New(const char *name)
Return value: New reference.

PyModule_NewObject() に似ていますが、 name は Unicode オブジェクトではなく UTF-8 でエンコードされた文字列です。

PyObject* PyModule_GetDict(PyObject *module)
Return value: Borrowed reference.

module の名前空間を実装する辞書オブジェクトを返します; このオブジェクトは、モジュールオブジェクトの __dict__ 属性と同じものです。 module がモジュールオブジェクト (もしくはモジュールオブジェクトのサブタイプ) でない場合は、 SystemError が送出され NULL が返されます。

拡張モジュールでは、モジュールの __dict__ を直接操作するよりも、 PyModule_*() および PyObject_*() 関数を使う方が推奨されます。

PyObject* PyModule_GetNameObject(PyObject *module)

module__name__ の値を返します。モジュールがこの属性を提供していない場合や文字列型でない場合、 SystemError を送出して NULL を返します。

バージョン 3.3 で追加.

char* PyModule_GetName(PyObject *module)

PyModule_GetNameObject() に似ていますが、 'utf-8' でエンコードされた name を返します。

void* PyModule_GetState(PyObject *module)

モジュールの "state"(モジュールを生成したタイミングで確保されるメモリブロックへのポインター) か、なければ NULL を返します。 PyModuleDef.m_size を参照してください。

PyModuleDef* PyModule_GetDef(PyObject *module)

モジュールが作られる元となった PyModuleDef 構造体へのポインタを返します。 モジュールが定義によって作られていなかった場合は NULL を返します。

PyObject* PyModule_GetFilenameObject(PyObject *module)

module__file__ 属性をもとに module がロードされたもとのファイル名を返します。もしファイル名が定義されていない場合や、 Unicode 文字列ではない場合、 SystemError を発生させて NULL を返します。それ以外の場合は Unicode オブジェクトへの参照を返します。

バージョン 3.2 で追加.

char* PyModule_GetFilename(PyObject *module)

PyModule_GetFilenameObject() と似ていますが、 'utf-8' でエンコードされたファイル名を返します。

バージョン 3.2 で非推奨: PyModule_GetFilename() はエンコードできないファイル名に対しては UnicodeEncodeError を送出します。これの代わりに PyModule_GetFilenameObject() を使用してください。

Cモジュールの初期化

通常、モジュールオブジェクトは拡張モジュール (初期化関数をエクスポートしている共有ライブラリ) または組み込まれたモジュール (PyImport_AppendInittab() を使って初期化関数が追加されているモジュール) から作られます。 詳細については C および C++ 拡張のビルド または 埋め込まれた Python の拡張 を見てください。

初期化関数は、モジュール定義のインスタンスを PyModule_Create() に渡して出来上がったモジュールオブジェクトを返してもよいですし、もしくは定義構造体そのものを返し"多段階初期化"を要求しても構いません。

PyModuleDef

モジュール定義構造体はモジュールオブジェクトを生成するのに必要なすべての情報を保持します。 通常は、それぞれのモジュールごとに静的に初期化されたこの型の変数が1つだけ存在します。

PyModuleDef_Base m_base

このメンバーは常に PyModuleDef_HEAD_INIT で初期化してください。

char* m_name

新しいモジュールの名前。

char* m_doc

モジュールの docstring。たいてい docstring は PyDoc_STRVAR() を利用して生成されます。

Py_ssize_t m_size

モジュールの状態は、静的なグローバルな領域ではなく PyModule_GetState() で取得できるモジュールごとのメモリ領域に保持されていることがあります。 これによってモジュールは複数のサブ・インタプリターで安全に使えます。

このメモリ領域は m_size に基づいてモジュール作成時に確保され、モジュールオブジェクトが破棄されるときに、 m_free 関数があればそれが呼ばれた後で解放されます。

m_size-1 を設定すると、そのモジュールはグローバルな状態を持つためにサブ・インタープリターをサポートしていないということになります。

m_size を非負の値に設定すると、モジュールは再初期化でき、その状態のために必要となる追加のメモリ量を指定できるということになります。 非負の m_size は多段階初期化で必要になります。

詳細は PEP 3121 を参照。

PyMethodDef* m_methods

PyMethodDef で定義される、モジュールレベル関数のテーブルへのポインター。関数が存在しない場合は NULL を設定することが可能。

PyModuleDef_Slot* m_slots

多段階初期化のためのスロット定義の配列で、 {0, NULL} 要素が終端となります。 一段階初期化を使うときは、 m_slotsNULL でなければなりません。

バージョン 3.5 で変更: バージョン 3.5 より前は、このメンバは常に NULL に設定されていて、次のものとして定義されていました:

inquiry m_reload
traverseproc m_traverse

A traversal function to call during GC traversal of the module object, or NULL if not needed.

inquiry m_clear

A clear function to call during GC clearing of the module object, or NULL if not needed.

freefunc m_free

A function to call during deallocation of the module object, or NULL if not needed.

一段階初期化

モジュールの初期化関数が直接モジュールオブジェクトを生成して返す場合があります。 これは"一段階初期化"と呼ばれ、次の2つのモジュール生成関数のどちらか1つを使います:

PyObject* PyModule_Create(PyModuleDef *def)

def での定義に従って新しいモジュールオブジェクトを生成します。 これは PyModule_Create2()module_api_versionPYTHON_API_VERSION を設定したときのように振る舞います。

PyObject* PyModule_Create2(PyModuleDef *def, int module_api_version)

APIバージョンを module_api_version として def での定義に従って新しいモジュールオブジェクトを生成します。 もし指定されたバージョンが実行しているインタープリターのバージョンと異なる場合は、 RuntimeWarning を発生させます。

注釈

ほとんどの場合、この関数ではなく PyModule_Create() を利用するべきです。この関数は、この関数の必要性を理解しているときにだけ利用してください。

モジュールオブジェクトが初期化関数から返される前に、たいていは PyModule_AddObject() などの関数を使ってモジュールオブジェクトにメンバを所属させます。

多段階初期化

拡張を直接生成するもう1つのやり方は、"多段階初期化"を要求する方法です。 この方法で作られる拡張モジュールは、よりPythonモジュールに近い振る舞いをします: 初期化処理は、モジュールオブジェクトを生成する 生成段階 とメンバを所属させる 実行段階 に分割されます。 この区別はクラスの __new__() メソッドと __init__() メソッドに似ています。

一段階初期化で生成されたモジュールと違い、多段階初期化で生成されたモジュールはシングルトンではありません: sys.modules のエントリーが削除されモジュールが再インポートされた場合、新しいモジュールオブジェクトが生成され、古いモジュールはPythonモジュールと同じように通常のガベージコレクションで処理されることになります。 デフォルトでは、同じ定義から作られた複数のモジュールは独立であるべきです: あるインスタンスに加えた変更は別のインスタンスに影響しません。 これは、(例えば PyModule_GetState() を使って取得できる) 全ての状態や、(モジュールの __dict__PyType_FromSpec() で生成された個々のクラスのような) モジュールに所属するものは、特定のモジュールオブジェクト特有のものであるべきということです。

多段階初期化を使って生成される全てのモジュールは サブ・インタプリター をサポートすることが求められます。 複数のモジュールが独立していることを保証するのには、たいていはこのサポートをするだけで十分です。

多段階初期化を要求するために、初期化関数 (PyInit_modulename) は空でない m_slots を持つ PyModuleDef を返します。 これを返す前に、 PyModuleDef インスタンスは次の関数で初期化されなくてはいけません:

PyObject* PyModuleDef_Init(PyModuleDef *def)

モジュール定義が型と参照カウントを正しく報告する、適切に初期化された Python オブジェクトであること保証します。

PyObject* にキャストされた def を返します。エラーが発生した場合 NULL を返します。

バージョン 3.5 で追加.

モジュール定義の m_slots メンバは PyModuleDef_Slot 構造体の配列を指さなければなりません:

PyModuleDef_Slot
int slot

スロット ID で、以下で説明されている利用可能な値から選ばれます。

void* value

スロットの値で、意味はスロット ID に依存します。

バージョン 3.5 で追加.

m_slots 配列はID 0 のスロットで終端されていなければなりません。

利用可能なスロットの型は以下です:

Py_mod_create

モジュールオブジェクト自身を生成するために呼ばれる関数を指定します。 このスロットの value ポインタは次のシグネチャを持つ関数を指していなくてはいけません:

PyObject* create_module(PyObject *spec, PyModuleDef *def)

PEP 451 で定義された ModuleSpec インスタンスと、モジュール定義を受け取る関数です。 これは新しいモジュールオブジェクトを返すか、エラーを設定して NULL を返すべきです。

この関数は最小限に留めておくべきです。 特に任意のPythonコードを呼び出すべきではなく、同じモジュールをインポートしようとすると無限ループに陥るでしょう。

複数の Py_mod_create スロットを1つのモジュール定義に設定しない方がよいです。

Py_mod_create が設定されていない場合は、インポート機構は PyModule_New() を使って通常のモジュールオブジェクトを生成します。 モジュールの名前は定義ではなく spec から取得され、これによって拡張モジュールが動的にモジュール階層における位置を調整できたり、シンボリックリンクを通して同一のモジュール定義を共有しつつ別の名前でインポートできたりします。

返されるオブジェクトが PyModule_Type のインスタンスである必要はありません。 インポートに関連する属性の設定と取得ができる限りは、どんな型でも使えます。 しかし、 PyModuleDefNULL でない m_traverse, m_clear, m_free 、もしくはゼロでない m_size 、もしくは Py_mod_create 以外のスロットを持つ場合は、 PyModule_Type インスタンスのみが返されるでしょう。

Py_mod_exec

モジュールを 実行する ときに呼ばれる関数を指定します。 これはPythonモジュールのコードを実行するのと同等です: この関数はたいていはクラスと定数をモジュールにします。 この関数のシグネチャは以下です:

int exec_module(PyObject* module)

複数の Py_mod_exec スロットが設定されていた場合は、 m_slots 配列に現れた順に処理されていきます。

多段階初期化についてより詳しくは PEP 489 を見てください。

低水準モジュール作成関数

以下の関数は、多段階初期化を使うときに裏側で呼び出されます。 例えばモジュールオブジェクトを動的に生成するときに、これらの関数を直接使えます。 PyModule_FromDefAndSpec および PyModule_ExecDef のどちらも、呼び出した後にはモジュールが完全に初期化されていなければなりません。

PyObject * PyModule_FromDefAndSpec(PyModuleDef *def, PyObject *spec)

module と ModuleSpec オブジェクトの spec で定義されたとおりに新しいモジュールオブジェクトを生成します。 この関数は、 PyModule_FromDefAndSpec2() 関数の module_api_versionPYTHON_API_VERSION を指定した時とおなじようにふるまいます。

バージョン 3.5 で追加.

PyObject * PyModule_FromDefAndSpec2(PyModuleDef *def, PyObject *spec, int module_api_version)

APIバージョンを module_api_version として、 module と ModuleSpec オブジェクトの spec で定義されたとおりに新しいモジュールオブジェクトを生成します。 もし指定されたバージョンが実行しているインタープリターのバージョンと異なる場合は、 RuntimeWarning を発生させます。

注釈

ほとんどの場合、この関数ではなく PyModule_FromDefAndSpec() を利用するべきです。 この関数は、この関数の必要性を理解しているときにだけ利用してください。

バージョン 3.5 で追加.

int PyModule_ExecDef(PyObject *module, PyModuleDef *def)

def で与えられた任意の実行スロット (Py_mod_exec) を実行します。

バージョン 3.5 で追加.

int PyModule_SetDocString(PyObject *module, const char *docstring)

module の docstring を docstring に設定します。 この関数は、 PyModuleDef から PyModule_Create もしくは PyModule_FromDefAndSpec を使ってモジュールを生成するときに自動的に呼び出されます。

バージョン 3.5 で追加.

int PyModule_AddFunctions(PyObject *module, PyMethodDef *functions)

終端が NULL になっている functions 配列にある関数を module に追加します。 PyMethodDef 構造体の個々のエントリについては PyMethodDef の説明を参照してください (モジュールの名前空間が共有されていないので、 C で実装されたモジュールレベル "関数" はたいていモジュールを1つ目の引数として受け取り、 Python クラスのインスタンスメソッドに似た形にします)。 この関数は、 PyModuleDef から PyModule_Create もしくは PyModule_FromDefAndSpec を使ってモジュールを生成するときに自動的に呼び出されます。

バージョン 3.5 で追加.

サポート関数

モジュールの初期化関数 (一段階初期化を使う場合) 、あるいはモジュールの実行スロットから呼び出される関数 (多段階初期化を使う場合) は次の関数を使うと、モジュールの state の初期化を簡単にできます:

int PyModule_AddObject(PyObject *module, const char *name, PyObject *value)

module にオブジェクトを name として追加します。 この関数はモジュールの初期化関数から利用される便利関数です。 これは value への参照を盗みます。 エラーのときには -1 を、成功したときには 0 を返します。

int PyModule_AddIntConstant(PyObject *module, const char *name, long value)

module に整数定数を name として追加します。この便宜関数はモジュールの初期化関数から利用されています。エラーのときには -1 を、成功したときには 0 を返します。

int PyModule_AddStringConstant(PyObject *module, const char *name, const char *value)

module に文字列定数を name として追加します。 この便利関数はモジュールの初期化関数から利用されています。 文字列 valueNULL 終端されていなければなりません。 エラーのときには -1 を、成功したときには 0 を返します。

int PyModule_AddIntMacro(PyObject *module, macro)

module に int 定数を追加します。名前と値は macro から取得されます。例えば、 PyModule_AddIntMacro(module, AF_INET) とすると、 AF_INET という名前の int 型定数を AF_INET の値で module に追加します。エラー時には -1 を、成功時には 0 を返します。

int PyModule_AddStringMacro(PyObject *module, macro)

文字列定数を module に追加します。

モジュール検索

一段階初期化は、現在のインタプリタのコンテキストから探せるシングルトンのモジュールを生成します。 これによって、後からモジュール定義への参照だけでモジュールオブジェクトが取得できます。

多段階初期化を使うと単一の定義から複数のモジュールが作成できるので、これらの関数は多段階初期化を使って作成されたモジュールには使えません。

PyObject* PyState_FindModule(PyModuleDef *def)

現在のインタプリタの def から作られたモジュールオブジェクトを返します。このメソッドの前提条件として、前もって PyState_AddModule() でインタプリタの state にモジュールオブジェクトを連結しておくことを要求します。対応するモジュールオブジェクトが見付からない、もしくは事前にインタプリタの state に連結されていない場合は、 NULL を返します。

int PyState_AddModule(PyObject *module, PyModuleDef *def)

関数に渡されたモジュールオブジェクトを、インタプリタの state に連結します。この関数を使うことで PyState_FindModule() からモジュールオブジェクトにアクセスできるようになります。

一段階初期化を使って作成されたモジュールにのみ有効です。

バージョン 3.3 で追加.

int PyState_RemoveModule(PyModuleDef *def)

def から作られたモジュールオブジェクトをインタプリタ state から削除します。

バージョン 3.3 で追加.