C++ Boost

Boost.Python

Headers <boost/python/class.hpp>, <boost/python/class_fwd.hpp>


Contents

Introduction
Classes
Class template class_
Class class_ synopsis
Class class_ constructors
Class class_ modifier functions
Class template bases
Class template bases synopsis
Class template init
Class template init synopsis
Class init constructors
init-expressions
Class template optional
Class template optional synopsis
Class template init_with_call_policies
Class template init_with_call_policies synopsis
Example(s)

Introduction

<boost/python/class.hpp> defines the interface through which users expose their C++ classes to Python. It declares the class_ class template, which is parameterized on the class type being exposed. It also exposes the init, optional and bases utility class templates, which are used in conjunction with class_.

<boost/python/class_fwd.hpp> contains a forward declaration of the class_ class template.

Classes

Class template class_<T, Bases, HeldType, NonCopyable>

Creates a Python class associated with the C++ type passed as its first parameter. Although it has four template parameters, only the first one is required. The three optional arguments can actually be supplied in any order; Boost.Python determines the role of the argument from its type.

Template Parameter Requirements Semantics Default
T A class type. The class being wrapped
Bases A specialization of bases<...> which specifies previously-exposed C++ base classes of T[1]. Registers from_python conversions from wrapped T instances to each of its exposed direct and indirect bases. For each polymorphic base B, registers conversions from indirectly-held wrapped B instances to T. bases<>
HeldType Must be T, a class derived from T, or a Dereferenceable type for which pointee<HeldType>::type is T or a class derived from T. Specifies the type which is actually embedded in a Python object wrapping a T instance. More details below. T
NonCopyable If supplied, must be boost::noncopyable. Suppresses automatic registration of to_python conversions which copy T instances. Required when T has no publicly-accessible copy constructor. An unspecified type other than boost::noncopyable.

HeldType Semantics

  1. If HeldType is derived from T, its exposed constructor(s) must accept an initial PyObject* argument which refers back to the Python object that contains the HeldType instance, as shown in this example. This argument is not included in the init-expression passed to def(init_expr), below, nor is it passed explicitly by users when Python instances of T are created. This idiom allows C++ virtual functions which will be overridden in Python to access the Python object so the Python method can be invoked. Boost.Python automatically registers additional converters which allow wrapped instances of T to be passed to wrapped C++ functions expecting HeldType arguments.
  2. Because Boost.Python will always allow wrapped instances of T to be passed in place of HeldType arguments, specifying a smart pointer for HeldType allows users to pass Python T instances where a smart pointer-to-T is expected. Smart pointers such as std::auto_ptr<> or boost::shared_ptr<> which contain a nested type element_type designating the referent type are automatically supported; additional smart pointer types can be supported by specializing pointee<HeldType>.
  3. As in case 1 above, when HeldType is a smart pointer to a class derived from T, the initial PyObject* argument must be supplied by all of HeldType's exposed constructors.
  4. Except in cases 1 and 3, users may optionally specify that T itself gets initialized with a similar initial PyObject* argument by specializing has_back_reference<T>.

Class template class_ synopsis

namespace boost { namespace python
{
  template <class T
           , class Bases = bases<>
            , class HeldType = T
            , class NonCopyable = unspecified
           >
  class class_ : public object
  {
    // Constructors with default __init__
    class_(char const* name);
    class_(char const* name, char const* docstring);

    // Constructors, specifying non-default __init__
    template <class Init>
    class_(char const* name, Init);
    template <class Init>
    class_(char const* name, char const* docstring, Init);

    // Exposing additional __init__ functions
    template <class Init>
    class_& def(Init);

    // defining methods
    template <class F>
    class_& def(char const* name, F f);
    template <class Fn, class A1>
    class_& def(char const* name, Fn fn, A1 const&);
    template <class Fn, class A1, class A2>
    class_& def(char const* name, Fn fn, A1 const&, A2 const&);
    template <class Fn, class A1, class A2, class A3>
    class_& def(char const* name, Fn fn, A1 const&, A2 const&, A3 const&);

    // exposing operators
    template <unspecified>
    class_& def(detail::operator_<unspecified>);

