拡張と埋め込み FAQ
******************


C で独自の関数を作ることはできますか？
======================================

はい。関数、変数、例外、そして新しいタイプまで含んだビルトインモジュー
ルを C で作れます。これはドキュメント Python インタプリタの拡張と埋め
込み で説明されています。

ほとんどの中級から上級の Python 本もこの話題を扱っています。


C++ で独自の関数を作ることはできますか？
========================================

はい。C++ 内にある C 互換機能を使ってできます。 "extern "C" { ... }"
で Python のインクルードファイルを囲み、 "extern "C"" を Python インタ
プリタから呼ぶ各関数の前に置いてください。グローバルや静的な C++ オブ
ジェクトの構造体を持つものは良くないでしょう。


C を書くのは大変です。他の方法はありませんか？
==============================================

独自の C 拡張を書くための別のやり方は、目的によっていくつかあります。

If you need more speed, Psyco generates x86 assembly code from Python
bytecode.  You can use Psyco to compile the most time-critical
functions in your code, and gain a significant improvement with very
little effort, as long as you’re running on a machine with an
x86-compatible processor.

Cython and its relative Pyrex are compilers that accept a slightly
modified form of Python and generate the corresponding C code.  Pyrex
makes it possible to write an extension without having to learn
Python’s C API.

If you need to interface to some C or C++ library for which no Python
extension currently exists, you can try wrapping the library’s data
types and functions with a tool such as SWIG.  SIP, CXX Boost, or
Weave are also alternatives for wrapping C++ libraries.


C から任意の Python 文を実行するにはどうしますか？
==================================================

これを行う最高水準の関数は "PyRun_SimpleString()" で、一つの文字列引数
を取り、モジュール "__main__" のコンテキストでそれを実行し、成功なら 0
、例外 ("SyntaxError" を含む) が発生したら -1 を返します。更に制御した
ければ、 "PyRun_String()"  を使ってください。ソースは
"Python/pythonrun.c" の 『"PyRun_SimpleString()" を参照してください。


C から任意の Python 式を評価するにはどうしますか？
==================================================

先の質問の "PyRun_String()" を、スタートシンボル "Py_eval_input" を渡
して呼び出してください。これは式を解析し、評価してその値を返します。


Python オブジェクトから C の値を取り出すにはどうしますか？
==========================================================

オブジェクトの型に依ります。タプルなら、 "PyTuple_Size()" が長さを返し
、 "PyTuple_GetItem()" が指定されたインデックスの要素を返します。リス
トにも同様の関数 "PyList_Size()" と "PyList_GetItem()" があります。

For strings, "PyString_Size()" returns its length and
"PyString_AsString()" a pointer to its value.  Note that Python
strings may contain null bytes so C’s "strlen()" should not be used.

To test the type of an object, first make sure it isn’t *NULL*, and
then use "PyString_Check()", "PyTuple_Check()", "PyList_Check()", etc.

There is also a high-level API to Python objects which is provided by
the so-called 『abstract』 interface – read "Include/abstract.h" for
further details.  It allows interfacing with any kind of Python
sequence using calls like "PySequence_Length()",
"PySequence_GetItem()", etc.)  as well as many other useful protocols.


Py_BuildValue() で任意長のタプルを作るにはどうしますか？
========================================================

You can’t.  Use "t = PyTuple_New(n)" instead, and fill it with objects
using "PyTuple_SetItem(t, i, o)" – note that this 「eats」 a reference
count of "o", so you have to "Py_INCREF()" it.  Lists have similar
functions "PyList_New(n)" and "PyList_SetItem(l, i, o)".  Note that
you *must* set all the tuple items to some value before you pass the
tuple to Python code – "PyTuple_New(n)" initializes them to NULL,
which isn’t a valid Python value.


C からオブジェクトのメソッドを呼び出すにはどうしますか？
========================================================

"PyObject_CallMethod()" 関数でオブジェクトの任意のメソッドを呼び出せま
す。パラメタは、オブジェクト、呼び出すメソッドの名前、
"Py_BuildValue()" で使われるようなフォーマット文字列、そして引数です:

   PyObject *
   PyObject_CallMethod(PyObject *object, char *method_name,
                       char *arg_format, ...);

