boost/python/pytype_function.hpp
はじめに
Python のシグニチャをサポートするには、変換器は関連する PyTypeObject
へのポインタを返す get_pytype
関数を提供しなければならない。例として ResultConverter
か to_python_converter
を見るとよい。このヘッダファイルのクラスは get_pytype
の実装に使用することを想定している。修飾無しの引数型とともに使用する T
に対するテンプレートの _direct
版1もある(これらはモジュールを読み込んだときに変換レジストリ内にあると考えてしかるべきものである)。
クラス
wrap_pytype
クラス
-
template<PyTypeObject const *pytype>
class wrap_pytype このテンプレートは、テンプレート引数を返す静的メンバ
get_pytype
を生成する。
wrap_pytype
クラスの概要
namespace boost { namespace python { namespace converter{
template < PyTypeObject const *pytype >
class wrap_pytype
{
public:
static PyTypeObject const *get_pytype(){return pytype; }
};
}}}
registered_pytype
クラス
-
template<class T>
class registered_pytype このテンプレートは、
class_
で Python へエクスポートする型(修飾子があってもよい)のテンプレート引数とともに使用すべきである。生成された静的メンバget_pytype
は対応する Python の型を返す。
registered_pytype
クラスの概要
namespace boost { namespace python { namespace converter{
template < class T >
class registered_pytype
{
public:
static PyTypeObject const *get_pytype();
};
}}}
expected_from_python_type
クラス
-
template<class T>
class expected_from_python_type このテンプレートは、型
T
について登録済みのfrom_python
変換器を問い合わせし合致した Python 型を返す静的メンバget_pytype
を生成する。
expected_from_python_type
クラスの概要
namespace boost { namespace python { namespace converter{
template < class T >
class expected_from_python_type
{
public:
static PyTypeObject const *get_pytype();
};
}}}
to_python_target_type
クラス
-
template<class T>
class to_python_target_type このテンプレートは、
T
から変換可能な Python の型を返す静的メンバget_pytype
を生成する。
to_python_target_type
クラスの概要
namespace boost { namespace python { namespace converter{
template < class T >
class to_python_target_type
{
public:
static PyTypeObject const *get_pytype();
};
}}}
例
以下の例では、Python のドキュメントにある標準的な noddy モジュール例を実装したとして、関連する宣言を noddy.h
に置いたものと仮定する。noddy_NoddyObject
は極限なまでに単純な拡張型であるので、この例は少しばかりわざとらしい。すべての情報がその戻り値の型に含まれる関数をラップしている。
#include <boost/python/reference.hpp>
#include <boost/python/module.hpp>
#include "noddy.h"
struct tag {};
tag make_tag() { return tag(); }
using namespace boost::python;
struct tag_to_noddy
#if defined BOOST_PYTHON_SUPPORTS_PY_SIGNATURES // Python のシグニチャがサポートされない場合は不要なオーバーヘッドが発生
: wrap_pytype<&noddy_NoddyType> // wrap_pytype から get_pytype を継承する
#endif
{
static PyObject* convert(tag const& x)
{
return PyObject_New(noddy_NoddyObject, &noddy_NoddyType);
}
};
BOOST_PYTHON_MODULE(to_python_converter)
{
def("make_tag", make_tag);
to_python_converter<tag, tag_to_noddy
#if defined BOOST_PYTHON_SUPPORTS_PY_SIGNATURES // Python のシグニチャがサポートされない場合は不正
, true
#endif
>(); // tag_to_noddy がメンバ get_pytype を持つので「真」
}
以下の例は、テンプレート expected_from_python_type
および to_python_target_type
を使用して Python との双方向変換器を登録している。
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <boost/python/extract.hpp>
#include <boost/python/to_python_converter.hpp>
#include <boost/python/class.hpp>
using namespace boost::python;
struct A
{
};
struct B
{
A a;
B(const A& a_):a(a_){}
};
// A から Python の整数への変換器
struct BToPython
#if defined BOOST_PYTHON_SUPPORTS_PY_SIGNATURES // Python のシグニチャがサポートされていない場合は不要なオーバーヘッドが発生
: converter::to_python_target_type<A> // get_pytype を継承する
#endif
{
static PyObject* convert(const B& b)
{
return incref(object(b.a).ptr());
}
};
// Python の整数から A への変換
struct BFromPython
{
BFromPython()
{
boost::python::converter::registry::push_back
( &convertible
, &construct
, type_id< B >()
#if defined BOOST_PYTHON_SUPPORTS_PY_SIGNATURES // Python のシグニチャがサポートされていない場合は不正
, &converter::expected_from_python_type<A>::get_pytype// A へ変換可能なものは B へ変換可能
#endif
);
}
static void* convertible(PyObject* obj_ptr)
{
extract<const A&> ex(obj_ptr);
if (!ex.check()) return 0;
return obj_ptr;
}
static void construct(
PyObject* obj_ptr,
converter::rvalue_from_python_stage1_data* data)
{
void* storage = (
(converter::rvalue_from_python_storage< B >*)data)-> storage.bytes;
extract<const A&> ex(obj_ptr);
new (storage) B(ex());
data->convertible = storage;
}
};
B func(const B& b) { return b ; }
BOOST_PYTHON_MODULE(pytype_function_ext)
{
to_python_converter< B , BtoPython
#if defined BOOST_PYTHON_SUPPORTS_PY_SIGNATURES // Python のシグニチャがサポートされていない場合は不正
,true
#endif
>(); // get_pytype を持つ
BFromPython();
class_<A>("A") ;
def("func", &func);
}
>>> from pytype_function_ext import *
>>> print func.__doc__
func( (A)arg1) -> A :
C++ signature:
struct B func(struct B)
- 1
訳注
expected_from_python_type_direct
、registered_pytype_direct
、to_python_target_type_direct
の 3 つ。