    // Raw attribute modification
    template <class U>
    class_& setattr(char const* name, U const&);

    // exposing data members
    template <class D>
    class_& def_readonly(char const* name, D T::*pm);

    template <class D>
    class_& def_readwrite(char const* name, D T::*pm);

    // property creation
    template <class Get>
    void add_property(char const* name, Get const& fget);
    template <class Get, class Set>
    void add_property(char const* name, Get const& fget, Set const& fset);

    // pickle support
    void enable_pickling(bool getstate_manages_dict);
    template <typename PickleSuite>
    self& def_pickle(PickleSuite const&);
  };
}}

Class template class_ constructors

class_(char const* name);
class_(char const* name, char const* docstring);
template <class Init>
class_(char const* name, Init init_spec);
template <class Init>
class_(char const* name, char const* docstring, Init init_spec);
Requires: name is a ntbs which conforms to Python's identifier naming rules. If docstring is supplied, it must be an ntbs. If init_spec is supplied, it must be either the special enumeration constant no_init or an init-expression compatible with T.
Effects: Constructs a class_ object holding a Boost.Python extension class named name. The named attribute of the current scope is bound to the new extension class.
Rationale:Allowing the user to specify constructor arguments in the class_<> constructor helps her to avoid the common run-time errors which result from invoking wrapped member functions without having exposed an __init__ function which creates the requisite T instance. Types which are not default-constructible will cause a compile-time error unless Init is supplied. The user must always supply name as there is currently no portable method to derive the text of the class name from its type.

Class template class_ modifier functions

template <class Init>
class_& def(Init init_expr);
Requires: init_expr is the result of an init-expression compatible with T.
Effects: For each valid prefix P of Init, adds an __init__(...) function overload to the extension class accepting P as arguments. Each overload generated constructs an object of HeldType according to the semantics described above, using a copy of init_expr's call policies. If the longest valid prefix of Init contains N types and init_expr holds M keywords, an initial sequence of the keywords are used for all but the first N - M arguments of each overload.
Returns: *this
Rationale: Allows users to easily expose a class' constructor to Python.

template <class F>
class_& def(char const* name, Fn fn);
template <class Fn, class A1>
class_& def(char const* name, Fn fn, A1 const& a1);
template <class Fn, class A1, class A2>
class_& def(char const* name, Fn fn, A1 const& a1, A2 const& a2);
template <class Fn, class A1, class A2, class A3>
class_& def(char const* name, Fn fn, A1 const& a1, A2 const& a2, A3 const& a3);
Requires: name is a ntbs which conforms to Python's identifier naming rules.
Returns: *this
template <unspecified>
class_& def(detail::operator_<unspecified>);
Effects: Adds a Python special method as described here.
Returns: *this
template <class U>
class_& setattr(char const* name, U const& u);
Requires: name is a ntbs which conforms to Python's identifier naming rules.
Effects: Converts u to Python and adds it to the attribute dictionary of the extension class:
PyObject_SetAttrString(this->ptr(), name, object(u).ptr());
Returns: *this

template <class Get>
void add_property(char const* name, Get const& fget);
template <class Get, class Set>
void add_property(char const* name, Get const& fget, Set const& fset);
Requires: name is a ntbs which conforms to Python's identifier naming rules.
Effects: Creates a new Python property class instance, passing object(fget) (and object(fset) in the second form) to its constructor, then adds that property to the Python class object under construction with the given attribute name.
Returns: *this
Rationale: Allows users to easily expose functions that can be invoked from Python with attribute access syntax.

template <class D>
class_& def_readonly(char const* name, D T::*pm);
Requires: name is a ntbs which conforms to Python's identifier naming rules.
Effects:
this->add_property(name, make_getter(pm));
Returns: *this
Rationale: Allows users to easily expose a class' data member such that it can be inspected from Python with a natural syntax.
template <class D>
class_& def_readwrite(char const* name, D T::*pm);
Effects:
this->add_property(name, make_getter(pm), make_setter(pm));
Returns: *this
Rationale: Allows users to easily expose a class' data member such that it can be inspected and set from Python with a natural syntax.
void enable_pickling(bool getstate_manages_dict);
Requires: {{Ralf}}
Effects: {{Ralf}}
Rationale: Allows users to easily expose functions that can be invoked from Python with attribute access syntax.
template <typename PickleSuite>
class_& def_pickle(PickleSuite const&);
Requires: {{Ralf}}
Effects: {{Ralf}}
Returns: *this
Rationale: {{Ralf}}