これはメソッドを持ついかなるオブジェクトにも有効で、組み込みかユーザ定
義かは関係ありません。返り値に対して "Py_DECREF()" する必要があること
もあります。

例えば、あるファイルオブジェクトの 「seek」 メソッドを 10, 0 を引数と
して呼ぶとき (ファイルオブジェクトのポインタを 「f」 とします):

   res = PyObject_CallMethod(f, "seek", "(ii)", 10, 0);
   if (res == NULL) {
           ... an exception occurred ...
   }
   else {
           Py_DECREF(res);
   }

なお、 "PyObject_CallObject()" の引数リストには *常に* タプルが必要で
す。関数を引数なしで呼び出すには、フォーマットに 「()」 を渡し、関数を
一つの引数で呼び出すには、関数を括弧でくくって例えば 「(i)」 としてく
ださい。


PyErr_Print() (その他 stdout/stderr に印字するもの) からの出力を受け取るにはどうしますか？
==========================================================================================

Python コード内で、 "write()" メソッドをサポートするオブジェクトを定義
してください。そのオブジェクトを "sys.stdout" と "sys.stderr" に代入し
てください。print_error を呼び出すか、単に標準のトレースバック機構を作
動させてください。そうすれば、出力は "write()" が送る任意の所に行きま
す。

The easiest way to do this is to use the StringIO class in the
standard library.

Sample code and use for catching stdout:

   >>> class StdoutCatcher:
   ...     def __init__(self):
   ...         self.data = ''
   ...     def write(self, stuff):
   ...         self.data = self.data + stuff
   ...
   >>> import sys
   >>> sys.stdout = StdoutCatcher()
   >>> print 'foo'
   >>> print 'hello world!'
   >>> sys.stderr.write(sys.stdout.data)
   foo
   hello world!


C から Python で書かれたモジュールにアクセスするにはどうしますか？
==================================================================

以下のようにモジュールオブジェクトへのポインタを得られます:

   module = PyImport_ImportModule("<modulename>");

そのモジュールがまだインポートされていない (つまり、まだ "sys.modules"
に現れていない) なら、これはモジュールを初期化します。そうでなければ、
単純に "sys.modules["<modulename>"]" の値を返します。なお、これはモジ
ュールをいかなる名前空間にも代入しません。これはモジュールが初期化され
て 『"sys.modules" に保管されていることを保証するだけです。

これで、モジュールの属性 (つまり、モジュールで定義された任意の名前) に
以下のようにアクセスできるようになります:

   attr = PyObject_GetAttrString(module, "<attrname>");

"PyObject_SetAttrString()" を呼んでモジュールの変数に代入することもで
きます。


Python から C++ へインタフェースするにはどうしますか？
======================================================

やりたいことに応じて、いろいろな方法があります。手動でやるなら、 「拡
張と埋め込み」 ドキュメント を読むことから始めてください。なお、Python
ランタイムシステムにとっては、 C と C++ はあまり変わりません。だから、
C 構造体 (ポインタ)型に基づいて新しい Python の型を構築する方針は C++
オブジェクトに対しても有効です。

C++ ライブラリに関しては、 C を書くのは大変です。他の方法はありません
か？ を参照してください。


セットアップファイルでモジュールを追加しようとしたらメイクに失敗しました。なぜですか？
======================================================================================

セットアップは改行で終わらなければならなくて、改行がないと、ビルド工程
は失敗します。(これを直すには、ある種の醜いシェルスクリプトハックが必
要ですが、このバグは小さいものですから努力に見合う価値はないでしょう。
)


拡張をデバッグするにはどうしますか？
====================================

動的にロードされた拡張に GDB を使うとき、拡張がロードされるまでブレー
クポイントを設定してはいけません。

".gdbinit" ファイルに(または対話的に)、このコマンドを加えてください:

   br _PyImport_LoadDynamicModule

そして、GDB を起動するときに:

   $ gdb /local/bin/python
   gdb) run myscript.py
   gdb) continue # repeat until your extension is loaded
   gdb) finish   # so that your extension is loaded
   gdb) br myfunction.c:50
   gdb) continue


Linux システムで Python モジュールをコンパイルしたいのですが、見つからないファイルがあります。なぜですか？
==========================================================================================================

Python の多くのパッケージバージョンには、Python 拡張をコンパイルするの
に必要な様々なファイルを含む "/usr/lib/python2.*x*/config/" ディレクト
リが含まれていません。

Red Hat では、Python RPM をインストールして必要なファイルを得てくださ
い。

Debian では、 "apt-get install python-dev" を実行してください。


What does 「SystemError: _PyImport_FixupExtension: module yourmodule not loaded」 mean?
=======================================================================================

This means that you have created an extension module named 「
yourmodule」, but your module init function does not initialize with
that name.

Every module init function will have a line similar to:

   module = Py_InitModule("yourmodule", yourmodule_functions);

If the string passed to this function is not the same name as your
extension module, the "SystemError" exception will be raised.


「不完全 (incomplete) な入力」 を 「不適切 (invalid) な入力」 から区別するにはどうしますか？
============================================================================================

Python インタラクティブインタプリタでは、入力が不完全なとき (例えば、
「if」 文の始まりをタイプした時や、カッコや三重文字列引用符を閉じてい
ない時など) には継続プロンプトを与えられますが、入力が不適切であるとき
には即座に構文エラーメッセージが与えられます。このようなふるまいを模倣
したいことがあります。

Python では構文解析器のふるまいに十分に近い "codeop" モジュールが使え
ます。例えば IDLE がこれを使っています。

これを C で行う最も簡単な方法は、 "PyRun_InteractiveLoop()" を (必要な
らば別のスレッドで) 呼び出し、Python インタプリタにあなたの入力を扱わ
せることです。独自の入力関数を指定するのに
"PyOS_ReadlineFunctionPointer()" を設定することもできます。詳しいヒン
トは、 "Modules/readline.c" や "Parser/myreadline.c" を参照してくださ
い。

しかし、組み込みの Python インタプリタを他のアプリケーションと同じスレ
ッドで実行することが必要で、 "PyRun_InteractiveLoop()" でユーザの入力
を待っている間止められないこともあります。このような場合の解決策の一つ
は、 "PyParser_ParseString()" を呼んで "e.error" と "E_EOF" が等しいこ
と、つまり入力が不完全であることを確かめることです。これは、Alex
Farber のコードを参考にした、コード片の例です:

   #include <Python.h>
   #include <node.h>
   #include <errcode.h>
   #include <grammar.h>
   #include <parsetok.h>
   #include <compile.h>

   int testcomplete(char *code)
     /* code should end in \n */
     /* return -1 for error, 0 for incomplete, 1 for complete */
   {
     node *n;
     perrdetail e;

     n = PyParser_ParseString(code, &_PyParser_Grammar,
                              Py_file_input, &e);
     if (n == NULL) {
       if (e.error == E_EOF)
         return 0;
       return -1;
     }

     PyNode_Free(n);
     return 1;
   }