Class template init<T1 = unspecified, T2 = unspecified,...Tn = unspecified>

A MPL sequence which can be used to specify a family of one or more __init__ functions. Only the last Ti supplied may be an instantiation of optional<...>.

Class template init synopsis

namespace boost { namespace python
{
  template <T1 = unspecified,...Tn = unspecified>
  struct init
  {
      init(char const* doc = 0);
      template <class Keywords> init(Keywords const& kw, char const* doc = 0);
      template <class Keywords> init(char const* doc, Keywords const& kw);

      template <class CallPolicies>
      unspecified operator[](CallPolicies const& policies) const
  };
}}

Class template init constructors

init(char const* doc = 0);
template <class Keywords> init(Keywords const& kw, char const* doc = 0);
template <class Keywords> init(char const* doc, Keywords const& kw);
Requires: If supplied, doc is an ntbs. If supplied, kw is the result of a
Effects: The result is an init-expression whose docstring is doc and whose keywords are a reference to kw. If the first form is used, the resulting expression's keywords are empty. The expression's call policies are an instance of default_call_policies. If Tn is optional<U1, U2,... Um>, the expression's valid prefixes are given by:
(T1, T2,...Tn-1), (T1, T2,...Tn-1 , U1), (T1, T2,...Tn-1 , U1, U2), ...(T1, T2,...Tn-1 , U1, U2,...Um).
Otherwise, the expression has one valid prefix given by the the template arguments the user specified.

Class template init observer functions

template <class Policies>
unspecified operator[](Policies const& policies) const
Requires: Policies is a model of CallPolicies.
Effects: Returns a new init-expression with all the same properties as the init object except that its callpolicies are replaced by a reference to policies.

init-expressions

An init-expression is a transport vehicle for the following properties, used to describe a family of __init__ methods to be generated for an extension class:
docstring: An ntbs whose value will bound to the method's __doc__ attribute
keywords: A keyword-expression which will be used to name (a trailing subset of) the arguments to the generated __init__ function(s).
call policies: An instance of a model of CallPolicies.
argument types: An MPL sequence of C++ argument types which will be used to construct the wrapped C++ object. An init expression has one or more valid prefixes which are given by a sequence of prefixes of its argument types.

Class template optional<T1 = unspecified, T2 = unspecified,...Tn = unspecified>

A MPL sequence which can be used to specify the optional arguments to an __init__ function.

Class template optional synopsis

namespace boost { namespace python
{
  template <T1 = unspecified,...Tn = unspecified>
  struct optional {};
}}

Class template bases<T1, T2,...TN>

An MPL sequence which can be used in class_<...> instantiations indicate a list of base classes.

Class template bases synopsis

namespace boost { namespace python
{
  template <T1 = unspecified,...Tn = unspecified>
  struct bases
  {};
}}

Example(s)

Given a C++ class declaration:

class Foo : public Bar, public Baz
{
 public:
   Foo(int x, char const* y);
   Foo(double);

   std::string const& name() { return m_name; }
   void name(char const*);

   double value; // public data
 private:
   ...
};
A corresponding Boost.Python extension class can be created with:
using namespace boost::python;

class_<Foo,bases<Bar,Baz> >("Foo",
          "This is Foo's docstring."
          "It describes our Foo extension class",

          init<int,char const*>(args("x","y"), "__init__ docstring")
          )
   .def(init<double>())
   .def("get_name", &Foo::get_name, return_internal_reference<>())
   .def("set_name", &Foo::set_name)
   .def_readwrite("value", &Foo::value)
   ;

[1] By "previously-exposed" we mean that the for each B in bases, an instance of class_<B, ...> must have already been constructed.
class_<Base>("Base");
class_<Derived, bases<Base> >("Derived");
Revised 29 Sept, 2002

© Copyright Dave Abrahams 2002. All Rights Reserved.