別の解決策は、受け取られた文字列を "Py_CompileString()" でコンパイルす
ることを試みることです。エラー無くコンパイルされたら、返されたコードオ
ブジェクトを "PyEval_EvalCode()" を呼んで実行することを試みてください
。そうでなければ、入力を後のために保存してください。コンパイルが失敗し
たなら、それがエラーなのか入力の続きが求められているだけなのか調べてく
ださい。そのためには、例外タプルからメッセージ文字列を展開し、それを文
字列 「unexpected EOF while parsing」 と比較します。ここに GNU
readline library を使った完全な例があります (readline() を読んでいる間
は **SIGINT** を無視したいかもしれません):

   #include <stdio.h>
   #include <readline.h>

   #include <Python.h>
   #include <object.h>
   #include <compile.h>
   #include <eval.h>

   int main (int argc, char* argv[])
   {
     int i, j, done = 0;                          /* lengths of line, code */
     char ps1[] = ">>> ";
     char ps2[] = "... ";
     char *prompt = ps1;
     char *msg, *line, *code = NULL;
     PyObject *src, *glb, *loc;
     PyObject *exc, *val, *trb, *obj, *dum;

     Py_Initialize ();
     loc = PyDict_New ();
     glb = PyDict_New ();
     PyDict_SetItemString (glb, "__builtins__", PyEval_GetBuiltins ());

     while (!done)
     {
       line = readline (prompt);

       if (NULL == line)                          /* Ctrl-D pressed */
       {
         done = 1;
       }
       else
       {
         i = strlen (line);

         if (i > 0)
           add_history (line);                    /* save non-empty lines */

         if (NULL == code)                        /* nothing in code yet */
           j = 0;
         else
           j = strlen (code);

         code = realloc (code, i + j + 2);
         if (NULL == code)                        /* out of memory */
           exit (1);

         if (0 == j)                              /* code was empty, so */
           code[0] = '\0';                        /* keep strncat happy */

         strncat (code, line, i);                 /* append line to code */
         code[i + j] = '\n';                      /* append '\n' to code */
         code[i + j + 1] = '\0';

         src = Py_CompileString (code, "<stdin>", Py_single_input);

         if (NULL != src)                         /* compiled just fine - */
         {
           if (ps1  == prompt ||                  /* ">>> " or */
               '\n' == code[i + j - 1])           /* "... " and double '\n' */
           {                                               /* so execute it */
             dum = PyEval_EvalCode ((PyCodeObject *)src, glb, loc);
             Py_XDECREF (dum);
             Py_XDECREF (src);
             free (code);
             code = NULL;
             if (PyErr_Occurred ())
               PyErr_Print ();
             prompt = ps1;
           }
         }                                        /* syntax error or E_EOF? */
         else if (PyErr_ExceptionMatches (PyExc_SyntaxError))
         {
           PyErr_Fetch (&exc, &val, &trb);        /* clears exception! */

           if (PyArg_ParseTuple (val, "sO", &msg, &obj) &&
               !strcmp (msg, "unexpected EOF while parsing")) /* E_EOF */
           {
             Py_XDECREF (exc);
             Py_XDECREF (val);
             Py_XDECREF (trb);
             prompt = ps2;
           }
           else                                   /* some other syntax error */
           {
             PyErr_Restore (exc, val, trb);
             PyErr_Print ();
             free (code);
             code = NULL;
             prompt = ps1;
           }
         }
         else                                     /* some non-syntax error */
         {
           PyErr_Print ();
           free (code);
           code = NULL;
           prompt = ps1;
         }

         free (line);
       }
     }

     Py_XDECREF(glb);
     Py_XDECREF(loc);
     Py_Finalize();
     exit(0);
   }


未定義の g++ シンボル __builtin_new や __pure_virtual を見つけるにはどうしますか？
==================================================================================

g++ モジュールを動的にロードするには、Python を再コンパイルし、それを
g++ で再リンク (Python Modules Makefile 内の LINKCC を変更) し、拡張を
g++ でリンク (例えば "g++ -shared -o mymodule.so mymodule.o") しなけれ
ばなりません。


メソッドのいくつかは C で、その他は Python で実装されたオブジェクトクラスを (継承などで) 作ることはできますか？
===============================================================================================================

はい、 "int" 、 "list" 、 "dict" などのビルトインクラスから継承できま
す。

The Boost Python Library (BPL,
http://www.boost.org/libs/python/doc/index.html) を使えば、これを C++
からできます。 (すなわち、BPL を使って C++ で書かれた拡張クラスを継承
できます).


When importing module X, why do I get 「undefined symbol: PyUnicodeUCS2*」?
===========================================================================

You are using a version of Python that uses a 4-byte representation
for Unicode characters, but some C extension module you are importing
was compiled using a Python that uses a 2-byte representation for
Unicode characters (the default).

If instead the name of the undefined symbol starts with
"PyUnicodeUCS4", the problem is the reverse: Python was built using
2-byte Unicode characters, and the extension module was compiled using
a Python with 4-byte Unicode characters.

This can easily occur when using pre-built extension packages.  RedHat
Linux 7.x, in particular, provided a 「python2」 binary that is
compiled with 4-byte Unicode.  This only causes the link failure if
the extension uses any of the "PyUnicode_*()" functions.  It is also a
problem if an extension uses any of the Unicode-related format
specifiers for "Py_BuildValue()" (or similar) or parameter
specifications for "PyArg_ParseTuple()".

You can check the size of the Unicode character a Python interpreter
is using by checking the value of sys.maxunicode:

   >>> import sys
   >>> if sys.maxunicode > 65535:
   ...     print 'UCS4 build'
   ... else:
   ...     print 'UCS2 build'

The only way to solve this problem is to use extension modules
compiled with a Python binary built using the same size for Unicode
characters.
