mirror of
https://github.com/boostorg/python.git
synced 2026-01-19 04:22:16 +00:00
restore article.
This commit is contained in:
@@ -1,5 +1,947 @@
|
||||
.. Copyright David Abrahams 2006. Distributed under the Boost
|
||||
.. Software License, Version 1.0. (See accompanying
|
||||
.. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
+++++++++++++++++++++++++++++++++++++++++++
|
||||
Building Hybrid Systems with Boost.Python
|
||||
+++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
This file has been moved to http://www.boost-consulting.com/writing/bpl.txt.
|
||||
:Author: David Abrahams
|
||||
:Contact: dave@boost-consulting.com
|
||||
:organization: `Boost Consulting`_
|
||||
:date: $Date$
|
||||
|
||||
:Author: Ralf W. Grosse-Kunstleve
|
||||
|
||||
:copyright: Copyright David Abrahams and Ralf W. Grosse-Kunstleve 2003. All rights reserved
|
||||
|
||||
.. contents:: Table of Contents
|
||||
|
||||
.. _`Boost Consulting`: http://www.boost-consulting.com
|
||||
|
||||
==========
|
||||
Abstract
|
||||
==========
|
||||
|
||||
Boost.Python is an open source C++ library which provides a concise
|
||||
IDL-like interface for binding C++ classes and functions to
|
||||
Python. Leveraging the full power of C++ compile-time introspection
|
||||
and of recently developed metaprogramming techniques, this is achieved
|
||||
entirely in pure C++, without introducing a new syntax.
|
||||
Boost.Python's rich set of features and high-level interface make it
|
||||
possible to engineer packages from the ground up as hybrid systems,
|
||||
giving programmers easy and coherent access to both the efficient
|
||||
compile-time polymorphism of C++ and the extremely convenient run-time
|
||||
polymorphism of Python.
|
||||
|
||||
==============
|
||||
Introduction
|
||||
==============
|
||||
|
||||
Python and C++ are in many ways as different as two languages could
|
||||
be: while C++ is usually compiled to machine-code, Python is
|
||||
interpreted. Python's dynamic type system is often cited as the
|
||||
foundation of its flexibility, while in C++ static typing is the
|
||||
cornerstone of its efficiency. C++ has an intricate and difficult
|
||||
compile-time meta-language, while in Python, practically everything
|
||||
happens at runtime.
|
||||
|
||||
Yet for many programmers, these very differences mean that Python and
|
||||
C++ complement one another perfectly. Performance bottlenecks in
|
||||
Python programs can be rewritten in C++ for maximal speed, and
|
||||
authors of powerful C++ libraries choose Python as a middleware
|
||||
language for its flexible system integration capabilities.
|
||||
Furthermore, the surface differences mask some strong similarities:
|
||||
|
||||
* 'C'-family control structures (if, while, for...)
|
||||
|
||||
* Support for object-orientation, functional programming, and generic
|
||||
programming (these are both *multi-paradigm* programming languages.)
|
||||
|
||||
* Comprehensive operator overloading facilities, recognizing the
|
||||
importance of syntactic variability for readability and
|
||||
expressivity.
|
||||
|
||||
* High-level concepts such as collections and iterators.
|
||||
|
||||
* High-level encapsulation facilities (C++: namespaces, Python: modules)
|
||||
to support the design of re-usable libraries.
|
||||
|
||||
* Exception-handling for effective management of error conditions.
|
||||
|
||||
* C++ idioms in common use, such as handle/body classes and
|
||||
reference-counted smart pointers mirror Python reference semantics.
|
||||
|
||||
Given Python's rich 'C' interoperability API, it should in principle
|
||||
be possible to expose C++ type and function interfaces to Python with
|
||||
an analogous interface to their C++ counterparts. However, the
|
||||
facilities provided by Python alone for integration with C++ are
|
||||
relatively meager. Compared to C++ and Python, 'C' has only very
|
||||
rudimentary abstraction facilities, and support for exception-handling
|
||||
is completely missing. 'C' extension module writers are required to
|
||||
manually manage Python reference counts, which is both annoyingly
|
||||
tedious and extremely error-prone. Traditional extension modules also
|
||||
tend to contain a great deal of boilerplate code repetition which
|
||||
makes them difficult to maintain, especially when wrapping an evolving
|
||||
API.
|
||||
|
||||
These limitations have lead to the development of a variety of wrapping
|
||||
systems. SWIG_ is probably the most popular package for the
|
||||
integration of C/C++ and Python. A more recent development is SIP_,
|
||||
which was specifically designed for interfacing Python with the Qt_
|
||||
graphical user interface library. Both SWIG and SIP introduce their
|
||||
own specialized languages for customizing inter-language bindings.
|
||||
This has certain advantages, but having to deal with three different
|
||||
languages (Python, C/C++ and the interface language) also introduces
|
||||
practical and mental difficulties. The CXX_ package demonstrates an
|
||||
interesting alternative. It shows that at least some parts of
|
||||
Python's 'C' API can be wrapped and presented through a much more
|
||||
user-friendly C++ interface. However, unlike SWIG and SIP, CXX does
|
||||
not include support for wrapping C++ classes as new Python types.
|
||||
|
||||
The features and goals of Boost.Python_ overlap significantly with
|
||||
many of these other systems. That said, Boost.Python attempts to
|
||||
maximize convenience and flexibility without introducing a separate
|
||||
wrapping language. Instead, it presents the user with a high-level
|
||||
C++ interface for wrapping C++ classes and functions, managing much of
|
||||
the complexity behind-the-scenes with static metaprogramming.
|
||||
Boost.Python also goes beyond the scope of earlier systems by
|
||||
providing:
|
||||
|
||||
* Support for C++ virtual functions that can be overridden in Python.
|
||||
|
||||
* Comprehensive lifetime management facilities for low-level C++
|
||||
pointers and references.
|
||||
|
||||
* Support for organizing extensions as Python packages,
|
||||
with a central registry for inter-language type conversions.
|
||||
|
||||
* A safe and convenient mechanism for tying into Python's powerful
|
||||
serialization engine (pickle).
|
||||
|
||||
* Coherence with the rules for handling C++ lvalues and rvalues that
|
||||
can only come from a deep understanding of both the Python and C++
|
||||
type systems.
|
||||
|
||||
The key insight that sparked the development of Boost.Python is that
|
||||
much of the boilerplate code in traditional extension modules could be
|
||||
eliminated using C++ compile-time introspection. Each argument of a
|
||||
wrapped C++ function must be extracted from a Python object using a
|
||||
procedure that depends on the argument type. Similarly the function's
|
||||
return type determines how the return value will be converted from C++
|
||||
to Python. Of course argument and return types are part of each
|
||||
function's type, and this is exactly the source from which
|
||||
Boost.Python deduces most of the information required.
|
||||
|
||||
This approach leads to *user guided wrapping*: as much information is
|
||||
extracted directly from the source code to be wrapped as is possible
|
||||
within the framework of pure C++, and some additional information is
|
||||
supplied explicitly by the user. Mostly the guidance is mechanical
|
||||
and little real intervention is required. Because the interface
|
||||
specification is written in the same full-featured language as the
|
||||
code being exposed, the user has unprecedented power available when
|
||||
she does need to take control.
|
||||
|
||||
.. _Python: http://www.python.org/
|
||||
.. _SWIG: http://www.swig.org/
|
||||
.. _SIP: http://www.riverbankcomputing.co.uk/sip/index.php
|
||||
.. _Qt: http://www.trolltech.com/
|
||||
.. _CXX: http://cxx.sourceforge.net/
|
||||
.. _Boost.Python: http://www.boost.org/libs/python/doc
|
||||
|
||||
===========================
|
||||
Boost.Python Design Goals
|
||||
===========================
|
||||
|
||||
The primary goal of Boost.Python is to allow users to expose C++
|
||||
classes and functions to Python using nothing more than a C++
|
||||
compiler. In broad strokes, the user experience should be one of
|
||||
directly manipulating C++ objects from Python.
|
||||
|
||||
However, it's also important not to translate all interfaces *too*
|
||||
literally: the idioms of each language must be respected. For
|
||||
example, though C++ and Python both have an iterator concept, they are
|
||||
expressed very differently. Boost.Python has to be able to bridge the
|
||||
interface gap.
|
||||
|
||||
It must be possible to insulate Python users from crashes resulting
|
||||
from trivial misuses of C++ interfaces, such as accessing
|
||||
already-deleted objects. By the same token the library should
|
||||
insulate C++ users from low-level Python 'C' API, replacing
|
||||
error-prone 'C' interfaces like manual reference-count management and
|
||||
raw ``PyObject`` pointers with more-robust alternatives.
|
||||
|
||||
Support for component-based development is crucial, so that C++ types
|
||||
exposed in one extension module can be passed to functions exposed in
|
||||
another without loss of crucial information like C++ inheritance
|
||||
relationships.
|
||||
|
||||
Finally, all wrapping must be *non-intrusive*, without modifying or
|
||||
even seeing the original C++ source code. Existing C++ libraries have
|
||||
to be wrappable by third parties who only have access to header files
|
||||
and binaries.
|
||||
|
||||
==========================
|
||||
Hello Boost.Python World
|
||||
==========================
|
||||
|
||||
And now for a preview of Boost.Python, and how it improves on the raw
|
||||
facilities offered by Python. Here's a function we might want to
|
||||
expose::
|
||||
|
||||
char const* greet(unsigned x)
|
||||
{
|
||||
static char const* const msgs[] = { "hello", "Boost.Python", "world!" };
|
||||
|
||||
if (x > 2)
|
||||
throw std::range_error("greet: index out of range");
|
||||
|
||||
return msgs[x];
|
||||
}
|
||||
|
||||
To wrap this function in standard C++ using the Python 'C' API, we'd
|
||||
need something like this::
|
||||
|
||||
extern "C" // all Python interactions use 'C' linkage and calling convention
|
||||
{
|
||||
// Wrapper to handle argument/result conversion and checking
|
||||
PyObject* greet_wrap(PyObject* args, PyObject * keywords)
|
||||
{
|
||||
int x;
|
||||
if (PyArg_ParseTuple(args, "i", &x)) // extract/check arguments
|
||||
{
|
||||
char const* result = greet(x); // invoke wrapped function
|
||||
return PyString_FromString(result); // convert result to Python
|
||||
}
|
||||
return 0; // error occurred
|
||||
}
|
||||
|
||||
// Table of wrapped functions to be exposed by the module
|
||||
static PyMethodDef methods[] = {
|
||||
{ "greet", greet_wrap, METH_VARARGS, "return one of 3 parts of a greeting" }
|
||||
, { NULL, NULL, 0, NULL } // sentinel
|
||||
};
|
||||
|
||||
// module initialization function
|
||||
DL_EXPORT init_hello()
|
||||
{
|
||||
(void) Py_InitModule("hello", methods); // add the methods to the module
|
||||
}
|
||||
}
|
||||
|
||||
Now here's the wrapping code we'd use to expose it with Boost.Python::
|
||||
|
||||
#include <boost/python.hpp>
|
||||
using namespace boost::python;
|
||||
BOOST_PYTHON_MODULE(hello)
|
||||
{
|
||||
def("greet", greet, "return one of 3 parts of a greeting");
|
||||
}
|
||||
|
||||
and here it is in action::
|
||||
|
||||
>>> import hello
|
||||
>>> for x in range(3):
|
||||
... print hello.greet(x)
|
||||
...
|
||||
hello
|
||||
Boost.Python
|
||||
world!
|
||||
|
||||
Aside from the fact that the 'C' API version is much more verbose,
|
||||
it's worth noting a few things that it doesn't handle correctly:
|
||||
|
||||
* The original function accepts an unsigned integer, and the Python
|
||||
'C' API only gives us a way of extracting signed integers. The
|
||||
Boost.Python version will raise a Python exception if we try to pass
|
||||
a negative number to ``hello.greet``, but the other one will proceed
|
||||
to do whatever the C++ implementation does when converting an
|
||||
negative integer to unsigned (usually wrapping to some very large
|
||||
number), and pass the incorrect translation on to the wrapped
|
||||
function.
|
||||
|
||||
* That brings us to the second problem: if the C++ ``greet()``
|
||||
function is called with a number greater than 2, it will throw an
|
||||
exception. Typically, if a C++ exception propagates across the
|
||||
boundary with code generated by a 'C' compiler, it will cause a
|
||||
crash. As you can see in the first version, there's no C++
|
||||
scaffolding there to prevent this from happening. Functions wrapped
|
||||
by Boost.Python automatically include an exception-handling layer
|
||||
which protects Python users by translating unhandled C++ exceptions
|
||||
into a corresponding Python exception.
|
||||
|
||||
* A slightly more-subtle limitation is that the argument conversion
|
||||
used in the Python 'C' API case can only get that integer ``x`` in
|
||||
*one way*. PyArg_ParseTuple can't convert Python ``long`` objects
|
||||
(arbitrary-precision integers) which happen to fit in an ``unsigned
|
||||
int`` but not in a ``signed long``, nor will it ever handle a
|
||||
wrapped C++ class with a user-defined implicit ``operator unsigned
|
||||
int()`` conversion. Boost.Python's dynamic type conversion
|
||||
registry allows users to add arbitrary conversion methods.
|
||||
|
||||
==================
|
||||
Library Overview
|
||||
==================
|
||||
|
||||
This section outlines some of the library's major features. Except as
|
||||
neccessary to avoid confusion, details of library implementation are
|
||||
omitted.
|
||||
|
||||
------------------
|
||||
Exposing Classes
|
||||
------------------
|
||||
|
||||
C++ classes and structs are exposed with a similarly-terse interface.
|
||||
Given::
|
||||
|
||||
struct World
|
||||
{
|
||||
void set(std::string msg) { this->msg = msg; }
|
||||
std::string greet() { return msg; }
|
||||
std::string msg;
|
||||
};
|
||||
|
||||
The following code will expose it in our extension module::
|
||||
|
||||
#include <boost/python.hpp>
|
||||
BOOST_PYTHON_MODULE(hello)
|
||||
{
|
||||
class_<World>("World")
|
||||
.def("greet", &World::greet)
|
||||
.def("set", &World::set)
|
||||
;
|
||||
}
|
||||
|
||||
Although this code has a certain pythonic familiarity, people
|
||||
sometimes find the syntax bit confusing because it doesn't look like
|
||||
most of the C++ code they're used to. All the same, this is just
|
||||
standard C++. Because of their flexible syntax and operator
|
||||
overloading, C++ and Python are great for defining domain-specific
|
||||
(sub)languages
|
||||
(DSLs), and that's what we've done in Boost.Python. To break it down::
|
||||
|
||||
class_<World>("World")
|
||||
|
||||
constructs an unnamed object of type ``class_<World>`` and passes
|
||||
``"World"`` to its constructor. This creates a new-style Python class
|
||||
called ``World`` in the extension module, and associates it with the
|
||||
C++ type ``World`` in the Boost.Python type conversion registry. We
|
||||
might have also written::
|
||||
|
||||
class_<World> w("World");
|
||||
|
||||
but that would've been more verbose, since we'd have to name ``w``
|
||||
again to invoke its ``def()`` member function::
|
||||
|
||||
w.def("greet", &World::greet)
|
||||
|
||||
There's nothing special about the location of the dot for member
|
||||
access in the original example: C++ allows any amount of whitespace on
|
||||
either side of a token, and placing the dot at the beginning of each
|
||||
line allows us to chain as many successive calls to member functions
|
||||
as we like with a uniform syntax. The other key fact that allows
|
||||
chaining is that ``class_<>`` member functions all return a reference
|
||||
to ``*this``.
|
||||
|
||||
So the example is equivalent to::
|
||||
|
||||
class_<World> w("World");
|
||||
w.def("greet", &World::greet);
|
||||
w.def("set", &World::set);
|
||||
|
||||
It's occasionally useful to be able to break down the components of a
|
||||
Boost.Python class wrapper in this way, but the rest of this article
|
||||
will stick to the terse syntax.
|
||||
|
||||
For completeness, here's the wrapped class in use: ::
|
||||
|
||||
>>> import hello
|
||||
>>> planet = hello.World()
|
||||
>>> planet.set('howdy')
|
||||
>>> planet.greet()
|
||||
'howdy'
|
||||
|
||||
Constructors
|
||||
============
|
||||
|
||||
Since our ``World`` class is just a plain ``struct``, it has an
|
||||
implicit no-argument (nullary) constructor. Boost.Python exposes the
|
||||
nullary constructor by default, which is why we were able to write: ::
|
||||
|
||||
>>> planet = hello.World()
|
||||
|
||||
However, well-designed classes in any language may require constructor
|
||||
arguments in order to establish their invariants. Unlike Python,
|
||||
where ``__init__`` is just a specially-named method, In C++
|
||||
constructors cannot be handled like ordinary member functions. In
|
||||
particular, we can't take their address: ``&World::World`` is an
|
||||
error. The library provides a different interface for specifying
|
||||
constructors. Given::
|
||||
|
||||
struct World
|
||||
{
|
||||
World(std::string msg); // added constructor
|
||||
...
|
||||
|
||||
we can modify our wrapping code as follows::
|
||||
|
||||
class_<World>("World", init<std::string>())
|
||||
...
|
||||
|
||||
of course, a C++ class may have additional constructors, and we can
|
||||
expose those as well by passing more instances of ``init<...>`` to
|
||||
``def()``::
|
||||
|
||||
class_<World>("World", init<std::string>())
|
||||
.def(init<double, double>())
|
||||
...
|
||||
|
||||
Boost.Python allows wrapped functions, member functions, and
|
||||
constructors to be overloaded to mirror C++ overloading.
|
||||
|
||||
Data Members and Properties
|
||||
===========================
|
||||
|
||||
Any publicly-accessible data members in a C++ class can be easily
|
||||
exposed as either ``readonly`` or ``readwrite`` attributes::
|
||||
|
||||
class_<World>("World", init<std::string>())
|
||||
.def_readonly("msg", &World::msg)
|
||||
...
|
||||
|
||||
and can be used directly in Python: ::
|
||||
|
||||
>>> planet = hello.World('howdy')
|
||||
>>> planet.msg
|
||||
'howdy'
|
||||
|
||||
This does *not* result in adding attributes to the ``World`` instance
|
||||
``__dict__``, which can result in substantial memory savings when
|
||||
wrapping large data structures. In fact, no instance ``__dict__``
|
||||
will be created at all unless attributes are explicitly added from
|
||||
Python. Boost.Python owes this capability to the new Python 2.2 type
|
||||
system, in particular the descriptor interface and ``property`` type.
|
||||
|
||||
In C++, publicly-accessible data members are considered a sign of poor
|
||||
design because they break encapsulation, and style guides usually
|
||||
dictate the use of "getter" and "setter" functions instead. In
|
||||
Python, however, ``__getattr__``, ``__setattr__``, and since 2.2,
|
||||
``property`` mean that attribute access is just one more
|
||||
well-encapsulated syntactic tool at the programmer's disposal.
|
||||
Boost.Python bridges this idiomatic gap by making Python ``property``
|
||||
creation directly available to users. If ``msg`` were private, we
|
||||
could still expose it as attribute in Python as follows::
|
||||
|
||||
class_<World>("World", init<std::string>())
|
||||
.add_property("msg", &World::greet, &World::set)
|
||||
...
|
||||
|
||||
The example above mirrors the familiar usage of properties in Python
|
||||
2.2+: ::
|
||||
|
||||
>>> class World(object):
|
||||
... __init__(self, msg):
|
||||
... self.__msg = msg
|
||||
... def greet(self):
|
||||
... return self.__msg
|
||||
... def set(self, msg):
|
||||
... self.__msg = msg
|
||||
... msg = property(greet, set)
|
||||
|
||||
Operator Overloading
|
||||
====================
|
||||
|
||||
The ability to write arithmetic operators for user-defined types has
|
||||
been a major factor in the success of both languages for numerical
|
||||
computation, and the success of packages like NumPy_ attests to the
|
||||
power of exposing operators in extension modules. Boost.Python
|
||||
provides a concise mechanism for wrapping operator overloads. The
|
||||
example below shows a fragment from a wrapper for the Boost rational
|
||||
number library::
|
||||
|
||||
class_<rational<int> >("rational_int")
|
||||
.def(init<int, int>()) // constructor, e.g. rational_int(3,4)
|
||||
.def("numerator", &rational<int>::numerator)
|
||||
.def("denominator", &rational<int>::denominator)
|
||||
.def(-self) // __neg__ (unary minus)
|
||||
.def(self + self) // __add__ (homogeneous)
|
||||
.def(self * self) // __mul__
|
||||
.def(self + int()) // __add__ (heterogenous)
|
||||
.def(int() + self) // __radd__
|
||||
...
|
||||
|
||||
The magic is performed using a simplified application of "expression
|
||||
templates" [VELD1995]_, a technique originally developed for
|
||||
optimization of high-performance matrix algebra expressions. The
|
||||
essence is that instead of performing the computation immediately,
|
||||
operators are overloaded to construct a type *representing* the
|
||||
computation. In matrix algebra, dramatic optimizations are often
|
||||
available when the structure of an entire expression can be taken into
|
||||
account, rather than evaluating each operation "greedily".
|
||||
Boost.Python uses the same technique to build an appropriate Python
|
||||
method object based on expressions involving ``self``.
|
||||
|
||||
.. _NumPy: http://www.pfdubois.com/numpy/
|
||||
|
||||
Inheritance
|
||||
===========
|
||||
|
||||
C++ inheritance relationships can be represented to Boost.Python by adding
|
||||
an optional ``bases<...>`` argument to the ``class_<...>`` template
|
||||
parameter list as follows::
|
||||
|
||||
class_<Derived, bases<Base1,Base2> >("Derived")
|
||||
...
|
||||
|
||||
This has two effects:
|
||||
|
||||
1. When the ``class_<...>`` is created, Python type objects
|
||||
corresponding to ``Base1`` and ``Base2`` are looked up in
|
||||
Boost.Python's registry, and are used as bases for the new Python
|
||||
``Derived`` type object, so methods exposed for the Python ``Base1``
|
||||
and ``Base2`` types are automatically members of the ``Derived``
|
||||
type. Because the registry is global, this works correctly even if
|
||||
``Derived`` is exposed in a different module from either of its
|
||||
bases.
|
||||
|
||||
2. C++ conversions from ``Derived`` to its bases are added to the
|
||||
Boost.Python registry. Thus wrapped C++ methods expecting (a
|
||||
pointer or reference to) an object of either base type can be
|
||||
called with an object wrapping a ``Derived`` instance. Wrapped
|
||||
member functions of class ``T`` are treated as though they have an
|
||||
implicit first argument of ``T&``, so these conversions are
|
||||
neccessary to allow the base class methods to be called for derived
|
||||
objects.
|
||||
|
||||
Of course it's possible to derive new Python classes from wrapped C++
|
||||
class instances. Because Boost.Python uses the new-style class
|
||||
system, that works very much as for the Python built-in types. There
|
||||
is one significant detail in which it differs: the built-in types
|
||||
generally establish their invariants in their ``__new__`` function, so
|
||||
that derived classes do not need to call ``__init__`` on the base
|
||||
class before invoking its methods : ::
|
||||
|
||||
>>> class L(list):
|
||||
... def __init__(self):
|
||||
... pass
|
||||
...
|
||||
>>> L().reverse()
|
||||
>>>
|
||||
|
||||
Because C++ object construction is a one-step operation, C++ instance
|
||||
data cannot be constructed until the arguments are available, in the
|
||||
``__init__`` function: ::
|
||||
|
||||
>>> class D(SomeBoostPythonClass):
|
||||
... def __init__(self):
|
||||
... pass
|
||||
...
|
||||
>>> D().some_boost_python_method()
|
||||
Traceback (most recent call last):
|
||||
File "<stdin>", line 1, in ?
|
||||
TypeError: bad argument type for built-in operation
|
||||
|
||||
This happened because Boost.Python couldn't find instance data of type
|
||||
``SomeBoostPythonClass`` within the ``D`` instance; ``D``'s ``__init__``
|
||||
function masked construction of the base class. It could be corrected
|
||||
by either removing ``D``'s ``__init__`` function or having it call
|
||||
``SomeBoostPythonClass.__init__(...)`` explicitly.
|
||||
|
||||
Virtual Functions
|
||||
=================
|
||||
|
||||
Deriving new types in Python from extension classes is not very
|
||||
interesting unless they can be used polymorphically from C++. In
|
||||
other words, Python method implementations should appear to override
|
||||
the implementation of C++ virtual functions when called *through base
|
||||
class pointers/references from C++*. Since the only way to alter the
|
||||
behavior of a virtual function is to override it in a derived class,
|
||||
the user must build a special derived class to dispatch a polymorphic
|
||||
class' virtual functions::
|
||||
|
||||
//
|
||||
// interface to wrap:
|
||||
//
|
||||
class Base
|
||||
{
|
||||
public:
|
||||
virtual int f(std::string x) { return 42; }
|
||||
virtual ~Base();
|
||||
};
|
||||
|
||||
int calls_f(Base const& b, std::string x) { return b.f(x); }
|
||||
|
||||
//
|
||||
// Wrapping Code
|
||||
//
|
||||
|
||||
// Dispatcher class
|
||||
struct BaseWrap : Base
|
||||
{
|
||||
// Store a pointer to the Python object
|
||||
BaseWrap(PyObject* self_) : self(self_) {}
|
||||
PyObject* self;
|
||||
|
||||
// Default implementation, for when f is not overridden
|
||||
int f_default(std::string x) { return this->Base::f(x); }
|
||||
// Dispatch implementation
|
||||
int f(std::string x) { return call_method<int>(self, "f", x); }
|
||||
};
|
||||
|
||||
...
|
||||
def("calls_f", calls_f);
|
||||
class_<Base, BaseWrap>("Base")
|
||||
.def("f", &Base::f, &BaseWrap::f_default)
|
||||
;
|
||||
|
||||
Now here's some Python code which demonstrates: ::
|
||||
|
||||
>>> class Derived(Base):
|
||||
... def f(self, s):
|
||||
... return len(s)
|
||||
...
|
||||
>>> calls_f(Base(), 'foo')
|
||||
42
|
||||
>>> calls_f(Derived(), 'forty-two')
|
||||
9
|
||||
|
||||
Things to notice about the dispatcher class:
|
||||
|
||||
* The key element which allows overriding in Python is the
|
||||
``call_method`` invocation, which uses the same global type
|
||||
conversion registry as the C++ function wrapping does to convert its
|
||||
arguments from C++ to Python and its return type from Python to C++.
|
||||
|
||||
* Any constructor signatures you wish to wrap must be replicated with
|
||||
an initial ``PyObject*`` argument
|
||||
|
||||
* The dispatcher must store this argument so that it can be used to
|
||||
invoke ``call_method``
|
||||
|
||||
* The ``f_default`` member function is needed when the function being
|
||||
exposed is not pure virtual; there's no other way ``Base::f`` can be
|
||||
called on an object of type ``BaseWrap``, since it overrides ``f``.
|
||||
|
||||
Deeper Reflection on the Horizon?
|
||||
=================================
|
||||
|
||||
Admittedly, this formula is tedious to repeat, especially on a project
|
||||
with many polymorphic classes. That it is neccessary reflects some
|
||||
limitations in C++'s compile-time introspection capabilities: there's
|
||||
no way to enumerate the members of a class and find out which are
|
||||
virtual functions. At least one very promising project has been
|
||||
started to write a front-end which can generate these dispatchers (and
|
||||
other wrapping code) automatically from C++ headers.
|
||||
|
||||
Pyste_ is being developed by Bruno da Silva de Oliveira. It builds on
|
||||
GCC_XML_, which generates an XML version of GCC's internal program
|
||||
representation. Since GCC is a highly-conformant C++ compiler, this
|
||||
ensures correct handling of the most-sophisticated template code and
|
||||
full access to the underlying type system. In keeping with the
|
||||
Boost.Python philosophy, a Pyste interface description is neither
|
||||
intrusive on the code being wrapped, nor expressed in some unfamiliar
|
||||
language: instead it is a 100% pure Python script. If Pyste is
|
||||
successful it will mark a move away from wrapping everything directly
|
||||
in C++ for many of our users. It will also allow us the choice to
|
||||
shift some of the metaprogram code from C++ to Python. We expect that
|
||||
soon, not only our users but the Boost.Python developers themselves
|
||||
will be "thinking hybrid" about their own code.
|
||||
|
||||
.. _`GCC_XML`: http://www.gccxml.org/HTML/Index.html
|
||||
.. _`Pyste`: http://www.boost.org/libs/python/pyste
|
||||
|
||||
---------------
|
||||
Serialization
|
||||
---------------
|
||||
|
||||
*Serialization* is the process of converting objects in memory to a
|
||||
form that can be stored on disk or sent over a network connection. The
|
||||
serialized object (most often a plain string) can be retrieved and
|
||||
converted back to the original object. A good serialization system will
|
||||
automatically convert entire object hierarchies. Python's standard
|
||||
``pickle`` module is just such a system. It leverages the language's strong
|
||||
runtime introspection facilities for serializing practically arbitrary
|
||||
user-defined objects. With a few simple and unintrusive provisions this
|
||||
powerful machinery can be extended to also work for wrapped C++ objects.
|
||||
Here is an example::
|
||||
|
||||
#include <string>
|
||||
|
||||
struct World
|
||||
{
|
||||
World(std::string a_msg) : msg(a_msg) {}
|
||||
std::string greet() const { return msg; }
|
||||
std::string msg;
|
||||
};
|
||||
|
||||
#include <boost/python.hpp>
|
||||
using namespace boost::python;
|
||||
|
||||
struct World_picklers : pickle_suite
|
||||
{
|
||||
static tuple
|
||||
getinitargs(World const& w) { return make_tuple(w.greet()); }
|
||||
};
|
||||
|
||||
BOOST_PYTHON_MODULE(hello)
|
||||
{
|
||||
class_<World>("World", init<std::string>())
|
||||
.def("greet", &World::greet)
|
||||
.def_pickle(World_picklers())
|
||||
;
|
||||
}
|
||||
|
||||
Now let's create a ``World`` object and put it to rest on disk::
|
||||
|
||||
>>> import hello
|
||||
>>> import pickle
|
||||
>>> a_world = hello.World("howdy")
|
||||
>>> pickle.dump(a_world, open("my_world", "w"))
|
||||
|
||||
In a potentially *different script* on a potentially *different
|
||||
computer* with a potentially *different operating system*::
|
||||
|
||||
>>> import pickle
|
||||
>>> resurrected_world = pickle.load(open("my_world", "r"))
|
||||
>>> resurrected_world.greet()
|
||||
'howdy'
|
||||
|
||||
Of course the ``cPickle`` module can also be used for faster
|
||||
processing.
|
||||
|
||||
Boost.Python's ``pickle_suite`` fully supports the ``pickle`` protocol
|
||||
defined in the standard Python documentation. Like a __getinitargs__
|
||||
function in Python, the pickle_suite's getinitargs() is responsible for
|
||||
creating the argument tuple that will be use to reconstruct the pickled
|
||||
object. The other elements of the Python pickling protocol,
|
||||
__getstate__ and __setstate__ can be optionally provided via C++
|
||||
getstate and setstate functions. C++'s static type system allows the
|
||||
library to ensure at compile-time that nonsensical combinations of
|
||||
functions (e.g. getstate without setstate) are not used.
|
||||
|
||||
Enabling serialization of more complex C++ objects requires a little
|
||||
more work than is shown in the example above. Fortunately the
|
||||
``object`` interface (see next section) greatly helps in keeping the
|
||||
code manageable.
|
||||
|
||||
------------------
|
||||
Object interface
|
||||
------------------
|
||||
|
||||
Experienced 'C' language extension module authors will be familiar
|
||||
with the ubiquitous ``PyObject*``, manual reference-counting, and the
|
||||
need to remember which API calls return "new" (owned) references or
|
||||
"borrowed" (raw) references. These constraints are not just
|
||||
cumbersome but also a major source of errors, especially in the
|
||||
presence of exceptions.
|
||||
|
||||
Boost.Python provides a class ``object`` which automates reference
|
||||
counting and provides conversion to Python from C++ objects of
|
||||
arbitrary type. This significantly reduces the learning effort for
|
||||
prospective extension module writers.
|
||||
|
||||
Creating an ``object`` from any other type is extremely simple::
|
||||
|
||||
object s("hello, world"); // s manages a Python string
|
||||
|
||||
``object`` has templated interactions with all other types, with
|
||||
automatic to-python conversions. It happens so naturally that it's
|
||||
easily overlooked::
|
||||
|
||||
object ten_Os = 10 * s[4]; // -> "oooooooooo"
|
||||
|
||||
In the example above, ``4`` and ``10`` are converted to Python objects
|
||||
before the indexing and multiplication operations are invoked.
|
||||
|
||||
The ``extract<T>`` class template can be used to convert Python objects
|
||||
to C++ types::
|
||||
|
||||
double x = extract<double>(o);
|
||||
|
||||
If a conversion in either direction cannot be performed, an
|
||||
appropriate exception is thrown at runtime.
|
||||
|
||||
The ``object`` type is accompanied by a set of derived types
|
||||
that mirror the Python built-in types such as ``list``, ``dict``,
|
||||
``tuple``, etc. as much as possible. This enables convenient
|
||||
manipulation of these high-level types from C++::
|
||||
|
||||
dict d;
|
||||
d["some"] = "thing";
|
||||
d["lucky_number"] = 13;
|
||||
list l = d.keys();
|
||||
|
||||
This almost looks and works like regular Python code, but it is pure
|
||||
C++. Of course we can wrap C++ functions which accept or return
|
||||
``object`` instances.
|
||||
|
||||
=================
|
||||
Thinking hybrid
|
||||
=================
|
||||
|
||||
Because of the practical and mental difficulties of combining
|
||||
programming languages, it is common to settle a single language at the
|
||||
outset of any development effort. For many applications, performance
|
||||
considerations dictate the use of a compiled language for the core
|
||||
algorithms. Unfortunately, due to the complexity of the static type
|
||||
system, the price we pay for runtime performance is often a
|
||||
significant increase in development time. Experience shows that
|
||||
writing maintainable C++ code usually takes longer and requires *far*
|
||||
more hard-earned working experience than developing comparable Python
|
||||
code. Even when developers are comfortable working exclusively in
|
||||
compiled languages, they often augment their systems by some type of
|
||||
ad hoc scripting layer for the benefit of their users without ever
|
||||
availing themselves of the same advantages.
|
||||
|
||||
Boost.Python enables us to *think hybrid*. Python can be used for
|
||||
rapidly prototyping a new application; its ease of use and the large
|
||||
pool of standard libraries give us a head start on the way to a
|
||||
working system. If necessary, the working code can be used to
|
||||
discover rate-limiting hotspots. To maximize performance these can
|
||||
be reimplemented in C++, together with the Boost.Python bindings
|
||||
needed to tie them back into the existing higher-level procedure.
|
||||
|
||||
Of course, this *top-down* approach is less attractive if it is clear
|
||||
from the start that many algorithms will eventually have to be
|
||||
implemented in C++. Fortunately Boost.Python also enables us to
|
||||
pursue a *bottom-up* approach. We have used this approach very
|
||||
successfully in the development of a toolbox for scientific
|
||||
applications. The toolbox started out mainly as a library of C++
|
||||
classes with Boost.Python bindings, and for a while the growth was
|
||||
mainly concentrated on the C++ parts. However, as the toolbox is
|
||||
becoming more complete, more and more newly added functionality can be
|
||||
implemented in Python.
|
||||
|
||||
.. image:: python_cpp_mix.jpg
|
||||
|
||||
This figure shows the estimated ratio of newly added C++ and Python
|
||||
code over time as new algorithms are implemented. We expect this
|
||||
ratio to level out near 70% Python. Being able to solve new problems
|
||||
mostly in Python rather than a more difficult statically typed
|
||||
language is the return on our investment in Boost.Python. The ability
|
||||
to access all of our code from Python allows a broader group of
|
||||
developers to use it in the rapid development of new applications.
|
||||
|
||||
=====================
|
||||
Development history
|
||||
=====================
|
||||
|
||||
The first version of Boost.Python was developed in 2000 by Dave
|
||||
Abrahams at Dragon Systems, where he was privileged to have Tim Peters
|
||||
as a guide to "The Zen of Python". One of Dave's jobs was to develop
|
||||
a Python-based natural language processing system. Since it was
|
||||
eventually going to be targeting embedded hardware, it was always
|
||||
assumed that the compute-intensive core would be rewritten in C++ to
|
||||
optimize speed and memory footprint [#proto]_. The project also wanted to
|
||||
test all of its C++ code using Python test scripts [#test]_. The only
|
||||
tool we knew of for binding C++ and Python was SWIG_, and at the time
|
||||
its handling of C++ was weak. It would be false to claim any deep
|
||||
insight into the possible advantages of Boost.Python's approach at
|
||||
this point. Dave's interest and expertise in fancy C++ template
|
||||
tricks had just reached the point where he could do some real damage,
|
||||
and Boost.Python emerged as it did because it filled a need and
|
||||
because it seemed like a cool thing to try.
|
||||
|
||||
This early version was aimed at many of the same basic goals we've
|
||||
described in this paper, differing most-noticeably by having a
|
||||
slightly more cumbersome syntax and by lack of special support for
|
||||
operator overloading, pickling, and component-based development.
|
||||
These last three features were quickly added by Ullrich Koethe and
|
||||
Ralf Grosse-Kunstleve [#feature]_, and other enthusiastic contributors arrived
|
||||
on the scene to contribute enhancements like support for nested
|
||||
modules and static member functions.
|
||||
|
||||
By early 2001 development had stabilized and few new features were
|
||||
being added, however a disturbing new fact came to light: Ralf had
|
||||
begun testing Boost.Python on pre-release versions of a compiler using
|
||||
the EDG_ front-end, and the mechanism at the core of Boost.Python
|
||||
responsible for handling conversions between Python and C++ types was
|
||||
failing to compile. As it turned out, we had been exploiting a very
|
||||
common bug in the implementation of all the C++ compilers we had
|
||||
tested. We knew that as C++ compilers rapidly became more
|
||||
standards-compliant, the library would begin failing on more
|
||||
platforms. Unfortunately, because the mechanism was so central to the
|
||||
functioning of the library, fixing the problem looked very difficult.
|
||||
|
||||
Fortunately, later that year Lawrence Berkeley and later Lawrence
|
||||
Livermore National labs contracted with `Boost Consulting`_ for support
|
||||
and development of Boost.Python, and there was a new opportunity to
|
||||
address fundamental issues and ensure a future for the library. A
|
||||
redesign effort began with the low level type conversion architecture,
|
||||
building in standards-compliance and support for component-based
|
||||
development (in contrast to version 1 where conversions had to be
|
||||
explicitly imported and exported across module boundaries). A new
|
||||
analysis of the relationship between the Python and C++ objects was
|
||||
done, resulting in more intuitive handling for C++ lvalues and
|
||||
rvalues.
|
||||
|
||||
The emergence of a powerful new type system in Python 2.2 made the
|
||||
choice of whether to maintain compatibility with Python 1.5.2 easy:
|
||||
the opportunity to throw away a great deal of elaborate code for
|
||||
emulating classic Python classes alone was too good to pass up. In
|
||||
addition, Python iterators and descriptors provided crucial and
|
||||
elegant tools for representing similar C++ constructs. The
|
||||
development of the generalized ``object`` interface allowed us to
|
||||
further shield C++ programmers from the dangers and syntactic burdens
|
||||
of the Python 'C' API. A great number of other features including C++
|
||||
exception translation, improved support for overloaded functions, and
|
||||
most significantly, CallPolicies for handling pointers and
|
||||
references, were added during this period.
|
||||
|
||||
In October 2002, version 2 of Boost.Python was released. Development
|
||||
since then has concentrated on improved support for C++ runtime
|
||||
polymorphism and smart pointers. Peter Dimov's ingenious
|
||||
``boost::shared_ptr`` design in particular has allowed us to give the
|
||||
hybrid developer a consistent interface for moving objects back and
|
||||
forth across the language barrier without loss of information. At
|
||||
first, we were concerned that the sophistication and complexity of the
|
||||
Boost.Python v2 implementation might discourage contributors, but the
|
||||
emergence of Pyste_ and several other significant feature
|
||||
contributions have laid those fears to rest. Daily questions on the
|
||||
Python C++-sig and a backlog of desired improvements show that the
|
||||
library is getting used. To us, the future looks bright.
|
||||
|
||||
.. _`EDG`: http://www.edg.com
|
||||
|
||||
=============
|
||||
Conclusions
|
||||
=============
|
||||
|
||||
Boost.Python achieves seamless interoperability between two rich and
|
||||
complimentary language environments. Because it leverages template
|
||||
metaprogramming to introspect about types and functions, the user
|
||||
never has to learn a third syntax: the interface definitions are
|
||||
written in concise and maintainable C++. Also, the wrapping system
|
||||
doesn't have to parse C++ headers or represent the type system: the
|
||||
compiler does that work for us.
|
||||
|
||||
Computationally intensive tasks play to the strengths of C++ and are
|
||||
often impossible to implement efficiently in pure Python, while jobs
|
||||
like serialization that are trivial in Python can be very difficult in
|
||||
pure C++. Given the luxury of building a hybrid software system from
|
||||
the ground up, we can approach design with new confidence and power.
|
||||
|
||||
===========
|
||||
Citations
|
||||
===========
|
||||
|
||||
.. [VELD1995] T. Veldhuizen, "Expression Templates," C++ Report,
|
||||
Vol. 7 No. 5 June 1995, pp. 26-31.
|
||||
http://osl.iu.edu/~tveldhui/papers/Expression-Templates/exprtmpl.html
|
||||
|
||||
===========
|
||||
Footnotes
|
||||
===========
|
||||
|
||||
.. [#proto] In retrospect, it seems that "thinking hybrid" from the
|
||||
ground up might have been better for the NLP system: the
|
||||
natural component boundaries defined by the pure python
|
||||
prototype turned out to be inappropriate for getting the
|
||||
desired performance and memory footprint out of the C++ core,
|
||||
which eventually caused some redesign overhead on the Python
|
||||
side when the core was moved to C++.
|
||||
|
||||
.. [#test] We also have some reservations about driving all C++
|
||||
testing through a Python interface, unless that's the only way
|
||||
it will be ultimately used. Any transition across language
|
||||
boundaries with such different object models can inevitably
|
||||
mask bugs.
|
||||
|
||||
.. [#feature] These features were expressed very differently in v1 of
|
||||
Boost.Python
|
||||
|
||||
@@ -54,7 +54,7 @@ modules or the executable containing `main()`.
|
||||
[section No-Install Quickstart]
|
||||
|
||||
There is no need to “install Boost” in order to get started using
|
||||
Boost.Python. These instructions use [@http://boost.org/build] projects,
|
||||
Boost.Python. These instructions use _bb_ projects,
|
||||
which will build those binaries as soon as they're needed. Your
|
||||
first tests may take a little longer while you wait for
|
||||
Boost.Python to build, but doing things this way will save you from
|
||||
@@ -69,9 +69,9 @@ compiler options to use yourself.
|
||||
build system* without first following these instructions.
|
||||
|
||||
If you want to use another system anyway, we suggest that you
|
||||
follow these instructions, and then invoke ``bjam`` with the
|
||||
follow these instructions, and then invoke `bjam` with the
|
||||
|
||||
`-a -o`\ *filename*
|
||||
`-a -o`\ /filename/
|
||||
|
||||
options to dump the build commands it executes to a file, so
|
||||
you can see what your alternate build system needs to do.]
|
||||
@@ -91,19 +91,19 @@ compiler options to use yourself.
|
||||
to see the output generated by the tests when they are run.
|
||||
On Windows, your `bjam` invocation might look something like:
|
||||
``
|
||||
C:\\boost_1_34_0\\...\\quickstart> bjam toolset=msvc --verbose-test test
|
||||
C:\\...\\quickstart> bjam toolset=msvc --verbose-test test
|
||||
``
|
||||
and on Unix variants, perhaps,
|
||||
``
|
||||
~/boost_1_34_0/.../quickstart$ bjam toolset=gcc --verbose-test test
|
||||
.../quickstart$ bjam toolset=gcc --verbose-test test
|
||||
``
|
||||
|
||||
[note For the sake of concision, the rest of this guide will use
|
||||
unix-style forward slashes in pathnames instead of the
|
||||
backslashes with which Windows users may be more familiar. The forward
|
||||
slashes should work everywhere except in
|
||||
[@http://www.boost.org/more/getting_started/windows.html#command-prompt Command Prompt windows],
|
||||
where you should use backslashes.]
|
||||
[@http://www.boost.org/more/getting_started/windows.html#command-prompt
|
||||
Command Prompt] windows, where you should use backslashes.]
|
||||
|
||||
If you followed this procedure successfully, you will have built an
|
||||
extension module called `extending` and tested it by running a
|
||||
@@ -178,11 +178,11 @@ For example, if you moved the project from
|
||||
`/home/dave/my-project`, you could change the first path in
|
||||
`boost-build.jam` from
|
||||
``
|
||||
../../../../tools/build/v2
|
||||
../../../../tools/build/src
|
||||
``
|
||||
to
|
||||
``
|
||||
/home/dave/boost_1_34_0/tools/build/v2
|
||||
/home/dave/boost_1_34_0/tools/build/src
|
||||
``
|
||||
and change the first path in `Jamroot` from
|
||||
``
|
||||
@@ -212,8 +212,8 @@ tell Boost.Build about it by editing the name in `Jamroot`.
|
||||
|
||||
The name of the extension module is determined by two things:
|
||||
|
||||
1. the name in `Jamroot` immediately following `python-extension`, and
|
||||
2. the name passed to ``BOOST_PYTHON_MODULE`` in `extending.cpp`.
|
||||
# the name in `Jamroot` immediately following `python-extension`, and
|
||||
# the name passed to `BOOST_PYTHON_MODULE` in `extending.cpp`.
|
||||
|
||||
To change the name of the extension module from `extending` to
|
||||
`hello`, you'd edit `Jamroot`, changing
|
||||
@@ -235,6 +235,7 @@ to
|
||||
``
|
||||
[endsect]
|
||||
[endsect]
|
||||
[endsect]
|
||||
[section Installing Boost.Python on your System]
|
||||
|
||||
Since Boost.Python is a separately-compiled (as opposed to
|
||||
@@ -252,7 +253,7 @@ rather than all the Boost binaries.
|
||||
[endsect]
|
||||
[section Configuring Boost.Build]
|
||||
|
||||
As described in the _reference_, a file called
|
||||
As described in the [@http://www.boost.org/build/doc/html/bbv2/overview/configuration.html Boost.Build Reference Manual], a file called
|
||||
`user-config.jam` in your home directory is used to
|
||||
specify the tools and libraries available to the build system. You
|
||||
may need to create or edit `user-config.jam` to tell Boost.Build
|
||||
@@ -284,59 +285,60 @@ method). If instead you are linking against separately-compiled
|
||||
Boost.Python binaries, you should set up a `user-config.jam` file
|
||||
with at least the minimal incantation above.
|
||||
|
||||
[endsect]
|
||||
[section Python Configuration Parameters]
|
||||
|
||||
If you have several versions of Python installed, or Python is
|
||||
installed in an unusual way, you may want to supply any or all of
|
||||
the following optional parameters to `using python`.
|
||||
|
||||
* *version*
|
||||
[variablelist
|
||||
[[version]
|
||||
|
||||
the version of Python to use. Should be in Major.Minor
|
||||
[the version of Python to use. Should be in Major.Minor
|
||||
format, for example, `2.3`. Do not include the subminor
|
||||
version (i.e. *not* `2.5.1`). If you have multiple Python
|
||||
versions installed, the version will usually be the only
|
||||
configuration argument required.
|
||||
configuration argument required.]]
|
||||
|
||||
* *cmd-or-prefix*
|
||||
[[cmd-or-prefix]
|
||||
|
||||
preferably, a command that invokes a Python interpreter.
|
||||
[preferably, a command that invokes a Python interpreter.
|
||||
Alternatively, the installation prefix for Python libraries and
|
||||
header files. Only use the alternative formulation if there is
|
||||
no appropriate Python executable available.
|
||||
no appropriate Python executable available.]]
|
||||
|
||||
* *includes*
|
||||
[[*includes*]
|
||||
|
||||
the `#include` paths for Python headers. Normally the correct
|
||||
[the `#include` paths for Python headers. Normally the correct
|
||||
path(s) will be automatically deduced from `version` and/or
|
||||
`cmd-or-prefix`.
|
||||
`cmd-or-prefix`.]]
|
||||
|
||||
* *libraries*
|
||||
[[*libraries*]
|
||||
|
||||
the path to Python library binaries. On MacOS/Darwin,
|
||||
[the path to Python library binaries. On MacOS/Darwin,
|
||||
you can also pass the path of the Python framework. Normally the
|
||||
correct path(s) will be automatically deduced from `version`
|
||||
and/or `cmd-or-prefix`.
|
||||
and/or `cmd-or-prefix`.]]
|
||||
|
||||
* *condition*
|
||||
[[*condition*]
|
||||
|
||||
if specified, should be a set of Boost.Build
|
||||
[if specified, should be a set of Boost.Build
|
||||
properties that are matched against the build configuration when
|
||||
Boost.Build selects a Python configuration to use. See examples
|
||||
below for details.
|
||||
below for details.]]
|
||||
|
||||
* *extension-suffix*
|
||||
[[*extension-suffix*]
|
||||
|
||||
A string to append to the name of extension
|
||||
[A string to append to the name of extension
|
||||
modules before the true filename extension. You almost certainly
|
||||
don't need to use this. Usually this suffix is only used when
|
||||
targeting a Windows debug build of Python, and will be set
|
||||
automatically for you based on the value of the
|
||||
|python-debugging|_ feature. However, at least one Linux
|
||||
distribution (Ubuntu Feisty Fawn) has a specially configured
|
||||
[@https://wiki.ubuntu.com/PyDbgBuilds <python-debugging>] package
|
||||
that claims to use such a suffix.
|
||||
[link building.python_debugging_builds <python-debugging>] feature.
|
||||
However, at least one Linux distribution (Ubuntu Feisty Fawn) has
|
||||
a specially configured [@https://wiki.ubuntu.com/PyDbgBuilds <python-dbg>]
|
||||
package that claims to use such a suffix.]]
|
||||
]
|
||||
|
||||
[endsect]
|
||||
[section Examples]
|
||||
@@ -381,8 +383,8 @@ significant.
|
||||
``
|
||||
|
||||
* If you have downloaded the Python sources and built both the
|
||||
normal and the “\ `python debugging`_\ ” builds from source on
|
||||
Windows, you might see:
|
||||
normal and the [link building.python_debugging_builds "python debugging"]
|
||||
builds from source on Windows, you might see:
|
||||
|
||||
``
|
||||
using python : 2.5 : C:\\src\\Python-2.5\\PCBuild\\python ;
|
||||
@@ -443,8 +445,8 @@ library, you'll need to think about which one to link with. The
|
||||
Boost.Python binary comes in both static and dynamic flavors. Take
|
||||
care to choose the right flavor for your application. [footnote
|
||||
Information about how to identify the static and dynamic builds of Boost.Python on
|
||||
[@http://boost.org/getting_started/windows.html#library-naming Windows] /
|
||||
[@http://boost.org/getting_started/unix-variants.html#library-naming Unix variants]]
|
||||
[@http://boost.org/more/getting_started/windows.html#library-naming Windows] /
|
||||
[@http://boost.org/more/getting_started/unix-variants.html#library-naming Unix variants]]
|
||||
|
||||
[section The Dynamic Binary]
|
||||
|
||||
@@ -475,12 +477,12 @@ The dynamic library is the safest and most-versatile choice:
|
||||
It might be appropriate to use the static Boost.Python library in
|
||||
any of the following cases:
|
||||
|
||||
* You are extending python and the types exposed in your
|
||||
* You are _extending_ python and the types exposed in your
|
||||
dynamically-loaded extension module don't need to be used by any
|
||||
other Boost.Python extension modules, and you don't care if the
|
||||
core library code is duplicated among them.
|
||||
|
||||
* You are embedding python in your application and either:
|
||||
* You are _embedding_ python in your application and either:
|
||||
|
||||
* You are targeting a Unix variant OS other than MacOS or AIX,
|
||||
where the dynamically-loaded extension modules can “see” the
|
||||
@@ -506,7 +508,7 @@ any of the following cases:
|
||||
`wrap_python.hpp`. This restriction is actually imposed by
|
||||
Python, or more properly, by Python's interaction with your
|
||||
operating system. See
|
||||
http://docs.python.org/ext/simpleExample.html for details.
|
||||
[@http://docs.python.org/ext/simpleExample.html] for details.
|
||||
|
||||
[endsect]
|
||||
[section Python Debugging Builds]
|
||||
@@ -521,7 +523,7 @@ vice-versa.*
|
||||
|
||||
Since pre-built “python debugging” versions of the Python
|
||||
executable and libraries are not supplied with most distributions
|
||||
of Python, [#get-debug-build]_ and we didn't want to force our users
|
||||
of Python, [footnote On Unix and similar platforms, a debugging python and associated libraries are built by adding --with-pydebug when configuring the Python build. On Windows, the debugging version of Python is generated by the "Win32 Debug" target of the Visual Studio project in the PCBuild subdirectory of a full Python source code distribution.] and we didn't want to force our users
|
||||
to build them, Boost.Build does not automatically enable python
|
||||
debugging in its `debug` build variant (which is the default).
|
||||
Instead there is a special build property called
|
||||
@@ -535,7 +537,7 @@ On many windows compilers, when extension modules are built with
|
||||
the preprocessor symbol `_DEBUG`, Python defaults to force
|
||||
linking with a special debugging version of the Python DLL. Since
|
||||
that symbol is very commonly used even when Python is not present,
|
||||
Boost.Python temporarily undefines _DEBUG when Python.h
|
||||
Boost.Python temporarily undefines `_DEBUG` when `Python.h`
|
||||
is #included from `boost/python/detail/wrap_python.hpp` - unless
|
||||
`BOOST_DEBUG_PYTHON` is defined. The upshot is that if you want
|
||||
“python debugging”and you aren't using Boost.Build, you should make
|
||||
@@ -556,8 +558,9 @@ prior to 3.0.0 (with binutils-2.13.90-20030111-1), you will need to
|
||||
create a MinGW-compatible version of the Python library; the one
|
||||
shipped with Python will only work with a Microsoft-compatible
|
||||
linker. Follow the instructions in the “Non-Microsoft” section of
|
||||
the “Building Extensions: Tips And Tricks” chapter in [@http://www.python.org/doc/current/inst/index.html Installing Python Modules] to create `libpythonXX.a`, where `XX`
|
||||
corresponds to the major and minor version numbers of your Python
|
||||
installation.
|
||||
the “Building Extensions: Tips And Tricks” chapter in
|
||||
[@https://docs.python.org/2/install/index.html Installing Python Modules]
|
||||
to create `libpythonXX.a`, where `XX` corresponds to the major and minor
|
||||
version numbers of your Python installation.
|
||||
|
||||
[endsect]
|
||||
|
||||
@@ -9,12 +9,12 @@
|
||||
[section Configuration]
|
||||
|
||||
[section Introduction]
|
||||
*Boost.Python* uses several configuration macros in `<boost/config.hpp>`, as well as configuration macros meant to be supplied by the application. These macros are documented here.
|
||||
[*Boost.Python] uses several configuration macros in `<boost/config.hpp>`, as well as configuration macros meant to be supplied by the application. These macros are documented here.
|
||||
|
||||
[endsect]
|
||||
[section Application Defined Macros]
|
||||
|
||||
These are the macros that may be defined by an application using Boost.Python. Note that if you extend a strict interpretation of the C++ standard to cover dynamic libraries, using different values of these macros when compiling different libraries (including extension modules and the Boost.Python library itself) is a violation of the ODR. However, we know of no C++ implementations on which this particular violation is detectable or causes any problems.
|
||||
These are the macros that may be defined by an application using Boost.Python. Note that if you extend a strict interpretation of the C++ standard to cover dynamic libraries, using different values of these macros when compiling different libraries (including extension modules and the Boost.Python library itself) is a violation of the [link odr ODR]. However, we know of no C++ implementations on which this particular violation is detectable or causes any problems.
|
||||
|
||||
[table
|
||||
[[Macro][Default][Meaning]]
|
||||
@@ -49,7 +49,7 @@ These are the macros that may be defined by an application using Boost.Python. N
|
||||
]
|
||||
[endsect]
|
||||
[section Library Defined Defined Macros]
|
||||
|
||||
These macros are defined by *Boost.Python* and are implementation details of interest only to implementors and those porting to new platforms.
|
||||
[table
|
||||
[[Macro][Default][Meaning]]
|
||||
[[BOOST_PYTHON_TYPE_ID_NAME][ /not defined/ ]
|
||||
|
||||
39
doc/faq.qbk
39
doc/faq.qbk
@@ -1,4 +1,4 @@
|
||||
[chapter FAQ
|
||||
[chapter Frequently Asked Questions (FAQs)
|
||||
[quickbook 1.7]
|
||||
[id faq]
|
||||
]
|
||||
@@ -79,25 +79,24 @@ situation at runtime and helpfully throws an exception instead of letting
|
||||
you do that.
|
||||
|
||||
[endsect]
|
||||
[section Is return_internal_reference efficient?]
|
||||
[section Is `return_internal_reference` efficient?]
|
||||
|
||||
[*Q:] /I have an object composed of 12 doubles. A const& to
|
||||
[*Q:] /I have an object composed of 12 doubles. A `const&` to
|
||||
this object is returned by a member function of another class. From the
|
||||
viewpoint of using the returned object in Python I do not care if I get
|
||||
a copy or a reference to the returned object. In Boost.Python Version 2
|
||||
I have the choice of using copy_const_reference or
|
||||
return_internal_reference. Are there considerations that would lead me
|
||||
to prefer one over the other, such as size of generated code or memory
|
||||
overhead?/
|
||||
a copy or a reference to the returned object. In Boost.Python I have the
|
||||
choice of using `copy_const_reference` or `return_internal_reference`.
|
||||
Are there considerations that would lead me to prefer one over the other,
|
||||
such as size of generated code or memory overhead?/
|
||||
|
||||
[*A:] `copy_const_reference` will make an instance with storage
|
||||
for one of your objects, size = base_size + 12 * sizeof(double).
|
||||
return_internal_reference will make an instance with storage for a
|
||||
pointer to one of your objects, size = base_size + sizeof(void*).
|
||||
for one of your objects, `size = base_size + 12 * sizeof(double)`.
|
||||
`return_internal_reference` will make an instance with storage for a
|
||||
pointer to one of your objects, `size = base_size + sizeof(void*)`.
|
||||
However, it will also create a weak reference object which goes in the
|
||||
source object's weakreflist and a special callback object to manage the
|
||||
lifetime of the internally-referenced object. My guess?
|
||||
copy_const_reference is your friend here, resulting in less overall
|
||||
`copy_const_reference` is your friend here, resulting in less overall
|
||||
memory use and less fragmentation, also probably fewer total
|
||||
cycles.
|
||||
|
||||
@@ -113,8 +112,8 @@ Ralf W. Grosse-Kunstleve provides these notes:
|
||||
...
|
||||
;
|
||||
``
|
||||
This can be moved to a template so that several types (double, int,
|
||||
long, etc.) can be wrapped with the same code. This technique is used
|
||||
This can be moved to a template so that several types (`double`, `int`,
|
||||
`long`, etc.) can be wrapped with the same code. This technique is used
|
||||
in the file `scitbx/include/scitbx/array_family/boost_python/flex_wrapper.h`
|
||||
in the "scitbx" package. The file could easily be modified for
|
||||
wrapping `std::vector<>` instantiations.
|
||||
@@ -157,7 +156,7 @@ C++:
|
||||
}
|
||||
}
|
||||
``
|
||||
Python:
|
||||
Python: [python]
|
||||
``
|
||||
>>> l = [1, 2, 3]
|
||||
>>> foo(l)
|
||||
@@ -187,7 +186,7 @@ CVS:
|
||||
|
||||
# Break your source file up into multiple translation units.
|
||||
|
||||
`my_module.cpp`:
|
||||
`my_module.cpp`: [c++]
|
||||
|
||||
``
|
||||
...
|
||||
@@ -208,7 +207,7 @@ CVS:
|
||||
...
|
||||
}
|
||||
``
|
||||
If you find that a [link reference.class-spec class_]<...> declaration
|
||||
If you find that a `class_<...>` declaration
|
||||
can't fit in a single source file without triggering the error, you
|
||||
can always pass a reference to the `class_` object to a
|
||||
function in another source file, and call some of its member
|
||||
@@ -522,7 +521,7 @@ Then make a thin wrapper function which takes an auto_ptr parameter:
|
||||
a.release();
|
||||
}
|
||||
``
|
||||
Wrap that as B.add. Note that pointers returned via [link reference.manage_new_object manage_new_object]
|
||||
Wrap that as B.add. Note that pointers returned via `manage_new_object`
|
||||
will also be held by `auto_ptr`, so this transfer-of-ownership
|
||||
will also work correctly.
|
||||
|
||||
@@ -530,12 +529,12 @@ will also work correctly.
|
||||
[section Compilation takes too much time and eats too much memory!
|
||||
What can I do to make it faster?]
|
||||
|
||||
Please refer to the [link tutorial.python.reducing_compiling_time Reducing Compiling Time] section in the tutorial.
|
||||
Please refer to the `Reducing Compiling Time` section in the _tutorial_.
|
||||
|
||||
[endsect]
|
||||
[section How do I create sub-packages using Boost.Python?]
|
||||
|
||||
Please refer to the [link tutorial.python.creating_packages Creating Packages] section in the tutorial.
|
||||
Please refer to the `Creating Packages` section in the _tutorial_.
|
||||
|
||||
[endsect]
|
||||
[section error C2064: term does not evaluate to a function taking 2 arguments]
|
||||
|
||||
@@ -1,22 +1,23 @@
|
||||
[chapter Glossary
|
||||
[quickbook 1.7]
|
||||
[id glossary]
|
||||
]
|
||||
|
||||
[variablelist
|
||||
[[arity]
|
||||
[[arity [#arity]]
|
||||
[The number of argumnts accepted by a function or member function.
|
||||
Unless otherwise specified, the hidden `this` argument to member
|
||||
functions is not counted when specifying arity.]]
|
||||
[[ntbs]
|
||||
[[ntbs [#ntbs]]
|
||||
[Null-Terminated Byte String, or 'C'-string. C++ string literals are *ntbs*\ es.
|
||||
An *ntbs* must never be null.]]
|
||||
[[raise]
|
||||
[[raise [#raise]]
|
||||
[Exceptions in Python are "raised", not "thrown", as they are in C++.
|
||||
When this documentation says that some Python exception is "raised" in
|
||||
the context of C++ code, it means that the corresponding Python exception
|
||||
is set via the [@http://www.python.org/doc/current/api/exceptionHandling.html Python/'C' API],
|
||||
and [link reference.errors.throw_error_already_set throw_error_already_set()] is called.]]
|
||||
[[POD]
|
||||
and `throw_error_already_set()` is called.]]
|
||||
[[POD [#pod]]
|
||||
[A technical term from the C++ standard. Short for "Plain Ol'Data":
|
||||
A POD-struct is an aggregate class that has no non-static data members
|
||||
of type pointer to member, non-POD-struct, non-POD-union (or array of such
|
||||
@@ -30,7 +31,7 @@
|
||||
constructors (12.1), no private or protected non-static data members
|
||||
(clause 11), no base classes (clause 10), and no virtual functions
|
||||
(10.3).]]
|
||||
[[ODR]
|
||||
[[ODR [#odr]]
|
||||
[The "One Definition Rule", which says that any entity in a C++ program must have
|
||||
the same definition in all translation units (object files) which make up a program.]]
|
||||
]
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
[def _tutorial_ [@tutorial/index.html Tutorial]]
|
||||
[def _reference_ [@reference/index.html Reference Manual]]
|
||||
[def _gsg_ Boost [@http://www.boost.org/more/getting_started/ Getting Started Guide]]
|
||||
[def _extending_ [@https://docs.python.org/2/extending/extending.html extending]]
|
||||
[def _embedding_ [@https://docs.python.org/2/extending/embedding.html embedding]]
|
||||
|
||||
[h2 Synopsis]
|
||||
|
||||
@@ -37,7 +39,7 @@ Welcome to Boost.Python, a C++ library which enables seamless interoperability b
|
||||
* Exporting C++ Iterators as Python Iterators
|
||||
* Documentation Strings
|
||||
|
||||
The development of these features was funded in part by grants to [@http://www.boost-consulting.com Boost Consulting] from the [@http://www.llnl.gov Lawrence Livermore National Laboratories] and by the [@http://cci.lbl.gov Computational Crystallography Initiative] at Lawrence Berkeley National Laboratories.
|
||||
The development of these features was funded in part by grants to `Boost Consulting` from the [@http://www.llnl.gov Lawrence Livermore National Laboratories] and by the [@http://cci.lbl.gov Computational Crystallography Initiative] at Lawrence Berkeley National Laboratories.
|
||||
|
||||
[section Contents]
|
||||
|
||||
@@ -53,7 +55,7 @@ The development of these features was funded in part by grants to [@http://www.b
|
||||
|
||||
[h2 Articles]
|
||||
|
||||
"Building Hybrid Systems With Boost Python", by Dave Abrahams and Ralf W. Grosse-Kunstleve (PDF)
|
||||
[@bpl.html Building Hybrid Systems With Boost Python], by Dave Abrahams and Ralf W. Grosse-Kunstleve ([@bpl.pdf PDF])
|
||||
|
||||
[include building.qbk]
|
||||
[include configuration.qbk]
|
||||
|
||||
@@ -2,12 +2,7 @@
|
||||
[quickbook 1.7]
|
||||
[authors [Abrahams, David], [Seefeld, Stefan]]
|
||||
[copyright 2002 2003 2004 2005 2015 David Abrahams, Stefan Seefeld]
|
||||
[category inter-language support]
|
||||
[id reference]
|
||||
[dirname reference]
|
||||
[purpose
|
||||
Reflects C++ classes and functions into Python
|
||||
]
|
||||
[license
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -23,3 +18,4 @@
|
||||
[include reference/embedding.qbk]
|
||||
[include reference/utility.qbk]
|
||||
[include reference/topics.qbk]
|
||||
[include glossary.qbk]
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
[section args.hpp]
|
||||
[section boost/python/args.hpp]
|
||||
[section Introduction]
|
||||
Supplies a family of overloaded functions for specifying argument keywords for wrapped C++ functions.
|
||||
[section keyword-expressions]
|
||||
A keyword-expression results in an object which holds a sequence of ntbses, and whose type encodes the number of keywords specified. The keyword-expression may contain default values for some or all of the keywords it holds
|
||||
A keyword-expression results in an object which holds a sequence of [link ntbs]\ es, and whose type encodes the number of keywords specified. The keyword-expression may contain default values for some or all of the keywords it holds
|
||||
[endsect]
|
||||
[endsect]
|
||||
[section Class `arg`]
|
||||
@@ -23,7 +23,7 @@ namespace boost { namespace python
|
||||
[section Class `arg` constructor]
|
||||
``arg(char const* name);``
|
||||
[variablelist
|
||||
[[Requires][The argument must be a ntbs.]]
|
||||
[[Requires][The argument must be a [link ntbs].]]
|
||||
[[Effects][Constructs an arg object holding a keyword with name name.]]
|
||||
]
|
||||
[endsect]
|
||||
@@ -41,7 +41,7 @@ keyword-expression operator , (keyword-expression, const arg &kw) const
|
||||
keyword-expression operator , (keyword-expression, const char *name) const;
|
||||
``
|
||||
[variablelist
|
||||
[[Requires][The argument name must be a ntbs.]]
|
||||
[[Requires][The argument name must be a [link ntbs].]]
|
||||
[[Effects][Extends the keyword-expression argument with one more keyword.]]
|
||||
[[Returns][The extended keyword-expression.]]
|
||||
]
|
||||
@@ -55,9 +55,7 @@ int f(double x, double y, double z=0.0, double w=1.0);
|
||||
|
||||
BOOST_PYTHON_MODULE(xxx)
|
||||
{
|
||||
def("f", f
|
||||
, ( arg("x"), "y", arg("z")=0.0, arg("w")=1.0 )
|
||||
);
|
||||
def("f", f, (arg("x"), "y", arg("z")=0.0, arg("w")=1.0));
|
||||
}
|
||||
``
|
||||
[endsect]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[section call.hpp]
|
||||
[section boost/python/call.hpp]
|
||||
[section Introduction]
|
||||
<boost/python/call.hpp> defines the call family of overloaded function templates, used to invoke Python callable objects from C++.
|
||||
[endsect]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[section call_method.hpp]
|
||||
[section boost/python/call_method.hpp]
|
||||
[section Introduction]
|
||||
<boost/python/call_method.hpp> defines the call_method family of overloaded function templates, used to invoke callable attributes of Python objects from C++.
|
||||
[endsect]
|
||||
@@ -8,14 +8,14 @@ template <class R, class A1, class A2, ... class An>
|
||||
R call_method(PyObject* self, char const* method, A1 const&, A2 const&, ... An const&)
|
||||
``
|
||||
[variablelist
|
||||
[[Requires][R is a pointer type, reference type, or a complete type with an accessible copy constructor]]
|
||||
[[Effects][Invokes self.method(a1, a2, ...an) in Python, where a1...an are the arguments to call_method(), converted to Python objects. For a complete semantic description, see this page.]]
|
||||
[[Returns][The result of the Python call, converted to the C++ type R.]]
|
||||
[[Rationale][call_method is critical to implementing C++ virtual functions which are overridable in Python, as shown by the example below.]]
|
||||
[[Requires][`R` is a pointer type, reference type, or a complete type with an accessible copy constructor]]
|
||||
[[Effects][Invokes `self.method(a1, a2, ...an)` in Python, where `a1...an` are the arguments to `call_method()`, converted to Python objects. For a complete semantic description, see this page.]]
|
||||
[[Returns][The result of the Python call, converted to the C++ type `R`.]]
|
||||
[[Rationale][`call_method` is critical to implementing C++ virtual functions which are overridable in Python, as shown by the example below.]]
|
||||
]
|
||||
[endsect]
|
||||
[section Example]
|
||||
The following C++ illustrates the use of call_method in wrapping a class with a virtual function that can be overridden in Python:
|
||||
The following C++ illustrates the use of `call_method` in wrapping a class with a virtual function that can be overridden in Python:
|
||||
C++ Module Definition
|
||||
``
|
||||
#include <boost/python/module.hpp>
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
[section Calling Python Functions and Methods]
|
||||
[section Introduction]
|
||||
The simplest way to call a Python function from C++, given an object instance f holding the function, is simply to invoke its function call operator.
|
||||
The simplest way to call a Python function from C++, given an [link object_wrappers.boost_python_object_hpp.class_object `object`] instance f holding the function, is simply to invoke its function call operator.
|
||||
``f("tea", 4, 2) // In Python: f('tea', 4, 2)``
|
||||
And of course, a method of an object instance x can be invoked by using the function-call operator of the corresponding attribute:
|
||||
And of course, a method of an [link object_wrappers.boost_python_object_hpp.class_object `object`] instance `x` can be invoked by using the function-call operator of the corresponding attribute:
|
||||
``x.attr("tea")(4, 2); // In Python: x.tea(4, 2)``
|
||||
If you don't have an object instance, Boost.Python provides two families of function templates, call and call_method, for invoking Python functions and methods respectively on PyObject*s. The interface for calling a Python function object (or any Python callable object) looks like:
|
||||
If you don't have an [link object_wrappers.boost_python_object_hpp.class_object `object`] instance, `Boost.Python` provides two families of function templates, [link function_invocation_and_creation.boost_python_call_hpp.function_call `call`] and [link function_invocation_and_creation.boost_python_call_method_hpp.function_call_method `call_method`], for invoking Python functions and methods respectively on `PyObject*`\ s. The interface for calling a Python function object (or any Python callable object) looks like:
|
||||
``call<ResultType>(callable_object, a1, a2... aN);``
|
||||
Calling a method of a Python object is similarly easy:
|
||||
``call_method<ResultType>(self_object, "method-name", a1, a2... aN);``
|
||||
This comparitively low-level interface is the one you'll use when implementing C++ virtual functions that can be overridden in Python.
|
||||
[endsect]
|
||||
[section Argument Handling]
|
||||
Arguments are converted to Python according to their type. By default, the arguments a1...aN are copied into new Python objects, but this behavior can be overridden by the use of ptr() and ref():
|
||||
Arguments are converted to Python according to their type. By default, the arguments `a1...aN` are copied into new Python objects, but this behavior can be overridden by the use of [link function_invocation_and_creation.boost_python_ptr_hpp.functions `ptr()`] and `ref()`:
|
||||
``
|
||||
class X : boost::noncopyable
|
||||
{
|
||||
@@ -36,7 +36,7 @@ void apply(PyObject* callable, X& x)
|
||||
]
|
||||
[endsect]
|
||||
[section Result Handling]
|
||||
In general, call<ResultType>() and call_method<ResultType>() return ResultType by exploiting all lvalue and rvalue from_python converters registered for ResultType and returning a copy of the result. However, when ResultType is a pointer or reference type, Boost.Python searches only for lvalue converters. To prevent dangling pointers and references, an exception will be thrown if the Python result object has only a single reference count.
|
||||
In general, `call<ResultType>()` and call_method<ResultType>() return ResultType by exploiting all lvalue and rvalue from_python converters registered for ResultType and returning a copy of the result. However, when ResultType is a pointer or reference type, Boost.Python searches only for lvalue converters. To prevent dangling pointers and references, an exception will be thrown if the Python result object has only a single reference count.
|
||||
[endsect]
|
||||
[section Rationale]
|
||||
In general, to get Python arguments corresponding to a1...aN, a new Python object must be created for each one; should the C++ object be copied into that Python object, or should the Python object simply hold a reference/pointer to the C++ object? In general, the latter approach is unsafe, since the called function may store a reference to the Python object somewhere. If the Python object is used after the C++ object is destroyed, we'll crash Python.
|
||||
@@ -54,12 +54,12 @@ As for results, we have a similar problem: if ResultType is allowed to be a poin
|
||||
|
||||
The old Boost.Python v1 deals with this issue by refusing to compile any uses of call<char const*>(), but this goes both too far and not far enough. It goes too far because there are cases where the owning Python string object survives beyond the call (just for instance, when it's the name of a Python class), and it goes not far enough because we might just as well have the same problem with a returned pointer or reference of any other type.
|
||||
|
||||
In Boost.Python v2 this is dealt with by:
|
||||
In Boost.Python this is dealt with by:
|
||||
|
||||
# lifting the compile-time restriction on const char* callback returns
|
||||
# lifting the compile-time restriction on `char const *` callback returns
|
||||
# detecting the case when the reference count on the result Python object is 1 and throwing an
|
||||
exception inside of call<U>(...) when U is a pointer or reference type.
|
||||
exception inside of `call<U>(...)` when `U` is a pointer or reference type.
|
||||
|
||||
This should be acceptably safe because users have to explicitly specify a pointer/reference for U in call<U>, and they will be protected against dangles at runtime, at least long enough to get out of the call<U>(...) invocation.
|
||||
This should be acceptably safe because users have to explicitly specify a pointer/reference for `U` in `call<U>`, and they will be protected against dangles at runtime, at least long enough to get out of the `call<U>(...)` invocation.
|
||||
[endsect]
|
||||
[endsect]
|
||||
|
||||
@@ -1,27 +1,26 @@
|
||||
[section class.hpp]
|
||||
[section boost/python/class.hpp]
|
||||
[section 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.
|
||||
[endsect]
|
||||
[section Classes]
|
||||
[section 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.
|
||||
[table
|
||||
[[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`.]
|
||||
[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 that is actually embedded in a Python object wrapping a `T` instance when `T`\ 's constructor is called or when a `T` or `T*` is converted to Python without the use of `ptr`, `ref`, or Call Policies such as `return_internal_reference`. More details below.][`T`]]
|
||||
[A specialization of [link high_level_components.boost_python_class_hpp.class_template_bases_t1_t2_tn bases<...>] which specifies previously-exposed C++ base classes of `T`.]
|
||||
[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`.][[link high_level_components.boost_python_class_hpp.class_template_bases_t1_t2_tn bases<>]]]
|
||||
[[HeldType][Must be `T`, a class derived from `T`, or a [link concepts.dereferenceable.concept_requirements Dereferenceable] type for which `pointee<HeldType>::type` is `T` or a class derived from `T`.][Specifies the type that is actually embedded in a Python object wrapping a `T` instance when `T`\ 's constructor is called or when a `T` or `T*` is converted to Python without the use of [link function_invocation_and_creation.boost_python_ptr_hpp.functions ptr], `ref`, or [link concepts.callpolicies Call Policies] such as [link function_invocation_and_creation.models_of_callpolicies.boost_python_return_internal_ref.class_template_return_internal_r return_internal_reference]. 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.]]
|
||||
]
|
||||
[section HeldType Semantics]
|
||||
|
||||
# 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.
|
||||
# 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 [link high_level_components.boost_python_init_hpp.introduction.init_expressions init-expression] passed to [link high_level_components.boost_python_class_hpp.class_template_class_t_bases_hel.class_template_class_modifier_fu 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.
|
||||
# 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>`.
|
||||
# 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.
|
||||
# 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>`.
|
||||
# Except in cases 1 and 3, users may optionally specify that T itself gets initialized with a similar initial `PyObject*` argument by specializing [link utility_and_infrastructure.boost_python_has_back_reference_.class_template_has_back_referenc has_back_reference<T>].
|
||||
|
||||
[endsect]
|
||||
[section Class template `class_` synopsis]
|
||||
@@ -114,11 +113,12 @@ Creates a Python class associated with the C++ type passed as its first paramete
|
||||
``
|
||||
|
||||
[variablelist
|
||||
[[Requires][name is an 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.
|
||||
* If supplied, the value of docstring is bound to the `__doc__` attribute of the extension class.
|
||||
* If `init_spec` is `no_init`, a special `__init__` function is generated which always raises a Python exception. Otherwise, `this->def(init_spec)` is called.
|
||||
* If `init_spec` is not supplied, `this->def(init<>())` is called.]]
|
||||
[[Requires][name is an [link ntbs] which conforms to Python's [@http://www.python.org/doc/current/ref/identifiers.html identifier naming rules]. If docstring is supplied, it must be an [link ntbs]. If `init_spec` is supplied, it must be either the special enumeration constant `no_init` or an [link high_level_components.boost_python_init_hpp.introduction.init_expressions init-expression] compatible with `T`.]]
|
||||
[[Effects][Constructs a `class_` object holding a Boost.Python extension class named name. The named attribute of the [link high_level_components.boost_python_scope_hpp.introduction current scope] is bound to the new extension class.
|
||||
|
||||
* If supplied, the value of docstring is bound to the `__doc__` attribute of the extension class.
|
||||
* If `init_spec` is `no_init`, a special `__init__` function is generated which always raises a Python exception. Otherwise, `this->def(init_spec)` is called.
|
||||
* If `init_spec` is not supplied, `this->def(init<>())` is called.]]
|
||||
[[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.]]
|
||||
]
|
||||
[endsect]
|
||||
@@ -129,8 +129,8 @@ Creates a Python class associated with the C++ type passed as its first paramete
|
||||
``
|
||||
|
||||
[variablelist
|
||||
[[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.]]
|
||||
[[Requires][`init_expr` is the result of an [link high_level_components.boost_python_init_hpp.introduction.init_expressions init-expression] compatible with `T`.]]
|
||||
[[Effects][For each [link high_level_components.boost_python_init_hpp.introduction.init_expressions 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 [link high_level_components.boost_python_init_hpp.introduction.init_expressions 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.]]
|
||||
]
|
||||
@@ -145,42 +145,51 @@ Creates a Python class associated with the C++ type passed as its first paramete
|
||||
class_& def(char const* name, Fn fn, A1 const& a1, A2 const& a2, A3 const& a3);
|
||||
``
|
||||
[variablelist
|
||||
[[Requires][name is an ntbs which conforms to Python's identifier naming rules.
|
||||
* If a1 is the result of an overload-dispatch-expression, only the second form is allowed and fn must be a pointer to function or pointer to member function whose arity is the same as A1's maximum arity.
|
||||
[[Requires][name is an [link ntbs] which conforms to Python's [@http://www.python.org/doc/current/ref/identifiers.html identifier naming rules].
|
||||
* If a1 is the result of an [link function_invocation_and_creation.boost_python_overloads_hpp.introduction.overload_dispatch_expressions overload-dispatch-expression], only the second form is allowed and fn must be a pointer to function or pointer to member function whose [link arity] is the same as A1's [link function_invocation_and_creation.boost_python_overloads_hpp.introduction.overload_dispatch_expressions maximum arity].
|
||||
|
||||
[*Effects:] For each prefix P of Fn's sequence of argument types, beginning with the one whose length is A1's minimum arity, adds a name(...) method overload to the extension class. Each overload generated invokes a1's call-expression with P, using a copy of a1's call policies. If the longest valid prefix of A1 contains N types and a1 holds M keywords, an initial sequence of the keywords are used for all but the first N - M arguments of each overload.
|
||||
[*Effects:] For each prefix `P` of `Fn`\ 's sequence of argument types, beginning with the one whose length is `A1`\ 's [link function_invocation_and_creation.boost_python_overloads_hpp.introduction.overload_dispatch_expressions minimum arity], adds a `name(...)` method overload to the extension class. Each overload generated invokes a1's call-expression with `P`, using a copy of a1's call policies. If the longest valid prefix of `A1` contains `N` types and a1 holds `M` keywords, an initial sequence of the keywords are used for all but the first `N - M` arguments of each overload.
|
||||
|
||||
* Otherwise, a single method overload is built around fn, which must not be null:
|
||||
|
||||
* If fn is a function pointer, its first argument must be of the form U, U cv&, U cv*, or U cv* const&, where T* is convertible to U*, and a1-a3, if supplied, may be selected in any order from the table below.
|
||||
* Otherwise, if fn is a member function pointer, its target must be T or one of its public base classes, and a1-a3, if supplied, may be selected in any order from the table below.
|
||||
* Otherwise, Fn must be [derived from] object, and a1-a2, if supplied, may be selcted in any order from the first two rows of the table below. To be useful, fn should be callable.
|
||||
* Otherwise, Fn must be [derived from] [link object_wrappers.boost_python_object_hpp.class_object object], and a1-a2, if supplied, may be selcted in any order from the first two rows of the table below. To be useful, fn should be [@http://www.python.org/doc/current/lib/built-in-funcs.html#l2h-6 callable].
|
||||
[table
|
||||
[[Mnemonic Name][Requirements/Type properties][Effects]]
|
||||
[[docstring][Any ntbs][Value will be bound to the __doc__ attribute of the resulting method overload. If an earlier overload supplied a docstring, two newline characters and the new docstring are appended to it.]]
|
||||
[[policies][A model of CallPolicies][A copy will be used as the call policies of the resulting method overload.]]
|
||||
[[keywords][The result of a keyword-expression specifying no more arguments than the arity of fn.][A copy will be used as the call policies of the resulting method overload.]]
|
||||
[[docstring][Any [link ntbs]][Value will be bound to the __doc__ attribute of the resulting method overload. If an earlier overload supplied a docstring, two newline characters and the new docstring are appended to it.]]
|
||||
[[policies][A model of [link concepts.callpolicies CallPolicies]][A copy will be used as the call policies of the resulting method overload.]]
|
||||
[[keywords][The result of a [link function_invocation_and_creation.boost_python_args_hpp.introduction.keyword_expressions keyword-expression] specifying no more arguments than the [link arity] of fn.][A copy will be used as the call policies of the resulting method overload.]]
|
||||
]
|
||||
]]
|
||||
[[Returns][`*this`]]
|
||||
]
|
||||
``class_& staticmethod(char const* name);``
|
||||
[variablelist
|
||||
[[Requires][name is an ntbs which conforms to Python's identifier naming rules, and corresponds to a method whose overloads have all been defined.]]
|
||||
[[Effects][Replaces the existing named attribute x with the result of invoking staticmethod(x) in Python. Specifies that the corresponding method is static and therefore no object instance will be passed to it. This is equivalent to the Python statement:]]
|
||||
[[Requires][name is an [link ntbs] which conforms to Python's [@http://www.python.org/doc/current/ref/identifiers.html identifier naming rules], and corresponds to a method whose overloads have all been defined.]]
|
||||
[[Effects][Replaces the existing named attribute `x` with the result of invoking `staticmethod(x)` in Python. Specifies that the corresponding method is static and therefore no object instance will be passed to it. This is equivalent to the Python statement:]]
|
||||
]
|
||||
``setattr(self, name, staticmethod(getattr(self, name)))``
|
||||
[variablelist
|
||||
[[Note][Attempting to invoke def(name,...) after invoking staticmethod(name) will raise a RuntimeError.]]
|
||||
[[Note][Attempting to invoke def(name,...) after invoking staticmethod(name) will [link raise] a RuntimeError.]]
|
||||
[[Returns][`*this`]]
|
||||
]
|
||||
``
|
||||
template <unspecified>
|
||||
class_& def(detail::operator_<unspecified>);
|
||||
``
|
||||
[variablelist
|
||||
[[Effects][Adds a Python [@http://www.python.org/doc/ref/specialnames.html special method] as described [link high_level_components.boost_python_operators_hpp here].]]
|
||||
[[Returns][`*this`]]
|
||||
]
|
||||
|
||||
``
|
||||
template <class U>
|
||||
class_& setattr(char const* name, U const& u);
|
||||
``
|
||||
[variablelist
|
||||
[[Requires][name is an 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:
|
||||
[[Requires][name is an [link ntbs] which conforms to Python's [@http://www.python.org/doc/current/ref/identifiers.html 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`]]
|
||||
]
|
||||
@@ -192,8 +201,8 @@ Creates a Python class associated with the C++ type passed as its first paramete
|
||||
char const* name, Get const& fget, Set const& fset, char const* doc=0);
|
||||
``
|
||||
[variablelist
|
||||
[[Requires][name is an ntbs which conform to Python's identifier naming rules.]]
|
||||
[[Effects][Creates a new Python property class instance, passing object(fget) (and object(fset) in the second form) with an (optional) docstring doc to its constructor, then adds that property to the Python class object under construction with the given attribute name.]]
|
||||
[[Requires][name is an [link ntbs] which conform to Python's [@http://www.python.org/doc/current/ref/identifiers.html identifier naming rules].]]
|
||||
[[Effects][Creates a new Python [@http://www.python.org/2.2.2/descrintro.html#property property] class instance, passing `object(fget)` (and `object(fset)` in the second form) with an (optional) docstring `doc` 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.]]
|
||||
]
|
||||
@@ -204,8 +213,8 @@ Creates a Python class associated with the C++ type passed as its first paramete
|
||||
void add_static_property(char const* name, Get const& fget, Set const& fset);
|
||||
``
|
||||
[variablelist
|
||||
[[Requires][name is an ntbs which conforms to Python's identifier naming rules.]]
|
||||
[[Effects][Creates a Boost.Python.StaticProperty object, passing object(fget) (and object(fset) in the second form) to its constructor, then adds that property to the Python class under construction with the given attribute name. StaticProperty is a special subclass of Python's property class which can be called without an initial self argument.]]
|
||||
[[Requires][name is an [link ntbs] which conforms to Python's [@http://www.python.org/doc/current/ref/identifiers.html identifier naming rules].]]
|
||||
[[Effects][Creates a Boost.Python.StaticProperty object, passing `object(fget)` (and `object(fset)` in the second form) to its constructor, then adds that property to the Python class under construction with the given attribute name. StaticProperty is a special subclass of Python's property class which can be called without an initial self argument.]]
|
||||
[[Returns][`*this`]]
|
||||
[[Rationale][Allows users to easily expose functions that can be invoked from Python with static attribute access syntax.]]
|
||||
]
|
||||
@@ -216,7 +225,7 @@ Creates a Python class associated with the C++ type passed as its first paramete
|
||||
class_& def_readonly(char const* name, D const& d);
|
||||
``
|
||||
[variablelist
|
||||
[[Requires][name is an ntbs which conforms to Python's identifier naming rules. doc is also an ntbs.]]
|
||||
[[Requires][name is an [link ntbs] which conforms to Python's [@http://www.python.org/doc/current/ref/identifiers.html identifier naming rules]. `doc` is also an [link ntbs].]]
|
||||
[[Effects][``this->add_property(name, make_getter(pm), doc);`` and ``this->add_static_property(name, make_getter(d));`` respectively.]]
|
||||
[[Returns][`*this`]]
|
||||
[[Rationale][Allows users to easily expose a class' data member or free variable such that it can be inspected from Python with a natural syntax.]]
|
||||
@@ -237,10 +246,10 @@ Creates a Python class associated with the C++ type passed as its first paramete
|
||||
class_& def_pickle(PickleSuite const&);
|
||||
``
|
||||
[variablelist
|
||||
[[Requires][PickleSuite must be publically derived from pickle_suite.]]
|
||||
[[Requires][PickleSuite must be publically derived from [link topics.pickle_support.the_pickle_interface pickle_suite].]]
|
||||
[[Effects][Defines a legal combination of the special attributes and methods: __getinitargs__, __getstate__, __setstate__, __getstate_manages_dict__, __safe_for_unpickling__, __reduce__]]
|
||||
[[Returns][`*this`]]
|
||||
[[Rationale][Provides an easy to use high-level interface for establishing complete pickle support for the wrapped class. The user is protected by compile-time consistency checks.]]
|
||||
[[Rationale][Provides an [link topics.pickle_support.the_pickle_interface easy to use high-level interface] for establishing complete [link topics.pickle_support.the_pickle_interface pickle support] for the wrapped class. The user is protected by compile-time consistency checks.]]
|
||||
]
|
||||
``class_& enable_pickling();``
|
||||
[variablelist
|
||||
@@ -263,7 +272,6 @@ namespace boost { namespace python
|
||||
``
|
||||
[endsect]
|
||||
[endsect]
|
||||
[endsect]
|
||||
[section Examples]
|
||||
Given a C++ class declaration:
|
||||
``
|
||||
|
||||
@@ -19,53 +19,53 @@ providing three behaviors:
|
||||
|
||||
In order to allow the use of multiple models of CallPolicies in the same callable object,
|
||||
Boost.Python's CallPolicies class templates provide a chaining interface which allows them to be
|
||||
recursively composed. This interface takes the form of an optional template parameter, Base which
|
||||
defaults to default_call_policies. By convention, the precall function of the Base is invoked after
|
||||
the precall function supplied by the outer template, and the postcall function of the Base is invoked
|
||||
before the postcall function of the outer template. If a result_converter is supplied by the outer
|
||||
template, it replaces any result_converter supplied by the Base. For an example, see
|
||||
return_internal_reference.
|
||||
recursively composed. This interface takes the form of an optional template parameter, `Base`, which
|
||||
defaults to `default_call_policies`. By convention, the `precall` function of the `Base` is invoked after
|
||||
the `precall` function supplied by the `outer` template, and the `postcall` function of the `Base` is invoked
|
||||
before the `postcall` function of the `outer` template. If a `result_converter` is supplied by the `outer`
|
||||
template, it replaces any `result_converter` supplied by the `Base`. For an example, see
|
||||
`return_internal_reference`.
|
||||
|
||||
[endsect]
|
||||
[section Concept Requirements]
|
||||
[table
|
||||
[[Expression][Type][Result/Semantics]]
|
||||
[[`x.precall(a)`][convertible to bool]
|
||||
[returns false and PyErr_Occurred() != 0 upon failure, true otherwise.]]
|
||||
[[`P::result_converter`][A model of ResultConverterGenerator.]
|
||||
[[`x.precall(a)`][convertible to `bool`]
|
||||
[returns `false` and `PyErr_Occurred() != 0` upon failure, `true` otherwise.]]
|
||||
[[`P::result_converter`][A model of `ResultConverterGenerator`.]
|
||||
[An MPL unary Metafunction Class used produce the "preliminary" result object.]]
|
||||
[[`x.postcall(a, r)`][convertible to PyObject*]
|
||||
[0 0 and PyErr_Occurred() != 0 upon failure. Must "conserve references" even in the event of an exception. In other words, if r is not returned, its reference count must be decremented; if another existing object is returned, its reference count must be incremented.]]
|
||||
[[`x.postcall(a, r)`][convertible to `PyObject*`]
|
||||
[`0` and `PyErr_Occurred() != 0` upon failure. Must "conserve references" even in the event of an exception. In other words, if `r` is not returned, its reference count must be decremented; if another existing object is returned, its reference count must be incremented.]]
|
||||
[[`P::extract_return_type`][A model of Metafunction.]
|
||||
[An MPL unary Metafunction used extract the return type from a given signature. By default it is derived from mpl::front.]]
|
||||
[An MPL unary Metafunction used extract the return type from a given signature. By default it is derived from `mpl::front`.]]
|
||||
]
|
||||
[endsect]
|
||||
[endsect]
|
||||
[section Dereferenceable]
|
||||
[section Introduction]
|
||||
Instances of a Dereferenceable type can be used like a pointer to access an lvalue.
|
||||
Instances of a `Dereferenceable` type can be used like a pointer to access an lvalue.
|
||||
[endsect]
|
||||
[section Concept Requirements]
|
||||
In the table below, T is a model of Dereferenceable, and x denotes an object of type T. In addition, all pointers are Dereferenceable.
|
||||
In the table below, `T` is a model of Dereferenceable, and `x` denotes an object of type `T`. In addition, all pointers are `Dereferenceable`.
|
||||
[table
|
||||
[[Expression][Result][Operational Semantics]]
|
||||
[[`get_pointer(x)`][convertible to pointee<T>::type*]
|
||||
[&*x, or a null pointer ]]
|
||||
[[`get_pointer(x)`][convertible to `pointee<T>::type*`]
|
||||
[`&*x`, or a null pointer ]]
|
||||
]
|
||||
[endsect]
|
||||
[endsect]
|
||||
[section Extractor]
|
||||
[section Introduction]
|
||||
An Extractor is a class which Boost.Python can use to extract C++ objects from Python objects, and is typically used by facilities that define from_python conversions for "traditional" Python extension types.
|
||||
An Extractor is a class which Boost.Python can use to extract C++ objects from Python objects, and is typically used by facilities that define `from_python` conversions for "traditional" Python extension types.
|
||||
[endsect]
|
||||
[section Concept Requirements]
|
||||
In the table below, X denotes a model of Extractor and a denotes an instance of a Python object type.
|
||||
In the table below, `X` denotes a model of `Extractor` and `a` denotes an instance of a Python object type.
|
||||
[table
|
||||
[[Expression][Type][Semantics]]
|
||||
[[`X::execute(a)`][non-void ]
|
||||
[[`X::execute(a)`][non-void]
|
||||
[Returns the C++ object being extracted. The execute function must not be overloaded.]]
|
||||
[[`&a.ob_type`][PyTypeObject**]
|
||||
[Points to the ob_type field of an object which is layout-compatible with PyObject]]
|
||||
[[`&a.ob_type`][`PyTypeObject**`]
|
||||
[Points to the `ob_type` field of an object which is layout-compatible with `PyObject`]]
|
||||
]
|
||||
[endsect]
|
||||
[section Notes]
|
||||
@@ -77,36 +77,36 @@ Informally, an Extractor's execute member must be a non-overloaded static functi
|
||||
A HolderGenerator is a unary metafunction class which returns types suitable for holding instances of its argument in a wrapped C++ class instance.
|
||||
[endsect]
|
||||
[section Concept Requirements]
|
||||
In the table below, G denotes an type which models HolderGenerator, and X denotes a class type.
|
||||
In the table below, `G` denotes an type which models `HolderGenerator`, and `X` denotes a class type.
|
||||
[table
|
||||
[[Expression][Requirements]]
|
||||
[[`G::apply<X>::type`][A concrete subclass of instance_holder which can hold objects of type X. ]]
|
||||
[[`G::apply<X>::type`][A concrete subclass of `instance_holder` which can hold objects of type `X`. ]]
|
||||
]
|
||||
[endsect]
|
||||
[endsect]
|
||||
[section ResultConverter]
|
||||
[section Introduction]
|
||||
A ResultConverter for a type T is a type whose instances can be used to convert C++ return values of type T to_python. A ResultConverterGenerator is an MPL unary metafunction class which, given the return type of a C++ function, returns a ResultConverter for that type. ResultConverters in Boost.Python generally inspect library's registry of converters to find a suitable converter, but converters which don't use the registry are also possible.
|
||||
A ResultConverter for a type `T` is a type whose instances can be used to convert C++ return values of type `T` `to_python`. A ResultConverterGenerator is an MPL unary metafunction class which, given the return type of a C++ function, returns a ResultConverter for that type. ResultConverters in Boost.Python generally inspect library's registry of converters to find a suitable converter, but converters which don't use the registry are also possible.
|
||||
[endsect]
|
||||
[section ResultConverter Concept Requirements]
|
||||
In the table below, C denotes a ResultConverter type for a type R , c denotes an object of type C , and r denotes an object of type R.
|
||||
In the table below, `C` denotes a ResultConverter type for a type `R`, `c` denotes an object of type `C`, and `r` denotes an object of type `R`.
|
||||
[table
|
||||
[[Expression][Type][Semantics]]
|
||||
[[`C c`][]
|
||||
[Constructs a c object.]]
|
||||
[[`c.convertible()`][convertible to bool]
|
||||
[false iff no conversion from any R value to a Python object is possible.]]
|
||||
[[`c(r)`][convertible to PyObject*]
|
||||
[A pointer to a Python object corresponding to r, or 0 iff r could not be converted to_python, in which case PyErr_Occurred should return non-zero.]]
|
||||
[[`c.get_pytype()`][PyTypeObject const *]
|
||||
[A pointer to a Python Type object corresponding to result of the conversion, or 0. Used for documentation generation. If 0 is returned the generated type in the documentation will be object .]]
|
||||
[Constructs a `c` object.]]
|
||||
[[`c.convertible()`][convertible to `bool`]
|
||||
[`false` iff no conversion from any `R` value to a Python object is possible.]]
|
||||
[[`c(r)`][convertible to `PyObject*`]
|
||||
[A pointer to a Python object corresponding to `r`, or `0` iff `r` could not be converted `to_python`, in which case `PyErr_Occurred` should return non-zero.]]
|
||||
[[`c.get_pytype()`][`PyTypeObject const *`]
|
||||
[A pointer to a Python Type object corresponding to result of the conversion, or `0`. Used for documentation generation. If `0` is returned the generated type in the documentation will be object.]]
|
||||
]
|
||||
[endsect]
|
||||
[section ResultConverterGenerator Concept Requirements]
|
||||
In the table below, G denotes a ResultConverterGenerator type and R denotes a possible C++ function return type.
|
||||
In the table below, `G` denotes a ResultConverterGenerator type and `R` denotes a possible C++ function return type.
|
||||
[table
|
||||
[[Expression][Requirements]]
|
||||
[[`G::apply<R>::type`][A ResultConverter type for R.]]
|
||||
[[`G::apply<R>::type`][A ResultConverter type for `R`.]]
|
||||
]
|
||||
[endsect]
|
||||
[endsect]
|
||||
@@ -115,20 +115,20 @@ In the table below, G denotes a ResultConverterGenerator type and R denotes a po
|
||||
This page defines two concepts used to describe classes which manage a Python objects, and which are intended to support usage with a Python-like syntax.
|
||||
[endsect]
|
||||
[section ObjectWrapper Concept Requirements]
|
||||
Models of the ObjectWrapper concept have object as a publicly-accessible base class, and are used to supply special construction behavior and/or additional convenient functionality through (often templated) member functions. Except when the return type R is itself an TypeWrapper, a member function invocation of the form ``x.some_function(a1, a2,...an)`` always has semantics equivalent to:
|
||||
``extract<R>(x.attr("some_function")(object(a1), object(a2),...object(an)))()`` (see [link caveat] below).
|
||||
Models of the ObjectWrapper concept have [link object_wrappers.boost_python_object_hpp.class_object object] as a publicly-accessible base class, and are used to supply special construction behavior and/or additional convenient functionality through (often templated) member functions. Except when the return type R is itself an [link concepts.objectwrapper.typewrapper_concept_requirements TypeWrapper], a member function invocation of the form ``x.some_function(a1, a2,...an)`` always has semantics equivalent to:
|
||||
``extract<R>(x.attr("some_function")(object(a1), object(a2),...object(an)))()`` (see [link concepts.objectwrapper.caveat caveat] below).
|
||||
[endsect]
|
||||
[section TypeWrapper Concept Requirements]
|
||||
TypeWrapper is a refinement of ObjectWrapper which is associated with a particular Python type X. For a given TypeWrapper T, a valid constructor expression ``T(a1, a2,...an)`` builds a new T object managing the result of invoking X with arguments corresponding to ``object(a1), object(a2),...object(an)``.
|
||||
When used as arguments to wrapped C++ functions, or as the template parameter to extract<>, only instances of the associated Python type will be considered a match.
|
||||
TypeWrapper is a refinement of [link concepts.objectwrapper.objectwrapper_concept_requiremen ObjectWrapper] which is associated with a particular Python type `X`. For a given TypeWrapper `T`, a valid constructor expression ``T(a1, a2,...an)`` builds a new T object managing the result of invoking X with arguments corresponding to ``object(a1), object(a2),...object(an)``.
|
||||
When used as arguments to wrapped C++ functions, or as the template parameter to [link to_from_python_type_conversion.boost_python_extract_hpp.class_template_extract extract<>], only instances of the associated Python type will be considered a match.
|
||||
[endsect]
|
||||
[section Caveat]
|
||||
The upshot of the special member function invocation rules when the return type is a TypeWrapper is that it is possible for the returned object to manage a Python object of an inappropriate type. This is not usually a serious problem; the worst-case result is that errors will be detected at runtime a little later than they might otherwise be. For an example of how this can occur, note that the dict member function items returns an object of type list. Now suppose the user defines this dict subclass in Python:
|
||||
The upshot of the special member function invocation rules when the return type is a TypeWrapper is that it is possible for the returned object to manage a Python object of an inappropriate type. This is not usually a serious problem; the worst-case result is that errors will be detected at runtime a little later than they might otherwise be. For an example of how this can occur, note that the [link object_wrappers.boost_python_dict_hpp.class_dict dict] member function `items` returns an object of type [link object_wrappers.boost_python_list_hpp.class_list list]. Now suppose the user defines this `dict` subclass in Python:
|
||||
``
|
||||
>>> class mydict(dict):
|
||||
... def items(self):
|
||||
... return tuple(dict.items(self)) # return a tuple
|
||||
``
|
||||
Since an instance of mydict is also an instance of dict, when used as an argument to a wrapped C++ function, boost::python::dict can accept objects of Python type mydict. Invoking items() on this object can result in an instance of boost::python::list which actually holds a Python tuple. Subsequent attempts to use list methods (e.g. append, or any other mutating operation) on this object will raise the same exception that would occur if you tried to do it from Python.
|
||||
Since an instance of `mydict` is also an instance of `dict`, when used as an argument to a wrapped C++ function, [link object_wrappers.boost_python_dict_hpp.class_dict boost::python::dict] can accept objects of Python type `mydict`. Invoking `items()` on this object can result in an instance of [link object_wrappers.boost_python_list_hpp.class_list boost::python::list] which actually holds a Python `tuple`. Subsequent attempts to use `list` methods (e.g. `append`, or any other mutating operation) on this object will raise the same exception that would occur if you tried to do it from Python.
|
||||
[endsect]
|
||||
[endsect]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[section copy_const_reference.hpp]
|
||||
[section boost/python/copy_const_reference.hpp]
|
||||
[section Class `copy_const_reference`]
|
||||
copy_const_reference is a model of ResultConverterGenerator which can be used to wrap C++ functions returning a reference-to-const type such that the referenced value is copied into a new Python object.
|
||||
`copy_const_reference` is a model of [link concepts.resultconverter.resultconvertergenerator_concept ResultConverterGenerator] which can be used to wrap C++ functions returning a reference-to-const type such that the referenced value is copied into a new Python object.
|
||||
``
|
||||
namespace boost { namespace python
|
||||
{
|
||||
@@ -14,8 +14,8 @@ namespace boost { namespace python
|
||||
[section Class `copy_const_reference` metafunctions]
|
||||
``template <class T> struct apply``
|
||||
[variablelist
|
||||
[[Requires][T is U const& for some U.]]
|
||||
[[Returns][typedef to_python_value<T> type;]]
|
||||
[[Requires][`T` is `U const&` for some `U`.]]
|
||||
[[Returns][`typedef to_python_value<T> type;`]]
|
||||
]
|
||||
[endsect]
|
||||
[section Example]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[section copy_non_const_reference.hpp]
|
||||
[section boost/python/copy_non_const_reference.hpp]
|
||||
[section Class `copy_non_const_reference`]
|
||||
copy_non_const_reference is a model of ResultConverterGenerator which can be used to wrap C++ functions returning a reference-to-non-const type such that the referenced value is copied into a new Python object.
|
||||
`copy_non_const_reference` is a model of [link concepts.resultconverter.resultconvertergenerator_concept ResultConverterGenerator] which can be used to wrap C++ functions returning a reference-to-non-const type such that the referenced value is copied into a new Python object.
|
||||
``
|
||||
namespace boost { namespace python
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[section data_members.hpp]
|
||||
[section boost/python/data_members.hpp]
|
||||
[section Introduction]
|
||||
make_getter() and make_setter() are the functions used internally by class_<>::def_readonly and class_<>::def_readwrite to produce Python callable objects which wrap C++ data members.
|
||||
`make_getter()` and `make_setter()` are the functions used internally by [link high_level_components.boost_python_class_hpp.class_template_class_t_bases_hel.class_template_class_modifier_fu `class_<>::def_readonly`] and [link high_level_components.boost_python_class_hpp.class_template_class_t_bases_hel.class_template_class_modifier_fu `class_<>::def_readwrite`] to produce Python callable objects which wrap C++ data members.
|
||||
[endsect]
|
||||
[section Functions]
|
||||
``
|
||||
@@ -11,7 +11,7 @@ template <class C, class D, class Policies>
|
||||
object make_getter(D C::*pm, Policies const& policies);
|
||||
``
|
||||
[variablelist
|
||||
[[Requires][Policies is a model of CallPolicies.]]
|
||||
[[Requires][Policies is a model of [link concepts.callpolicies `CallPolicies`].]]
|
||||
[[Effects][Creates a Python callable object which accepts a single argument that can be converted from_python to C*, and returns the corresponding member D member of the C object, converted to_python. If policies is supplied, it will be applied to the function as described here. Otherwise, the library attempts to determine whether D is a user-defined class type, and if so uses return_internal_reference<>
|
||||
for Policies. Note that this test may inappropriately choose return_internal_reference<> in some cases when D is a smart pointer type. This is a known defect.]]
|
||||
[[Returns][An instance of object which holds the new Python callable object.]]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[section def.hpp]
|
||||
[section boost/python/def.hpp]
|
||||
[section Introduction]
|
||||
`def()` is the function which can be used to expose C++ functions and callable objects as Python functions in the current scope.
|
||||
`def()` is the function which can be used to expose C++ functions and callable objects as Python functions in the [link high_level_components.boost_python_scope_hpp.introduction current scope].
|
||||
[endsect]
|
||||
[section Functions]
|
||||
``
|
||||
@@ -17,20 +17,20 @@ template <class Fn, class A1, class A2, class A3>
|
||||
void def(char const* name, Fn fn, A1 const&, A2 const&, A3 const&);
|
||||
``
|
||||
[variablelist
|
||||
[[Requires][name is an ntbs which conforms to Python's identifier naming rules.
|
||||
[[Requires][name is an [link ntbs] which conforms to Python's [@http://www.python.org/doc/current/ref/identifiers.html identifier naming rules].
|
||||
|
||||
* If `Fn` is [derived from] object, it will be added to the current scope as a single overload. To be useful, fn should be callable.
|
||||
* If a1 is the result of an overload-dispatch-expression, only the second form is allowed and fn must be a pointer to function or pointer to member function whose arity is the same as A1's maximum arity.
|
||||
* If `Fn` is [derived from] [link object_wrappers.boost_python_object_hpp.class_object object], it will be added to the [link high_level_components.boost_python_scope_hpp.introduction current scope] as a single overload. To be useful, `fn` should be [@http://www.python.org/doc/current/lib/built-in-funcs.html#l2h-6 callable].
|
||||
* If `a1` is the result of an [link function_invocation_and_creation.boost_python_overloads_hpp.introduction.overload_dispatch_expressions overload-dispatch-expression], only the second form is allowed and `fn` must be a pointer to function or pointer to member function whose [link arity] is the same as A1's [link function_invocation_and_creation.boost_python_overloads_hpp.introduction.overload_dispatch_expressions maximum arity].
|
||||
|
||||
[*Effects:] For each prefix P of Fn's sequence of argument types, beginning with the one whose length is A1's minimum arity, adds a name(...) function overload to the current scope. Each overload generated invokes a1's call-expression with P, using a copy of a1's call policies. If the longest valid prefix of A1 contains N types and a1 holds M keywords, an initial sequence of the keywords are used for all but the first N - M arguments of each overload.
|
||||
[*Effects:] For each prefix `P` of `Fn`\ 's sequence of argument types, beginning with the one whose length is `A1`\ 's [link function_invocation_and_creation.boost_python_overloads_hpp.introduction.overload_dispatch_expressions minimum arity], adds a `name(...)` function overload to the [link high_level_components.boost_python_scope_hpp.introduction current scope]. Each overload generated invokes a1's call-expression with P, using a copy of a1's call policies. If the longest valid prefix of A1 contains N types and a1 holds M keywords, an initial sequence of the keywords are used for all but the first N - M arguments of each overload.
|
||||
|
||||
* Otherwise, fn must be a non-null function or member function pointer, and a single function overload built around fn is added to the current scope. If any of a1-a3 are supplied, they may be selected in any order from the table below.
|
||||
|
||||
[table
|
||||
[[Mnemonic Name][Requirements/Type properties][Effects]]
|
||||
[[docstring][Any ntbs][Value will be bound to the __doc__ attribute of the resulting method overload.]]
|
||||
[[policies][A model of CallPolicies][A copy will be used as the call policies of the resulting method overload.]]
|
||||
[[keywords][The result of a keyword-expression specifying no more arguments than the arity of fn.][A copy will be used as the call policies of the resulting method overload.]]
|
||||
[[docstring][Any [link ntbs]][Value will be bound to the `__doc__` attribute of the resulting method overload.]]
|
||||
[[policies][A model of [link concepts.callpolicies CallPolicies]][A copy will be used as the call policies of the resulting method overload.]]
|
||||
[[keywords][The result of a [link function_invocation_and_creation.boost_python_args_hpp.introduction.keyword_expressions keyword-expression] specifying no more arguments than the [link arity] of `fn`.][A copy will be used as the call policies of the resulting method overload.]]
|
||||
]
|
||||
]]
|
||||
]
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
[section def_visitor.hpp]
|
||||
[section boost/python/def_visitor.hpp]
|
||||
[section Introduction]
|
||||
<boost/python/def_visitor.hpp> provides a generic visitation interface through which the class_ def member functionality can be extended non-intrusively to avoid cluttering the class_ interface. It declares the def_visitor<T> class template, which is parameterized on the derived type DerivedVisitor, which provides the actual def functionality through its visit member functions.
|
||||
<boost/python/def_visitor.hpp> provides a generic visitation interface through which the [link high_level_components.boost_python_class_hpp.class_template_class_t_bases_hel class_] def member functionality can be extended non-intrusively to avoid cluttering the [link high_level_components.boost_python_class_hpp.class_template_class_t_bases_hel class_] interface. It declares the `def_visitor<T>` class template, which is parameterized on the derived type `DerivedVisitor`, which provides the actual `def` functionality through its `visit` member functions.
|
||||
[endsect]
|
||||
[section Class `def_visitor`]
|
||||
The class def_visitor is a base class paramaterized by its derived class. The def_visitor class is a protocol class. Its derived class, DerivedVisitor, is expected to have a member function visit. The def_visitor class is never instantiated directly. Instead, an instance of its subclass, DerivedVisitor, is passed on as an argument to the class_ def member function.
|
||||
The class `def_visitor` is a base class paramaterized by its derived class. The `def_visitor` class is a protocol class. Its derived class, DerivedVisitor, is expected to have a member function `visit`. The `def_visitor` class is never instantiated directly. Instead, an instance of its subclass, DerivedVisitor, is passed on as an argument to the [link high_level_components.boost_python_class_hpp.class_template_class_t_bases_hel class_] `def` member function.
|
||||
|
||||
``
|
||||
namespace boost { namespace python {
|
||||
@@ -21,11 +21,11 @@ namespace boost { namespace python {
|
||||
[table
|
||||
[[Expression][Return Type][Requirements][Effects]]
|
||||
[[`visitor.visit(cls)`][`void`]
|
||||
[cls is an instance of a class_ being wrapped to Python. visitor is a def_visitor derived class.]
|
||||
[A call to cls.def(visitor) forwards to this member function.]]
|
||||
[`cls` is an instance of a [link high_level_components.boost_python_class_hpp.class_template_class_t_bases_hel class_] being wrapped to Python. `visitor` is a `def_visitor` derived class.]
|
||||
[A call to `cls.def(visitor)` forwards to this member function.]]
|
||||
[[`visitor.visit(cls, name, options)`][`void`]
|
||||
[cls is a class_ instance, name is a C string. visitor is a def_visitor derived class. options is a context specific optional argument.]
|
||||
[A call to cls.def(name, visitor) or cls.def(name, visitor, options) forwards to this member function. ]]]
|
||||
[`cls` is a [link high_level_components.boost_python_class_hpp.class_template_class_t_bases_hel class_] instance, name is a C string. `visitor` is a `def_visitor` derived class. options is a context specific optional argument.]
|
||||
[A call to `cls.def(name, visitor)` or `cls.def(name, visitor, options)` forwards to this member function. ]]]
|
||||
]]
|
||||
]
|
||||
[endsect]
|
||||
@@ -35,26 +35,23 @@ class X {/*...*/};
|
||||
|
||||
class my_def_visitor : boost::python::def_visitor<my_def_visitor>
|
||||
{
|
||||
friend class def_visitor_access;
|
||||
friend class def_visitor_access;
|
||||
|
||||
template <class classT>
|
||||
void visit(classT& c) const
|
||||
{
|
||||
c
|
||||
.def("foo", &my_def_visitor::foo)
|
||||
.def("bar", &my_def_visitor::bar)
|
||||
;
|
||||
}
|
||||
template <class classT>
|
||||
void visit(classT& c) const
|
||||
{
|
||||
c.def("foo", &my_def_visitor::foo);
|
||||
c.def("bar", &my_def_visitor::bar);
|
||||
}
|
||||
|
||||
static void foo(X& self);
|
||||
static void bar(X& self);
|
||||
static void foo(X& self);
|
||||
static void bar(X& self);
|
||||
};
|
||||
|
||||
BOOST_PYTHON_MODULE(my_ext)
|
||||
{
|
||||
class_<X>("X")
|
||||
.def(my_def_visitor())
|
||||
;
|
||||
class_<X>("X")
|
||||
.def(my_def_visitor());
|
||||
}
|
||||
``
|
||||
[endsect]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[section default_call_policies.hpp]
|
||||
[section boost/python/default_call_policies.hpp]
|
||||
[section Class `default_call_policies`]
|
||||
default_call_policies is a model of CallPolicies with no precall or postcall behavior and a result_converter which handles by-value returns. Wrapped C++ functions and member functions use default_call_policies unless otherwise specified. You may find it convenient to derive new models of CallPolicies from default_call_policies.
|
||||
`default_call_policies` is a model of [link concepts.callpolicies `CallPolicies`] with no `precall` or `postcall` behavior and a `result_converter` which handles by-value returns. Wrapped C++ functions and member functions `use default_call_policies` unless otherwise specified. You may find it convenient to derive new models of [link concepts.callpolicies `CallPolicies`] from `default_call_policies`.
|
||||
``
|
||||
namespace boost { namespace python
|
||||
{
|
||||
@@ -27,7 +27,7 @@ namespace boost { namespace python
|
||||
]
|
||||
[endsect]
|
||||
[section Class `default_result_converter`]
|
||||
default_result_converter is a model of ResultConverterGenerator which can be used to wrap C++ functions returning non-pointer types, `char const*`, and `PyObject*`, by-value.
|
||||
default_result_converter is a model of [link concepts.resultconverter.resultconvertergenerator_concept `ResultConverterGenerator`] which can be used to wrap C++ functions returning non-pointer types, `char const*`, and `PyObject*`, by-value.
|
||||
``
|
||||
namespace boost { namespace python
|
||||
{
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
[section dict.hpp]
|
||||
[section boost/python/dict.hpp]
|
||||
[section Introduction]
|
||||
Exposes a TypeWrapper for the Python dict type.
|
||||
Exposes a [link concepts.objectwrapper.typewrapper_concept_requirements TypeWrapper] for the Python [@http://www.python.org/dev/doc/devel/lib/typesmapping.html `dict`] type.
|
||||
[endsect]
|
||||
[section Class `dict`]
|
||||
Exposes the mapping protocol of Python's built-in dict type. The semantics of the constructors and member functions defined below can be fully understood by reading the TypeWrapper concept definition. Since dict is publicly derived from object, the public object interface applies to dict instances as well.
|
||||
Exposes the [@http://www.python.org/dev/doc/devel/lib/typesmapping.html mapping protocol] of Python's built-in `dict` type. The semantics of the constructors and member functions defined below can be fully understood by reading the [link concepts.objectwrapper.typewrapper_concept_requirements TypeWrapper] concept definition. Since `dict` is publicly derived from [link object_wrappers.boost_python_object_hpp.class_object `object`], the public `object` interface applies to `dict` instances as well.
|
||||
``
|
||||
namespace boost { namespace python
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[section docstring_options.hpp]
|
||||
[section boost/python/docstring_options.hpp]
|
||||
[section Introduction]
|
||||
Boost.Python supports user-defined docstrings with automatic appending of C++ signatures. These features are enabled by default. The class docstring_options is available to selectively suppress the user-defined docstrings, signatures, or both.
|
||||
[endsect]
|
||||
@@ -7,25 +7,24 @@ Controls the appearance of docstrings of wrapped functions and member functions
|
||||
|
||||
``namespace boost { namespace python {
|
||||
|
||||
class docstring_options : boost::noncopyable
|
||||
{
|
||||
public:
|
||||
docstring_options(bool show_all=true);
|
||||
docstring_options(bool show_user_defined, bool show_signatures);
|
||||
docstring_options(bool show_user_defined, bool show_py_signatures, bool show_cpp_signatures);
|
||||
~docstring_options();
|
||||
void disable_user_defined();
|
||||
void enable_user_defined();
|
||||
void disable_signatures();
|
||||
void enable_signatures();
|
||||
void disable_py_signatures();
|
||||
void enable_py_signatures();
|
||||
void disable_cpp_signatures();
|
||||
void enable_cpp_signatures();
|
||||
void disable_all();
|
||||
void enable_all();
|
||||
};
|
||||
|
||||
class docstring_options : boost::noncopyable
|
||||
{
|
||||
public:
|
||||
docstring_options(bool show_all=true);
|
||||
docstring_options(bool show_user_defined, bool show_signatures);
|
||||
docstring_options(bool show_user_defined, bool show_py_signatures, bool show_cpp_signatures);
|
||||
~docstring_options();
|
||||
void disable_user_defined();
|
||||
void enable_user_defined();
|
||||
void disable_signatures();
|
||||
void enable_signatures();
|
||||
void disable_py_signatures();
|
||||
void enable_py_signatures();
|
||||
void disable_cpp_signatures();
|
||||
void enable_cpp_signatures();
|
||||
void disable_all();
|
||||
void enable_all();
|
||||
};
|
||||
}}
|
||||
|
||||
``
|
||||
@@ -35,27 +34,27 @@ Controls the appearance of docstrings of wrapped functions and member functions
|
||||
docstring_options(bool show_all=true);
|
||||
``
|
||||
[variablelist
|
||||
[[Effects][Constructs a docstring_options object which controls the appearance of function and member-function docstrings defined in the code that follows. If show_all is true, both the user-defined docstrings and the automatically generated Python and C++ signatures are shown. If show_all is false the __doc__ attributes are None.]]
|
||||
[[Effects][Constructs a docstring_options object which controls the appearance of function and member-function docstrings defined in the code that follows. If show_all is true, both the user-defined docstrings and the automatically generated Python and C++ signatures are shown. If show_all is false the `__doc__` attributes are `None`.]]
|
||||
]
|
||||
``
|
||||
docstring_options(bool show_user_defined, bool show_signatures);
|
||||
``
|
||||
[variablelist
|
||||
[[Effects][Constructs a docstring_options object which controls the appearance of function and member-function docstrings defined in the code that follows. Iff show_user_defined is true, the user-defined docstrings are shown. Iff show_signatures is true, Python and C++ signatures are automatically added. If both show_user_defined and show_signatures are false, the __doc__ attributes are None.]]
|
||||
[[Effects][Constructs a `docstring_options` object which controls the appearance of function and member-function docstrings defined in the code that follows. Iff `show_user_defined` is `true`, the user-defined docstrings are shown. Iff `show_signatures` is `true`, Python and C++ signatures are automatically added. If both `show_user_defined` and `show_signatures` are `false`, the `__doc__` attributes are `None`.]]
|
||||
]
|
||||
``
|
||||
docstring_options(bool show_user_defined, bool show_py_signatures, bool show_cpp_signatures);
|
||||
``
|
||||
[variablelist
|
||||
[[Effects][Constructs a docstring_options object which controls the appearance of function and member-function docstrings defined in the code that follows. Iff show_user_defined is true, the user-defined docstrings are shown. Iff show_py_signatures is true, Python signatures are automatically added. Iff show_cpp_signatures is true, C++ signatures are automatically added. If all parameters are false, the __doc__ attributes are None.]]
|
||||
[[Effects][Constructs a `docstring_options` object which controls the appearance of function and member-function docstrings defined in the code that follows. Iff `show_user_defined` is `true`, the user-defined docstrings are shown. Iff `show_py_signatures` is `true`, Python signatures are automatically added. Iff `show_cpp_signatures` is true, C++ signatures are automatically added. If all parameters are `false`, the `__doc__` attributes are `None`.]]
|
||||
]
|
||||
[endsect]
|
||||
[section Class docstring_options destructor]
|
||||
``~docstring_options();``
|
||||
[variablelist
|
||||
[[Effects][Restores the previous state of the docstring options. In particular, if docstring_options instances are in nested C++ scopes the settings effective in the enclosing scope are restored. If the last docstring_options instance goes out of scope the default "all on" settings are restored.]]]
|
||||
[[Effects][Restores the previous state of the docstring options. In particular, if `docstring_options` instances are in nested C++ scopes the settings effective in the enclosing scope are restored. If the last `docstring_options` instance goes out of scope the default "all on" settings are restored.]]]
|
||||
[endsect]
|
||||
[section Class docstring_options modifier functions]
|
||||
[section Class `docstring_options` modifier functions]
|
||||
``
|
||||
void disable_user_defined();
|
||||
void enable_user_defined();
|
||||
@@ -68,7 +67,7 @@ void enable_cpp_signatures();
|
||||
void disable_all();
|
||||
void enable_all();
|
||||
``
|
||||
These member functions dynamically change the appearance of docstrings in the code that follows. The *_user_defined() and *_signatures() member functions are provided for fine-grained control. The *_all() member functions are convenient shortcuts to manipulate all settings simultaneously.
|
||||
These member functions dynamically change the appearance of docstrings in the code that follows. The `*_user_defined()` and `*_signatures()` member functions are provided for fine-grained control. The `*_all()` member functions are convenient shortcuts to manipulate all settings simultaneously.
|
||||
[endsect]
|
||||
[section Example]
|
||||
[section Docstring options defined at compile time]
|
||||
@@ -86,7 +85,7 @@ BOOST_PYTHON_MODULE(demo)
|
||||
def("foo", foo, "foo doc");
|
||||
}
|
||||
``
|
||||
If compiled with -DDEMO_DOCSTRING_SHOW_ALL=true:
|
||||
If compiled with `-DDEMO_DOCSTRING_SHOW_ALL=true`:
|
||||
``
|
||||
>>> import demo
|
||||
>>> print demo.foo.__doc__
|
||||
@@ -94,7 +93,7 @@ foo() -> None : foo doc
|
||||
C++ signature:
|
||||
foo(void) -> void
|
||||
``
|
||||
If compiled with -DDEMO_DOCSTRING_SHOW_ALL=false:
|
||||
If compiled with `-DDEMO_DOCSTRING_SHOW_ALL=false`:
|
||||
``
|
||||
>>> import demo
|
||||
>>> print demo.foo.__doc__
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
[section enum.hpp]
|
||||
[section boost/python/enum.hpp]
|
||||
[section Introduction]
|
||||
<boost/python/enum.hpp> defines the interface through which users expose their C++ enumeration types to Python. It declares the enum_ class template, which is parameterized on the enumeration type being exposed.
|
||||
<boost/python/enum.hpp> defines the interface through which users expose their C++ enumeration types to Python. It declares the `enum_` class template, which is parameterized on the enumeration type being exposed.
|
||||
[endsect]
|
||||
[section Class template `enum_`]
|
||||
Creates a Python class derived from Python's int type which is associated with the C++ type passed as its first parameter.
|
||||
Creates a Python class derived from Python's `int` type which is associated with the C++ type passed as its first parameter.
|
||||
``
|
||||
namespace boost { namespace python
|
||||
{
|
||||
@@ -20,20 +20,20 @@ namespace boost { namespace python
|
||||
[section Class template `enum_` constructors]
|
||||
``enum_(char const* name, char const* doc=0);``
|
||||
[variablelist
|
||||
[[Requires][name is an ntbs which conforms to Python's identifier naming rules. ]]
|
||||
[[Effects][Constructs an enum_ object holding a Python extension type derived from int which is named name. The named attribute of the current scope is bound to the new extension type.]]
|
||||
[[Requires][name is an [link ntbs] which conforms to Python's [@http://www.python.org/doc/current/ref/identifiers.html identifier naming rules].]]
|
||||
[[Effects][Constructs an `enum_` object holding a Python extension type derived from `int` which is named `name`. The named attribute of the [link high_level_components.boost_python_scope_hpp current scope] is bound to the new extension type.]]
|
||||
]
|
||||
[endsect]
|
||||
[section Class template `enum_` modifier functions]
|
||||
``enum_<T>& value(char const* name, T x);``
|
||||
[variablelist
|
||||
[[Requires][name is an ntbs which conforms to Python's identifier naming rules. ]]
|
||||
[[Requires][name is an [link ntbs] which conforms to Python's [@http://www.python.org/doc/current/ref/identifiers.html identifier naming rules].]]
|
||||
[[Effects][adds an instance of the wrapped enumeration type with value x to the type's dictionary as the named attribute.]]
|
||||
[[Returns][`*this`]]
|
||||
]
|
||||
``enum_<T>& export_values();``
|
||||
[variablelist
|
||||
[[Effects][sets attributes in the current scope with the same names and values as all enumeration values exposed so far by calling value().]]
|
||||
[[Effects][sets attributes in the [link high_level_components.boost_python_scope_hpp current scope] with the same names and values as all enumeration values exposed so far by calling value().]]
|
||||
[[Returns][`*this`]]
|
||||
]
|
||||
[endsect]
|
||||
@@ -52,14 +52,14 @@ color identity_(color x) { return x; }
|
||||
|
||||
BOOST_PYTHON_MODULE(enums)
|
||||
{
|
||||
enum_<color>("color")
|
||||
.value("red", red)
|
||||
.value("green", green)
|
||||
.export_values()
|
||||
.value("blue", blue)
|
||||
;
|
||||
|
||||
def("identity", identity_);
|
||||
enum_<color>("color")
|
||||
.value("red", red)
|
||||
.value("green", green)
|
||||
.export_values()
|
||||
.value("blue", blue)
|
||||
;
|
||||
|
||||
def("identity", identity_);
|
||||
}
|
||||
``
|
||||
Interactive Python:
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
[section errors.hpp]
|
||||
[section boost/python/errors.hpp]
|
||||
[section Introduction]
|
||||
<boost/python/errors.hpp> provides types and functions for managing and translating between Python and C++ exceptions. This is relatively low-level functionality that is mostly used internally by Boost.Python. Users should seldom need it.
|
||||
[endsect]
|
||||
[section Class `error_already_set`]
|
||||
error_already_set is an exception type which can be thrown to indicate that a Python error has occurred. If thrown, the precondition is that PyErr_Occurred() returns a value convertible to true. Portable code shouldn't throw this exception type directly, but should instead use throw_error_already_set(), below.
|
||||
error_already_set is an exception type which can be thrown to indicate that a Python error has occurred. If thrown, the precondition is that [@http://www.python.org/doc/2.2/api/exceptionHandling.html#l2h-71 PyErr_Occurred()] returns a value convertible to `true`. Portable code shouldn't throw this exception type directly, but should instead use [link high_level_components.boost_python_errors_hpp.functions throw_error_already_set()], below.
|
||||
``
|
||||
namespace boost { namespace python
|
||||
{
|
||||
@@ -18,10 +18,10 @@ void handle_exception() throw();
|
||||
``
|
||||
[variablelist
|
||||
[[Requires][The first form requires that the expression function0<void>(f) is valid. The second form requires that a C++ exception is currently being handled (see section 15.1 in the C++ standard).]]
|
||||
[[Effects][The first form calls f() inside a try block which first attempts to use all registered exception translators. If none of those translates the exception, the catch clauses then set an appropriate Python exception for the C++ exception caught, returning true if an exception was thrown, false otherwise. The second form passes a function which rethrows the exception currently being handled to the first form.]]
|
||||
[[Effects][The first form calls f() inside a try block which first attempts to use all registered [link high_level_components.boost_python_exception_translato exception translators]. If none of those translates the exception, the catch clauses then set an appropriate Python exception for the C++ exception caught, returning true if an exception was thrown, false otherwise. The second form passes a function which rethrows the exception currently being handled to the first form.]]
|
||||
[[Postconditions][No exception is being handled]]
|
||||
[[Throws][nothing]]
|
||||
[[Rationale][At inter-language boundaries it is important to ensure that no C++ exceptions escape, since the calling language usually doesn't have the equipment necessary to properly unwind the stack. Use handle_exception to manage exception translation whenever your C++ code is called directly from the Python API. This is done for you automatically by the usual function wrapping facilities: make_function(), make_constructor(), def() and class_::def(). The second form can be more convenient to use (see the example below), but various compilers have problems when exceptions are rethrown from within an enclosing try block.]]
|
||||
[[Rationale][At inter-language boundaries it is important to ensure that no C++ exceptions escape, since the calling language usually doesn't have the equipment necessary to properly unwind the stack. Use handle_exception to manage exception translation whenever your C++ code is called directly from the Python API. This is done for you automatically by the usual function wrapping facilities: [link function_invocation_and_creation.boost_python_make_function_hpp.functions make_function()], [link function_invocation_and_creation.boost_python_make_function_hpp.functions make_constructor()], [link high_level_components.boost_python_def_hpp.functions def()] and [link high_level_components.boost_python_class_hpp.class_template_class_t_bases_hel.class_template_class_modifier_fu class_::def()]. The second form can be more convenient to use (see the example below), but various compilers have problems when exceptions are rethrown from within an enclosing try block.]]
|
||||
]
|
||||
``template <class T> T* expect_non_null(T* x);``
|
||||
[variablelist
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[section exception_translator.hpp]
|
||||
[section boost/python/exception_translator.hpp]
|
||||
[section Introduction]
|
||||
As described here, it is important to make sure that exceptions thrown by C++ code do not pass into the Python interpreter core. By default, Boost.Python translates all C++ exceptions thrown by wrapped functions and module init functions into Python, but the default translators are extremely limited: most C++ exceptions will appear in Python as a RuntimeError exception whose representation is 'Unidentifiable C++ Exception'. To produce better error messages, users can register additional exception translators as described below.
|
||||
As described [link high_level_components.boost_python_errors_hpp.introduction here], it is important to make sure that exceptions thrown by C++ code do not pass into the Python interpreter core. By default, Boost.Python translates all C++ exceptions thrown by wrapped functions and module init functions into Python, but the default translators are extremely limited: most C++ exceptions will appear in Python as a [@http://www.python.org/doc/current/lib/module-exceptions.html RuntimeError] exception whose representation is 'Unidentifiable C++ Exception'. To produce better error messages, users can register additional exception translators as described below.
|
||||
[endsect]
|
||||
[section Function `register_exception_translator`]
|
||||
``
|
||||
@@ -8,7 +8,7 @@ template<class ExceptionType, class Translate>
|
||||
void register_exception_translator(Translate translate);
|
||||
``
|
||||
[variablelist
|
||||
[[Requires][Translate is Copyconstructible, and the following code must be well-formed:
|
||||
[[Requires][Translate is CopyConstructible, and the following code must be well-formed:
|
||||
``void f(ExceptionType x) { translate(x); }``.
|
||||
The expression `translate(x)` must either throw a C++ exception, or a subsequent call to `PyErr_Occurred()` must return 1. ]]
|
||||
[[Effects][Adds a copy of translate to the sequence of exception translators tried when Boost.Python catches an exception that is about to pass into Python's core interpreter. The new translator will get "first shot" at translating all exceptions matching the catch clause shown above. Any subsequently-registered translators will be allowed to translate the exception earlier. A translator which cannot translate a given C++ exception can re-throw it, and it will be handled by a translator which was registered earlier (or by the default translator).]]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[section exec.hpp]
|
||||
[section boost/python/exec.hpp]
|
||||
[section Introduction]
|
||||
Exposes a mechanism for embedding the python interpreter into C++ code.
|
||||
[endsect]
|
||||
@@ -36,7 +36,7 @@ object exec_file(str filename,
|
||||
]
|
||||
[endsect]
|
||||
[section Examples]
|
||||
The following example demonstrates the use of import and exec to define a function in python, and later call it from within C++.
|
||||
The following example demonstrates the use of import and exec to define a function in python, and later call it from within C++.
|
||||
|
||||
``
|
||||
#include <iostream>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
[section extract.hpp]
|
||||
[section boost/python/extract.hpp]
|
||||
[section Introduction]
|
||||
Exposes a mechanism for extracting C++ object values from generalized Python objects. Note that `extract<...>` can also be used to "downcast" an object to some specific ObjectWrapper. Because invoking a mutable python type with an argument of the same type (e.g. `list([1,2]`) typically makes a copy of the argument object, this may be the only way to access the ObjectWrapper's interface on the original object.
|
||||
Exposes a mechanism for extracting C++ object values from generalized Python objects. Note that `extract<...>` can also be used to "downcast" an [link object_wrappers.boost_python_object_hpp.class_object `object`] to some specific [link concepts.objectwrapper ObjectWrapper]. Because invoking a mutable python type with an argument of the same type (e.g. `list([1,2]`) typically makes a copy of the argument object, this may be the only way to access the [link concepts.objectwrapper ObjectWrapper]\ 's interface on the original object.
|
||||
[endsect]
|
||||
[section Class template `extract`]
|
||||
`extract<T>` can be used to extract a value of an arbitrary C++ type from an instance of object. Two usages are supported:
|
||||
`extract<T>` can be used to extract a value of an arbitrary C++ type from an instance of [link object_wrappers.boost_python_object_hpp.class_object object]. Two usages are supported:
|
||||
|
||||
# `extract<T>(o)` is a temporary object which is implicitly convertible to `T` (explicit conversion is also available through the object's function-call operator). However, if no conversion is available which can convert o to an object of type `T`, a Python TypeError exception will be raised.
|
||||
# `extract<T> x(o);` constructs an extractor whose `check()` member function can be used to ask whether a conversion is available without causing an exception to be thrown.
|
||||
@@ -45,7 +45,7 @@ operator result_type() const;
|
||||
[variablelist
|
||||
[[Effects][Converts the stored pointer to result_type, which is either T or T const&. ]]
|
||||
[[Returns][An object of result_type corresponding to the one referenced by the stored pointer.]]
|
||||
[[Throws][error_already_set and sets a TypeError if no such conversion is available. May also emit other unspecified exceptions thrown by the converter which is actually used.]]
|
||||
[[Throws][[link high_level_components.boost_python_errors_hpp.class_error_already_set `error_already_set`] and sets a `TypeError` if no such conversion is available. May also emit other unspecified exceptions thrown by the converter which is actually used.]]
|
||||
]
|
||||
`` bool check() const;``
|
||||
[variablelist
|
||||
@@ -69,7 +69,7 @@ int Print(str s)
|
||||
return extract<int>(s.attr("__len__")())
|
||||
}
|
||||
``
|
||||
The following example shows how extract can be used along with class_<...> to create and access an instance of a wrapped C++ class.
|
||||
The following example shows how extract can be used along with [link high_level_components.boost_python_class_hpp.class_template_class_t_bases_hel `class_<...>`] to create and access an instance of a wrapped C++ class.
|
||||
``
|
||||
struct X
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[section function_doc_signature.hpp]
|
||||
[section boost/python/function_doc_signature.hpp]
|
||||
[section Introduction]
|
||||
Boost.Python supports docstrings with automatic appending of Pythonic and C++ signatures. This feature is implemented by class function_doc_signature_generator The class uses all of the overloads, supplied arg names and default values, as well as the user-defined docstrings, to generate documentation for a given function.
|
||||
Boost.Python supports docstrings with automatic appending of Pythonic and C++ signatures. This feature is implemented by class `function_doc_signature_generator`. The class uses all of the overloads, supplied arg names and default values, as well as the user-defined docstrings, to generate documentation for a given function.
|
||||
[endsect]
|
||||
[section Class `function_doc_signature_generator`]
|
||||
The class has only one public function which returns a list of strings documenting the overloads of a function.
|
||||
@@ -71,7 +71,7 @@ BOOST_PYTHON_MODULE(args_ext)
|
||||
|
||||
}
|
||||
``
|
||||
Python code:
|
||||
Python code: [python]
|
||||
``
|
||||
>>> import args_ext
|
||||
>>> help(args_ext)
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
[section handle.hpp]
|
||||
[section boost/python/handle.hpp]
|
||||
[section Introduction]
|
||||
<boost/python/handle.hpp> provides class template handle, a smart pointer for managing reference-counted Python objects.
|
||||
<boost/python/handle.hpp> provides class template `handle`, a smart pointer for managing reference-counted Python objects.
|
||||
[endsect]
|
||||
[section Class template `handle`]
|
||||
handle is a smart pointer to a Python object type; it holds a pointer of type T*, where T is its template parameter. T must be either a type derived from PyObject or a POD type whose initial sizeof(PyObject) bytes are layout-compatible with PyObject. Use handle<> at the boundary between the Python/'C' API and high-level code; prefer object for a generalized interface to Python objects.
|
||||
`handle` is a smart pointer to a Python object type; it holds a pointer of type `T*`, where `T` is its template parameter. T must be either a type derived from `PyObject` or a [link pod POD] type whose initial `sizeof(PyObject)` bytes are layout-compatible with `PyObject`. Use `handle<>` at the boundary between the Python/'C' API and high-level code; prefer object for a generalized interface to Python objects.
|
||||
|
||||
In this document, the term "upcast" refers to an operation which converts a pointer Y* to a base class pointer T* via static_cast<T*> if Y is derived from T, or via C-style cast (T*) if it is not. However, in the latter case the "upcast" is ill-formed if the initial sizeof(PyObject) bytes of Y are not layout-compatible with PyObject.
|
||||
In this document, the term "upcast" refers to an operation which converts a pointer `Y*` to a base class `pointer T*` via `static_cast<T*>` if `Y` is derived from `T`, or via C-style cast (`T*`) if it is not. However, in the latter case the "upcast" is ill-formed if the initial `sizeof(PyObject)` bytes of `Y` are not layout-compatible with `PyObject`.
|
||||
|
||||
``
|
||||
namespace boost { namespace python
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
[section has_back_reference.hpp]
|
||||
[section boost/python/has_back_reference.hpp]
|
||||
[section Introduction]
|
||||
<boost/python/has_back_reference.hpp> defines the predicate metafunction has_back_reference<>, which can be specialized by the user to indicate that a wrapped class instance holds a PyObject* corresponding to a Python object.
|
||||
<boost/python/has_back_reference.hpp> defines the predicate metafunction `has_back_reference<>`, which can be specialized by the user to indicate that a wrapped class instance holds a `PyObject*` corresponding to a Python object.
|
||||
[endsect]
|
||||
[section Class template `has_back_reference`]
|
||||
A unary metafunction whose value is true iff its argument is a pointer_wrapper<>.
|
||||
A unary metafunction whose value is true iff its argument is a `pointer_wrapper<>`.
|
||||
``
|
||||
namespace boost { namespace python
|
||||
{
|
||||
@@ -14,7 +14,7 @@ namespace boost { namespace python
|
||||
}}
|
||||
``
|
||||
|
||||
A " metafunction" that is inspected by Boost.Python to determine how wrapped classes can be constructed.
|
||||
A metafunction that is inspected by Boost.Python to determine how wrapped classes can be constructed.
|
||||
|
||||
`type::value` is an integral constant convertible to bool of unspecified type.
|
||||
Specializations may substitute a true-valued integral constant wrapper for type iff for each invocation of `class_<WrappedClass>::def(init< type-sequence...>())` and the implicitly wrapped copy constructor (unless it is noncopyable), there exists a corresponding constructor `WrappedClass::WrappedClass(PyObject*, type-sequence...)`. If such a specialization exists, the WrappedClass constructors will be called with a "back reference" pointer to the corresponding Python object whenever they are invoked from Python. The easiest way to provide this nested type is to derive the specialization from `mpl::true_`.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[section implicit.hpp]
|
||||
[section boost/python/implicit.hpp]
|
||||
[section Introduction]
|
||||
implicitly_convertible allows Boost.Python to implicitly take advantage of a C++ implicit or explicit conversion when matching Python objects to C++ argument types.
|
||||
`implicitly_convertible` allows Boost.Python to implicitly take advantage of a C++ implicit or explicit conversion when matching Python objects to C++ argument types.
|
||||
[endsect]
|
||||
[section Function template `implicit_convertible`]
|
||||
``
|
||||
@@ -13,8 +13,8 @@ void implicitly_convertible();
|
||||
[[Target][The target type of the implicit conversion]]
|
||||
]
|
||||
[variablelist
|
||||
[[Requires][The declaration Target t(s);, where s is of type Source, is valid.]]
|
||||
[[Effects][registers an rvalue from_python converter to Target which can succeed for any PyObject* p iff there exists any registered converter which can produce Source rvalues]]
|
||||
[[Requires][The declaration `Target t(s);`, where s is of type Source, is valid.]]
|
||||
[[Effects][registers an rvalue `from_python` converter to Target which can succeed for any `PyObject* p` iff there exists any registered converter which can produce Source rvalues]]
|
||||
[[Rationale][C++ users expect to be able to take advantage of the same sort of interoperability in Python as they do in C++.]]
|
||||
]
|
||||
[endsect]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[section import.hpp]
|
||||
[section boost/python/import.hpp]
|
||||
[section Introduction]
|
||||
Exposes a mechanism for importing python modules.
|
||||
[endsect]
|
||||
@@ -10,7 +10,7 @@ Exposes a mechanism for importing python modules.
|
||||
]
|
||||
[endsect]
|
||||
[section Examples]
|
||||
The following example demonstrates the use of import to access a function in python, and later call it from within C++.
|
||||
The following example demonstrates the use of import to access a function in python, and later call it from within C++.
|
||||
``
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
[section Indexing support]
|
||||
[section Introduction]
|
||||
Indexing is a Boost Python facility for easy exportation of indexable C++ containers to Python. Indexable containers are containers that allow random access through the operator[] (e.g. std::vector).
|
||||
Indexing is a `Boost Python` facility for easy exportation of indexable C++ containers to Python. Indexable containers are containers that allow random access through the `operator[]` (e.g. `std::vector`).
|
||||
|
||||
While Boost Python has all the facilities needed to expose indexable C++ containers such as the ubiquitous std::vector to Python, the procedure is not as straightforward as we'd like it to be. Python containers do not map easily to C++ containers. Emulating Python containers in C++ (see Python Reference Manual, Emulating container types) using Boost Python is non trivial. There are a lot of issues to consider before we can map a C++ container to Python. These involve implementing wrapper functions for the methods __len__, __getitem__, __setitem__, __delitem__, __iter__ and __contains.
|
||||
While `Boost Python` has all the facilities needed to expose indexable C++ containers such as the ubiquitous std::vector to Python, the procedure is not as straightforward as we'd like it to be. Python containers do not map easily to C++ containers. Emulating Python containers in C++ (see Python Reference Manual, [@http://www.python.org/doc/current/ref/sequence-types.html Emulating container types]) using `Boost.Python` is non trivial. There are a lot of issues to consider before we can map a C++ container to Python. These involve implementing wrapper functions for the methods `__len__`, `__getitem__`, `__setitem__`, `__delitem__`, `__iter__` and `__contains__`.
|
||||
|
||||
The goals:
|
||||
|
||||
* Make indexable C++ containers behave exactly as one would expect a Python container to behave.
|
||||
* Provide default reference semantics for container element indexing (__getitem__) such that c[i] can be mutable. Require:
|
||||
* Provide default reference semantics for container element indexing (`__getitem__`) such that c[i] can be mutable. Require:
|
||||
|
||||
``
|
||||
val = c[i]
|
||||
@@ -16,21 +16,21 @@ The goals:
|
||||
``
|
||||
|
||||
where m is a non-const (mutating) member function (method).
|
||||
* Return safe references from __getitem__ such that subsequent adds and deletes to and from the container will not result in dangling references (will not crash Python).
|
||||
* Return safe references from `__getitem__` such that subsequent adds and deletes to and from the container will not result in dangling references (will not crash Python).
|
||||
* Support slice indexes.
|
||||
* Accept Python container arguments (e.g. lists, tuples) wherever appropriate.
|
||||
* Accept Python container arguments (e.g. `lists`, `tuples`) wherever appropriate.
|
||||
* Allow for extensibility through re-definable policy classes.
|
||||
* Provide predefined support for the most common STL and STL like indexable containers.
|
||||
* Provide predefined support for the most common STL and STL-like indexable containers.
|
||||
|
||||
[endsect]
|
||||
[section The Indexing Interface]
|
||||
The indexing_suite class is the base class for the management of C++ containers intended to be integrated to Python. The objective is make a C++ container look and feel and behave exactly as we'd expect a Python container. The class automatically wraps these special Python methods (taken from the Python reference: Emulating container types):
|
||||
The `indexing_suite` class is the base class for the management of C++ containers intended to be integrated to Python. The objective is make a C++ container look and feel and behave exactly as we'd expect a Python container. The class automatically wraps these special Python methods (taken from the Python reference: Emulating container types):
|
||||
|
||||
[variablelist
|
||||
[[__len__(self)]
|
||||
[Called to implement the built-in function len() Should return the length of the object, an integer >= 0. Also, an object that doesn't define a __nonzero__() method and whose __len__() method returns zero is considered to be false in a Boolean context.]]
|
||||
[Called to implement the built-in function `len()`. Should return the length of the object, an integer `>= 0`. Also, an object that doesn't define a `__nonzero__()` method and whose `__len__()` method returns zero is considered to be false in a Boolean context.]]
|
||||
[[__getitem__(self, key)]
|
||||
[Called to implement evaluation of self[key]. For sequence types, the accepted keys should be integers and slice objects. Note that the special interpretation of negative indexes (if the class wishes to emulate a sequence type) is up to the __getitem__() method. If key is of an inappropriate type, TypeError may be raised; if of a value outside the set of indexes for the sequence (after any special interpretation of negative values), IndexError should be raised. Note: for loops expect that an IndexError will be raised for illegal indexes to allow proper detection of the end of the sequence.]]
|
||||
[Called to implement evaluation of `self[key]`. For sequence types, the accepted keys should be integers and slice objects. Note that the special interpretation of negative indexes (if the class wishes to emulate a sequence type) is up to the `__getitem__()` method. If key is of an inappropriate type, `TypeError` may be raised; if of a value outside the set of indexes for the sequence (after any special interpretation of negative values), IndexError should be raised. [Note: for loops expect that an IndexError will be raised for illegal indexes to allow proper detection of the end of the sequence.]]]
|
||||
[[__setitem__(self, key, value)]
|
||||
[Called to implement assignment to self[key]. Same note as for __getitem__(). This should only be implemented for mappings if the objects support changes to the values for keys, or if new keys can be added, or for sequences if elements can be replaced. The same exceptions should be raised for improper key values as for the __getitem__() method.]]
|
||||
[[__delitem__(self, key)]
|
||||
@@ -38,17 +38,16 @@ The goals:
|
||||
[[__iter__(self)]
|
||||
[This method is called when an iterator is required for a container. This method should return a new iterator object that can iterate over all the objects in the container. For mappings, it should iterate over the keys of the container, and should also be made available as the method iterkeys().
|
||||
|
||||
Iterator objects also need to implement this method; they are required to return themselves. For more information on iterator objects, see "Iterator Types" in the Python Library Reference.]]
|
||||
Iterator objects also need to implement this method; they are required to return themselves. For more information on iterator objects, see [@http://www.python.org/doc/current/lib/typeiter.html Iterator Types] in the [@http://www.python.org/doc/current/lib/lib.html Python Library Reference].]]
|
||||
|
||||
[[__contains__(self, item)]
|
||||
[Called to implement membership test operators. Should return true if item is in self, false otherwise. For mapping objects, this should consider the keys of the mapping rather than the values or the key-item pairs.]]
|
||||
]
|
||||
[endsect]
|
||||
[section index_suite sub-classes]
|
||||
The indexing_suite is not meant to be used as is. A couple of policy functions must be supplied by subclasses of indexing_suite. However, a set of indexing_suite subclasses for the standard indexable STL containers will be provided, In most cases, we can simply use the available predefined suites. In some cases, we can refine the predefined suites to suit our needs.
|
||||
[endsect]
|
||||
The `indexing_suite` is not meant to be used as is. A couple of policy functions must be supplied by subclasses of `indexing_suite`. However, a set of indexing_suite subclasses for the standard indexable STL containers will be provided, In most cases, we can simply use the available predefined suites. In some cases, we can refine the predefined suites to suit our needs.
|
||||
[section vector_index_suite]
|
||||
The vector_indexing_suite class is a predefined indexing_suite derived class designed to wrap std::vector (and std::vector like [i.e. a class with std::vector interface]) classes. It provides all the policies required by the indexing_suite.
|
||||
The `vector_indexing_suite` class is a predefined `indexing_suite` derived class designed to wrap `std::vector` (and `std::vector`-like [i.e. a class with `std::vector` interface]) classes. It provides all the policies required by the `indexing_suite`.
|
||||
|
||||
Example usage:
|
||||
``
|
||||
@@ -59,10 +58,10 @@ class_<std::vector<X> >("XVec")
|
||||
;
|
||||
``
|
||||
|
||||
XVec is now a full-fledged Python container (see the example in full, along with its python test).
|
||||
XVec is now a full-fledged Python container (see the example in full, along with its python test).
|
||||
[endsect]
|
||||
[section map_index_suite]
|
||||
The map_indexing_suite class is a predefined indexing_suite derived class designed to wrap std::map (and std::map like [i.e. a class with std::map interface]) classes. It provides all the policies required by the indexing_suite.
|
||||
The `map_indexing_suite` class is a predefined `indexing_suite` derived class designed to wrap `std::map` (and `std::map`-like [i.e. a class with `std::map` interface]) classes. It provides all the policies required by the `indexing_suite`.
|
||||
|
||||
Example usage:
|
||||
|
||||
@@ -75,17 +74,10 @@ class_<std::map<X> >("XMap")
|
||||
;
|
||||
``
|
||||
|
||||
By default indexed elements are returned by proxy. This can be disabled by supplying true in the NoProxy template parameter. XMap is now a full-fledged Python container (see the example in full, along with its python test).
|
||||
By default indexed elements are returned by proxy. This can be disabled by supplying `true` in the `NoProxy` template parameter. XMap is now a full-fledged Python container (see the example in full, along with its python test).
|
||||
[endsect]
|
||||
[endsect]
|
||||
[section `indexing_suite` class]
|
||||
`` indexing_suite<class Container,
|
||||
class DerivedPolicies,
|
||||
bool NoProxy,
|
||||
bool NoSlice,
|
||||
class Data,
|
||||
class Index,
|
||||
class Key>``
|
||||
|
||||
[table
|
||||
[[Template Parameter][Requirements][Semantics][Default]]
|
||||
[[Container][A class type][ The container type to be wrapped to Python. ][]]
|
||||
@@ -156,11 +148,11 @@ adjust_index(index_type current, index_type from,
|
||||
index_type to, size_type len);
|
||||
``
|
||||
|
||||
Most of these policies are self explanatory. However, convert_index and adjust_index deserve some explanation.
|
||||
Most of these policies are self explanatory. However, convert_index and adjust_index deserve some explanation.
|
||||
|
||||
convert_index converts a Python index into a C++ index that the container can handle. For instance, negative indexes in Python, by convention, start counting from the right(e.g. C[-1] indexes the rightmost element in C). convert_index should handle the necessary conversion for the C++ container (e.g. convert -1 to C.size()-1). convert_index should also be able to convert the type of the index (A dynamic Python type) to the actual type that the C++ container expects.
|
||||
convert_index converts a Python index into a C++ index that the container can handle. For instance, negative indexes in Python, by convention, start counting from the right(e.g. C[-1] indexes the rightmost element in C). convert_index should handle the necessary conversion for the C++ container (e.g. convert -1 to C.size()-1). convert_index should also be able to convert the type of the index (A dynamic Python type) to the actual type that the C++ container expects.
|
||||
|
||||
When a container expands or contracts, held indexes to its elements must be adjusted to follow the movement of data. For instance, if we erase 3 elements, starting from index 0 from a 5 element vector, what used to be at index 4 will now be at index 1:
|
||||
When a container expands or contracts, held indexes to its elements must be adjusted to follow the movement of data. For instance, if we erase 3 elements, starting from index 0 from a 5 element vector, what used to be at index 4 will now be at index 1:
|
||||
|
||||
``
|
||||
[a][b][c][d][e] ---> [d][e]
|
||||
@@ -168,7 +160,7 @@ adjust_index(index_type current, index_type from,
|
||||
4 1
|
||||
``
|
||||
|
||||
adjust_index takes care of the adjustment. Given a current index, the function should return the adjusted index when data in the container at index from..to is replaced by len elements.
|
||||
adjust_index takes care of the adjustment. Given a current index, the function should return the adjusted index when data in the container at index from..to is replaced by len elements.
|
||||
[endsect]
|
||||
[endsect]
|
||||
[section class `vector_indexing_suite`]
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
[section init.hpp]
|
||||
[section boost/python/init.hpp]
|
||||
[section Introduction]
|
||||
<boost/python/init.hpp> defines the interface for exposing C++ constructors to Python as extension class __init__ functions.
|
||||
<boost/python/init.hpp> defines the interface for exposing C++ constructors to Python as extension class `__init__` functions.
|
||||
[section init-expressions]
|
||||
An init-expression is used to describe a family of __init__ methods to be generated for an extension class, and the result has the following properties:
|
||||
An init-expression is used to describe a family of `__init__` methods to be generated for an extension class, and the result has the following properties:
|
||||
[variablelist
|
||||
[[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 subsequence of) the arguments to the generated __init__ function(s).]]
|
||||
[[call_policies][An instance of a model of CallPolicies.]]
|
||||
[[docstring][An [link ntbs] whose value will bound to the method's `__doc__` attribute]]
|
||||
[[keywords][A [link function_invocation_and_creation.boost_python_args_hpp.introduction.keyword_expressions keyword-expression] which will be used to name (a trailing subsequence of) the arguments to the generated `__init__` function(s).]]
|
||||
[[call_policies][An instance of a model of [link concepts.callpolicies 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.]]
|
||||
]
|
||||
[endsect]
|
||||
@@ -20,12 +20,12 @@ 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);
|
||||
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
|
||||
template <class CallPolicies>
|
||||
unspecified operator[](CallPolicies const& policies) const
|
||||
};
|
||||
}}
|
||||
``
|
||||
@@ -36,9 +36,9 @@ template <class Keywords> init(Keywords const& kw, char const* doc = 0);
|
||||
template <class Keywords> init(char const* doc, Keywords const& kw);
|
||||
``
|
||||
[variablelist
|
||||
[[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. ]]
|
||||
[[Requires][If supplied, doc is an [link 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 [link function_invocation_and_creation.models_of_callpolicies.boost_python_default_call_polici default_call_policies]. If Tn is [link high_level_components.boost_python_init_hpp.class_template_optional 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 template arguments the user specified. ]]
|
||||
]
|
||||
[endsect]
|
||||
[section Class template `init` observer functions]
|
||||
@@ -47,8 +47,8 @@ template <class Policies>
|
||||
unspecified operator[](Policies const& policies) const
|
||||
``
|
||||
[variablelist
|
||||
[[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 call policies are replaced by a reference to policies.]]
|
||||
[[Requires][Policies is a model of [link concepts.callpolicies CallPolicies].]]
|
||||
[[Effects][Returns a new [link high_level_components.boost_python_init_hpp.introduction.init_expressions init-expression] with all the same properties as the init object except that its call policies are replaced by a reference to policies.]]
|
||||
]
|
||||
[endsect]
|
||||
[endsect]
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
[section instance_holder.hpp]
|
||||
[section boost/python/instance_holder.hpp]
|
||||
[section Introduction]
|
||||
<boost/python/instance_holder.hpp> provides class instance_holder, the base class for types which hold C++ instances of wrapped classes.
|
||||
<boost/python/instance_holder.hpp> provides class `instance_holder`, the base class for types which hold C++ instances of wrapped classes.
|
||||
[endsect]
|
||||
[section Class template `instance_holder`]
|
||||
instance_holder is an abstract base class whose concrete derived classes hold C++ class instances within their Python object wrappers. To allow multiple inheritance in Python from C++ class wrappers, each such Python object contains a chain of instance_holders. When an __init__ function for a wrapped C++ class is invoked, a new instance_holder instance is created and installed in the Python object using its install() function. Each concrete class derived from instance_holder must provide a holds() implementation which allows Boost.Python to query it for the type(s) it is holding. In order to support the held type's wrapped constructor(s), the class must also provide constructors that can accept an initial PyObject* argument referring to the owning Python object, and which forward the rest of their arguments to the constructor of the held type. The initial argument is needed to enable virtual function overriding in Python, and may be ignored, depending on the specific instance_holder subclass.
|
||||
`instance_holder` is an abstract base class whose concrete derived classes hold C++ class instances within their Python object wrappers. To allow multiple inheritance in Python from C++ class wrappers, each such Python object contains a chain of instance_holders. When an `__init__` function for a wrapped C++ class is invoked, a new `instance_holder` instance is created and installed in the Python object using its `install()` function. Each concrete class derived from `instance_holder` must provide a `holds()` implementation which allows Boost.Python to query it for the type(s) it is holding. In order to support the held type's wrapped constructor(s), the class must also provide constructors that can accept an initial `PyObject*` argument referring to the owning Python object, and which forward the rest of their arguments to the constructor of the held type. The initial argument is needed to enable virtual function overriding in Python, and may be ignored, depending on the specific `instance_holder` subclass.
|
||||
``
|
||||
namespace boost { namespace python
|
||||
{
|
||||
@@ -30,7 +30,7 @@ namespace boost { namespace python
|
||||
[section Class `intance_holder` modifiers]
|
||||
``void install(PyObject* inst) throw();``
|
||||
[variablelist
|
||||
[[Requires][inst is a Python instance of a wrapped C++ class type, or is a type derived from a wrapped C++ class type. ]]
|
||||
[[Requires][`inst` is a Python instance of a wrapped C++ class type, or is a type derived from a wrapped C++ class type. ]]
|
||||
[[Effects][installs the new instance at the head of the Python object's chain of held instances. ]]
|
||||
[[Throws][nothing]]
|
||||
]
|
||||
@@ -43,7 +43,7 @@ namespace boost { namespace python
|
||||
[endsect]
|
||||
[endsect]
|
||||
[section Examples]
|
||||
The following is a simplified version of the instance holder template used by Boost.Python to wrap classes held by smart pointers:
|
||||
The following is a simplified version of the instance holder template used by Boost.Python to wrap classes held by smart pointers:
|
||||
|
||||
``
|
||||
template <class SmartPtr, class Value>
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
[section iterator.hpp]
|
||||
[section boost/python/iterator.hpp]
|
||||
[section Introduction]
|
||||
<boost/python/iterator.hpp> provides types and functions for creating Python iterators from C++ Containers and Iterators. Note that if your class_ supports random-access iterators, implementing `__getitem__` (also known as the Sequence Protocol) may serve you better than using this facility: Python will automatically create an iterator type for you (see `iter()`), and each access can be range-checked, leaving no possiblity of accessing through an invalidated C++ iterator.
|
||||
<boost/python/iterator.hpp> provides types and functions for creating [@http://www.python.org/doc/current/lib/typeiter.html Python iterators] from C++ Containers and Iterators. Note that if your `class_` supports random-access iterators, implementing [@http://www.python.org/doc/current/ref/sequence-types.html#l2h-128 __getitem__] (also known as the Sequence Protocol) may serve you better than using this facility: Python will automatically create an iterator type for you (see [@http://www.python.org/doc/current/lib/built-in-funcs.html#l2h-35 `iter()`]), and each access can be range-checked, leaving no possiblity of accessing through an invalidated C++ iterator.
|
||||
[endsect]
|
||||
[section Class template `iterator`]
|
||||
Instances of `iterator<C,P>` hold a reference to a callable Python object which, when invoked from Python, expects a single argument c convertible to C and creates a Python iterator that traverses `[c.begin(), c.end())`. The optional CallPolicies P can be used to control how elements are returned during iteration.
|
||||
Instances of `iterator<C,P>` hold a reference to a callable Python object which, when invoked from Python, expects a single argument c convertible to C and creates a Python iterator that traverses `[c.begin(), c.end())`. The optional [link concepts.callpolicies CallPolicies] `P` can be used to control how elements are returned during iteration.
|
||||
|
||||
In the table below, c is an instance of Container.
|
||||
|
||||
[table
|
||||
[[Template Parameter][Requirements][Semantics][Default]]
|
||||
[[Container][`[c.begin(),c.end()`) is a valid Iterator range.][The result will convert its argument to c and call c.begin() and c.end() to acquire iterators. To invoke Container's const begin() and end() functions, make it const.][ ]]
|
||||
[[NextPolicies][A default-constructible model of CallPolicies.][Applied to the resulting iterators' next() method.][An unspecified model of CallPolicies which always makes a copy of the result of deferencing the underlying C++ iterator]]
|
||||
[[Container][`[c.begin(),c.end()`) is a valid Iterator range.][The result will convert its argument to c and call c.begin() and c.end() to acquire iterators. To invoke Container's const `begin()` and `end()` functions, make it const.][ ]]
|
||||
[[NextPolicies][A default-constructible model of [link concepts.callpolicies CallPolicies].][Applied to the resulting iterators' `next()` method.][An unspecified model of [link concepts.callpolicies CallPolicies] which always makes a copy of the result of deferencing the underlying C++ iterator]]
|
||||
]
|
||||
|
||||
``
|
||||
@@ -30,12 +30,12 @@ namespace boost { namespace python
|
||||
[variablelist
|
||||
[[Effects][Initializes its base class with the result of:
|
||||
``range<NextPolicies>(&iterators<Container>::begin, &iterators<Container>::end)``]]
|
||||
[[Postconditions][this->get() points to a Python callable object which creates a Python iterator as described above.]]
|
||||
[[Rationale][Provides an easy way to create iterators for the common case where a C++ class being wrapped provides begin() and end().]]
|
||||
[[Postconditions][`this->get()` points to a Python callable object which creates a Python iterator as described above.]]
|
||||
[[Rationale][Provides an easy way to create iterators for the common case where a C++ class being wrapped provides `begin()` and `end()`.]]
|
||||
]
|
||||
[endsect]
|
||||
[section Class template `iterators`]
|
||||
A utility class template which provides a way to reliably call its argument's begin() and end() member functions. Note that there is no portable way to take the address of a member function of a C++ standard library container, so iterators<> can be particularly helpful when wrapping them.
|
||||
A utility class template which provides a way to reliably call its argument's `begin()` and `end()` member functions. Note that there is no portable way to take the address of a member function of a C++ standard library container, so `iterators<>` can be particularly helpful when wrapping them.
|
||||
|
||||
In the table below, x is an instance of C.
|
||||
[table
|
||||
@@ -78,18 +78,18 @@ template <class Accessor1, class Accessor2>
|
||||
object range(Accessor1 start, Accessor2 finish);
|
||||
``
|
||||
[variablelist
|
||||
[[Requires][ NextPolicies is a default-constructible model of CallPolicies.]]
|
||||
[[Effects][The first form creates a Python callable object which, when invoked, converts its argument to a Target object x, and creates a Python iterator which traverses `[bind(start,_1)(x), bind(finish,_1)(x))`, applying NextPolicies to the iterator's next() function.
|
||||
[[Requires][ NextPolicies is a default-constructible model of [link concepts.callpolicies CallPolicies].]]
|
||||
[[Effects][The first form creates a Python callable object which, when invoked, converts its argument to a Target object x, and creates a Python iterator which traverses `[bind(start,_1)(x), bind(finish,_1)(x))`, applying NextPolicies to the iterator's `next()` function.
|
||||
The second form is identical to the first, except that Target is deduced from Accessor1 as follows:
|
||||
|
||||
# If Accessor1 is a function type, Target is the type of its first argument.
|
||||
# If Accessor1 is a data member pointer of the form `R (T::*)`, Target is identical to `T`.
|
||||
# If Accessor1 is a member function pointer of the form `R (T::*)(arguments...) cv-opt`, where cv-opt is an optional cv-qualifier, Target is identical to `T`.
|
||||
|
||||
The third form is identical to the second, except that NextPolicies is an unspecified model of CallPolicies which always makes a copy of the result of deferencing the underlying C++ iterator
|
||||
The third form is identical to the second, except that NextPolicies is an unspecified model of [link concepts.callpolicies CallPolicies] which always makes a copy of the result of deferencing the underlying C++ iterator
|
||||
|
||||
]]
|
||||
[[Rationale][The use of boost::bind() allows C++ iterators to be accessed through functions, member functions or data member pointers. Customization of NextPolicies (e.g. using return_internal_reference) is useful when it is expensive to copy sequence elements of a wrapped class type. Customization of Target is useful when Accessor1 is a function object, or when a base class of the intended target type would otherwise be deduced.]]
|
||||
[[Rationale][The use of `boost::bind()` allows C++ iterators to be accessed through functions, member functions or data member pointers. Customization of NextPolicies (e.g. using [link function_invocation_and_creation.models_of_callpolicies.boost_python_return_internal_ref.class_template_return_internal_r return_internal_reference]) is useful when it is expensive to copy sequence elements of a wrapped class type. Customization of Target is useful when Accessor1 is a function object, or when a base class of the intended target type would otherwise be deduced.]]
|
||||
]
|
||||
[endsect]
|
||||
[section Example]
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
[section list.hpp]
|
||||
[section boost_python_list.hpp]
|
||||
[section Introduction]
|
||||
Exposes a TypeWrapper for the Python list type.
|
||||
Exposes a [link concepts.objectwrapper.typewrapper_concept_requirements TypeWrapper] for the Python [@http://www.python.org/doc/current/lib/typesseq-mutable.html list] type.
|
||||
[endsect]
|
||||
[section Class `list`]
|
||||
Exposes the mapping protocol of Python's built-in list type. The semantics of the constructors and member functions defined below can be fully understood by reading the TypeWrapper concept definition. Since list is publicly derived from object, the public object interface applies to list instances as well.``
|
||||
Exposes the [@http://www.python.org/doc/current/lib/typesseq-mutable.html mapping protocol] of Python's built-in `list` type. The semantics of the constructors and member functions defined below can be fully understood by reading the [link concepts.objectwrapper.typewrapper_concept_requirements TypeWrapper] concept definition. Since `list` is publicly derived from [link object_wrappers.boost_python_object_hpp.class_object `object`], the public `object` interface applies to `list` instances as well.``
|
||||
namespace boost { namespace python
|
||||
{
|
||||
class list : public object
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
[section long.hpp]
|
||||
[section boost/python/long.hpp]
|
||||
[section Introduction]
|
||||
Exposes a TypeWrapper for the Python long integer type.
|
||||
Exposes a [link concepts.objectwrapper.typewrapper_concept_requirements TypeWrapper] for the Python [@http://www.python.org/doc/current/lib/typesnumeric.html long] integer type.
|
||||
[endsect]
|
||||
[section Class `long_`]
|
||||
Exposes the numeric type protocol of Python's built-in long type. The semantics of the constructors and member functions defined below can be fully understood by reading the TypeWrapper concept definition. Since long_ is publicly derived from object, the public object interface applies to long_ instances as well.
|
||||
Exposes the [@http://www.python.org/doc/current/lib/typesnumeric.html numeric type protocol] of Python's built-in `long` type. The semantics of the constructors and member functions defined below can be fully understood by reading the [link concepts.objectwrapper.typewrapper_concept_requirements TypeWrapper] concept definition. Since `long_` is publicly derived from [link object_wrappers.boost_python_object_hpp.class_object `object`], the public `object` interface applies to `long_` instances as well.
|
||||
``
|
||||
namespace boost { namespace python
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[section lvalue_from_pytype.hpp]
|
||||
[section boost/python/lvalue_from_pytype.hpp]
|
||||
[section Introduction]
|
||||
<boost/python/lvalue_from_pytype.hpp> supplies a facility for extracting C++ objects from within Python instances of a given type. This is typically useful for dealing with "traditional" Python extension types.
|
||||
<boost/python/lvalue_from_pytype.hpp> supplies a facility for extracting C++ objects from within Python instances of a given type. This is typically useful for dealing with "traditional" Python extension types.
|
||||
[endsect]
|
||||
[section Class template `lvalue_from_pytype`]
|
||||
Class template lvalue_from_pytype will register from_python converters which, given an object of the given Python type, can extract references and pointers to a particular C++ type. Its template arguments are:
|
||||
@@ -8,8 +8,8 @@ Class template lvalue_from_pytype will register from_python converters which, gi
|
||||
In the table below, x denotes an object of type PythonObject&
|
||||
[table
|
||||
[[Parameter][Requirements][Semantics]]
|
||||
[[Extractor][a model of Extractor whose execute function returns a reference type.][Extracts the lvalue from the Python object once its type has been confirmed]]
|
||||
[[python_type][A compile-time constant PyTypeObject*][The Python type of instances convertible by this converter. Python subtypes are also convertible.]]
|
||||
[[Extractor][a model of [link concepts.extractor `Extractor`] whose execute function returns a reference type.][Extracts the lvalue from the Python object once its type has been confirmed]]
|
||||
[[python_type][A compile-time constant [@http://www.python.org/doc/2.2/ext/dnt-type-methods.html `PyTypeObject*`]][The Python type of instances convertible by this converter. Python subtypes are also convertible.]]
|
||||
]
|
||||
``
|
||||
namespace boost { namespace python
|
||||
@@ -29,7 +29,7 @@ namespace boost { namespace python
|
||||
[endsect]
|
||||
[endsect]
|
||||
[section Class template `extract_identity`]
|
||||
extract_identity is a model of Extractor which can be used in the common case where the C++ type to be extracted is the same as the Python object type.
|
||||
extract_identity is a model of [link concepts.extractor `Extractor`] which can be used in the common case where the C++ type to be extracted is the same as the Python object type.
|
||||
``
|
||||
namespace boost { namespace python
|
||||
{
|
||||
@@ -48,7 +48,7 @@ namespace boost { namespace python
|
||||
[endsect]
|
||||
[endsect]
|
||||
[section Class template `extract_member`]
|
||||
extract_member is a model of Extractor which can be used in the common case in the common case where the C++ type to be extracted is a member of the Python object.
|
||||
`extract_member` is a model of [link concepts.extractor `Extractor`] which can be used in the common case in the common case where the C++ type to be extracted is a member of the Python object.
|
||||
``
|
||||
namespace boost { namespace python
|
||||
{
|
||||
@@ -67,7 +67,7 @@ namespace boost { namespace python
|
||||
[endsect]
|
||||
[endsect]
|
||||
[section Example]
|
||||
This example presumes that someone has implemented the standard noddy example module from the Python documentation, and we want to build a module which manipulates Noddys. Since noddy_NoddyObject is so simple that it carries no interesting information, the example is a bit contrived: it assumes you want to keep track of one particular object for some reason. This module would have to be dynamically linked to the module which defines noddy_NoddyType.
|
||||
This example presumes that someone has implemented the standard noddy example module from the Python documentation, and we want to build a module which manipulates Noddys. Since noddy_NoddyObject is so simple that it carries no interesting information, the example is a bit contrived: it assumes you want to keep track of one particular object for some reason. This module would have to be dynamically linked to the module which defines noddy_NoddyType.
|
||||
|
||||
In C++:
|
||||
``
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[section make_function.hpp]
|
||||
[section boost/python/make_function.hpp]
|
||||
[section Introduction]
|
||||
make_function() and make_constructor() are the functions used internally by def() and class_<>::def() to produce Python callable objects which wrap C++ functions and member functions.
|
||||
[endsect]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[section manage_new_object.hpp]
|
||||
[section boost/python/manage_new_object.hpp]
|
||||
[section Class `manage_new_object`]
|
||||
manage_new_object is a model of ResultConverterGenerator which can be used to wrap C++ functions which return a pointer to an object allocated with a new-expression, and expect the caller to take responsibility for deleting that object.
|
||||
`manage_new_object` is a model of [link concepts.resultconverter.resultconvertergenerator_concept ResultConverterGenerator] which can be used to wrap C++ functions which return a pointer to an object allocated with a new-expression, and expect the caller to take responsibility for deleting that object.
|
||||
``
|
||||
namespace boost { namespace python
|
||||
{
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
[section module.hpp]
|
||||
[section boost/python/module.hpp]
|
||||
[section Introduction]
|
||||
This header provides the basic facilities needed to create a Boost.Python extension module.
|
||||
[endsect]
|
||||
[section Macros]
|
||||
`BOOST_PYTHON_MODULE(name)` is used to declare Python module initialization functions. The name argument must exactly match the name of the module to be initialized, and must conform to Python's identifier naming rules. Where you would normally write
|
||||
`BOOST_PYTHON_MODULE(name)` is used to declare Python [@http://www.python.org/doc/2.2/ext/methodTable.html#SECTION003400000000000000000 module initialization functions]. The name argument must exactly match the name of the module to be initialized, and must conform to Python's [@http://www.python.org/doc/2.2/ref/identifiers.html identifier naming rules]. Where you would normally write
|
||||
|
||||
``
|
||||
extern "C" void initname()
|
||||
@@ -18,7 +18,7 @@ BOOST_PYTHON_MODULE(name)
|
||||
...
|
||||
}
|
||||
``
|
||||
This macro generates two functions in the scope where it is used: `extern "C" void initname()`, and `void init_module_name()`, whose body must follow the macro invocation. `init_name` passes `init_module_name` to `handle_exception()` so that any C++ exceptions generated are safely processeed. During the body of `init_name`, the current scope refers to the module being initialized.
|
||||
This macro generates two functions in the scope where it is used: `extern "C" void initname()`, and `void init_module_name()`, whose body must follow the macro invocation. `init_name` passes `init_module_name` to [link high_level_components.boost_python_errors_hpp.functions handle_exception()] so that any C++ exceptions generated are safely processeed. During the body of `init_name`, the [link high_level_components.boost_python_scope_hpp current scope] refers to the module being initialized.
|
||||
[endsect]
|
||||
[section Examples]
|
||||
C++ module definition:
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
[section numeric.hpp]
|
||||
[section boost/python/numeric.hpp]
|
||||
[section Introduction]
|
||||
Exposes a TypeWrapper for the Python array type.
|
||||
Exposes a [link concepts.objectwrapper.typewrapper_concept_requirements TypeWrapper] for the Python [@http://www.python.org/dev/doc/devel/lib/typesmapping.html array] type.
|
||||
[endsect]
|
||||
[section Class `array`]
|
||||
Provides access to the array types of Numerical Python's Numeric and NumArray modules. With the exception of the functions documented below, the semantics of the constructors and member functions defined below can be fully understood by reading the TypeWrapper concept definition. Since array is publicly derived from object, the public object interface applies to array instances as well.
|
||||
Provides access to the array types of [@http://www.pfdubois.com/numpy/ Numerical Python]\ 's [@http://www.pfdubois.com/numpy/#Numeric Numeric] and [@http://stsdas.stsci.edu/numarray/index.html NumArray] modules. With the exception of the functions documented below, the semantics of the constructors and member functions defined below can be fully understood by reading the [link concepts.objectwrapper.typewrapper_concept_requirements TypeWrapper] concept definition. Since array is publicly derived from object, the public object interface applies to array instances as well.
|
||||
|
||||
The default behavior is to use numarray.NDArray as the associated Python type if the numarray module is installed in the default location. Otherwise it falls back to use Numeric.ArrayType. If neither extension module is installed, overloads of wrapped C++ functions with numeric::array parameters will never be matched, and other attempted uses of numeric::array will raise an appropriate Python exception. The associated Python type can be set manually using the set_module_and_type(...) static function.
|
||||
``
|
||||
@@ -130,12 +130,12 @@ static void set_module_and_type(char const* package_path, char const* type_name)
|
||||
static void set_module_and_type();
|
||||
``
|
||||
[variablelist
|
||||
[[Requires][package_path and type_name, if supplied, is an ntbs.]]
|
||||
[[Requires][package_path and type_name, if supplied, is an [link ntbs].]]
|
||||
[[Effects][The first form sets the package path of the module that supplies the type named by type_name to package_path. The second form restores the default search behavior. The associated Python type will be searched for only the first time it is needed, and thereafter the first time it is needed after an invocation of set_module_and_type.]]
|
||||
]
|
||||
``static std::string get_module_name()``
|
||||
[variablename
|
||||
[[Effects][Returns the name of the module containing the class that will be held by new numeric::array instances.]]
|
||||
[variablelist
|
||||
[[Effects][Returns the name of the module containing the class that will be held by new `numeric::array` instances.]]
|
||||
]
|
||||
[endsect]
|
||||
[section Example]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[section object.hpp]
|
||||
[section boost/python/object.hpp]
|
||||
[section Introduction]
|
||||
Exposes the generic Python object wrapper class object, and related classes. In order to avoid some potenential problems with argument-dependent lookup and the generalized operators defined on object, all these facilities are defined in namespace boost::python::api, and object is imported into namespace boost::python with a using-declaration.
|
||||
[endsect]
|
||||
@@ -36,10 +36,10 @@ namespace boost { namespace python { namespace api
|
||||
static object get(object const& target, char const* key);
|
||||
``
|
||||
[variablelist
|
||||
[[Requires][key is an ntbs.]]
|
||||
[[Requires][key is an [link ntbs].]]
|
||||
[[Effects][accesses the attribute of target named by key.]]
|
||||
[[Returns][An object managing the result of the attribute access.]]
|
||||
[[Throws][error_already_set if a Python exception is raised.]]
|
||||
[[Throws][[link high_level_components.boost_python_errors_hpp.class_error_already_set error_already_set] if a Python exception is raised.]]
|
||||
]
|
||||
[endsect]
|
||||
[section Class `attribute_policies`]
|
||||
@@ -60,17 +60,17 @@ namespace boost { namespace python { namespace api
|
||||
static object const& set(object const& target, char const* key, object const& value);
|
||||
``
|
||||
[variablelist
|
||||
[[Requires][key is an ntbs.]]
|
||||
[[Requires][key is an [link ntbs].]]
|
||||
[[Effects][sets the attribute of target named by key to value.]]
|
||||
[[Throws][error_already_set if a Python exception is raised.]]
|
||||
[[Throws][[link high_level_components.boost_python_errors_hpp.class_error_already_set error_already_set] if a Python exception is raised.]]
|
||||
]
|
||||
``
|
||||
static void del(object const&target, char const* key);
|
||||
``
|
||||
[variablelist
|
||||
[[Requires][key is an ntbs.]]
|
||||
[[Requires][key is an [link ntbs].]]
|
||||
[[Effects][deletes the attribute of target named by key.]]
|
||||
[[Throws][error_already_set if a Python exception is raised.]]
|
||||
[[Throws][[link high_level_components.boost_python_errors_hpp.class_error_already_set error_already_set] if a Python exception is raised.]]
|
||||
]
|
||||
[endsect]
|
||||
[section Class `const_objattribute_policies`]
|
||||
@@ -94,7 +94,7 @@ static object get(object const& target, object const& key);
|
||||
[[Requires][key is an object holding a string.]]
|
||||
[[Effects][accesses the attribute of target named by key.]]
|
||||
[[Returns][An object managing the result of the attribute access.]]
|
||||
[[Throws][error_already_set if a Python exception is raised.]]
|
||||
[[Throws][[link high_level_components.boost_python_errors_hpp.class_error_already_set error_already_set] if a Python exception is raised.]]
|
||||
]
|
||||
[endsect]
|
||||
[section Class `objattribute_policies`]
|
||||
@@ -117,7 +117,7 @@ static object const& set(object const& target, object const& key, object const&
|
||||
[variablelist
|
||||
[[Requires][key is an object holding a string.]]
|
||||
[[Effects][sets the attribute of target named by key to value.]]
|
||||
[[Throws][error_already_set if a Python exception is raised.]]
|
||||
[[Throws][[link high_level_components.boost_python_errors_hpp.class_error_already_set error_already_set] if a Python exception is raised.]]
|
||||
]
|
||||
``
|
||||
static void del(object const&target, object const& key);
|
||||
@@ -125,7 +125,7 @@ static void del(object const&target, object const& key);
|
||||
[variablelist
|
||||
[[Requires][key is an object holding a string.]]
|
||||
[[Effects][deletes the attribute of target named by key.]]
|
||||
[[Throws][error_already_set if a Python exception is raised.]]
|
||||
[[Throws][[link high_level_components.boost_python_errors_hpp.class_error_already_set error_already_set] if a Python exception is raised.]]
|
||||
]
|
||||
[endsect]
|
||||
[section Class `const_item_policies`]
|
||||
@@ -148,7 +148,7 @@ static object get(object const& target, object const& key);
|
||||
[variablelist
|
||||
[[Effects][accesses the item of target specified by key.]]
|
||||
[[Returns][An object managing the result of the item access.]]
|
||||
[[Throws][error_already_set if a Python exception is raised.]]
|
||||
[[Throws][[link high_level_components.boost_python_errors_hpp.class_error_already_set error_already_set] if a Python exception is raised.]]
|
||||
]
|
||||
[endsect]
|
||||
[section Class `item_policies`]
|
||||
@@ -170,14 +170,14 @@ static object const& set(object const& target, object const& key, object const&
|
||||
``
|
||||
[variablelist
|
||||
[[Effects][sets the item of target specified by key to value.]]
|
||||
[[Throws][error_already_set if a Python exception is raised.]]
|
||||
[[Throws][[link high_level_components.boost_python_errors_hpp.class_error_already_set error_already_set] if a Python exception is raised.]]
|
||||
]
|
||||
``
|
||||
static void del(object const& target, object const& key);
|
||||
``
|
||||
[variablelist
|
||||
[[Effects][deletes the item of target specified by key.]]
|
||||
[[Throws][ error_already_set if a Python exception is raised.]]
|
||||
[[Throws][[link high_level_components.boost_python_errors_hpp.class_error_already_set error_already_set] if a Python exception is raised.]]
|
||||
]
|
||||
[endsect]
|
||||
[section Class `const_slice_policies`]
|
||||
@@ -200,7 +200,7 @@ static object get(object const& target, key_type const& key);
|
||||
[variablelist
|
||||
[[Effects][accesses the slice of target specified by key.]]
|
||||
[[Returns][An object managing the result of the slice access.]]
|
||||
[[Throws][error_already_set if a Python exception is raised.]]
|
||||
[[Throws][[link high_level_components.boost_python_errors_hpp.class_error_already_set error_already_set] if a Python exception is raised.]]
|
||||
]
|
||||
[endsect]
|
||||
[section Class `slice_policies`]
|
||||
@@ -222,14 +222,14 @@ static object const& set(object const& target, key_type const& key, object const
|
||||
``
|
||||
[variablelist
|
||||
[[Effects][sets the slice of target specified by key to value.]]
|
||||
[[Throws][error_already_set if a Python exception is raised.]]
|
||||
[[Throws][[link high_level_components.boost_python_errors_hpp.class_error_already_set error_already_set] if a Python exception is raised.]]
|
||||
]
|
||||
``
|
||||
static void del(object const& target, key_type const& key);
|
||||
``
|
||||
[variablelist
|
||||
[[Effects][deletes the slice of target specified by key.]]
|
||||
[[Throws][error_already_set if a Python exception is raised.]]
|
||||
[[Throws][[link high_level_components.boost_python_errors_hpp.class_error_already_set error_already_set] if a Python exception is raised.]]
|
||||
]
|
||||
[endsect]
|
||||
[section Class template `object_operators`]
|
||||
@@ -324,9 +324,9 @@ proxy<const_object_attribute> attr(char const* name) const;
|
||||
proxy<object_attribute> attr(char const* name);
|
||||
``
|
||||
[variablelist
|
||||
[[Requires][name is an ntbs.]]
|
||||
[[Requires][name is an [link ntbs].]]
|
||||
[[Effects][accesses the named attribute of *this.]]
|
||||
[[Returns][a proxy object which binds object(*static_cast<U*>(this)) as its target, and name as its key.]]
|
||||
[[Returns][a proxy object which binds `object(*static_cast<U*>(this))` as its target, and name as its key.]]
|
||||
]
|
||||
``
|
||||
proxy<const_object_objattribute> attr(const object& name) const;
|
||||
@@ -334,8 +334,8 @@ proxy<object_objattribute> attr(const object& name);
|
||||
``
|
||||
[variablelist
|
||||
[[Requires][name is a object holding a string.]]
|
||||
[[Effects][accesses the named attribute of *this.]]
|
||||
[[Returns][a proxy object which binds object(*static_cast<U*>(this)) as its target, and name as its key.]]
|
||||
[[Effects][accesses the named attribute of `*this`.]]
|
||||
[[Returns][a proxy object which binds `object(*static_cast<U*>(this))` as its target, and name as its key.]]
|
||||
]
|
||||
``
|
||||
template <class T>
|
||||
@@ -344,8 +344,8 @@ template <class T>
|
||||
proxy<object_item> operator[](T const& key);
|
||||
``
|
||||
[variablelist
|
||||
[[Effects][accesses the item of *this indicated by key.]]
|
||||
[[Returns][a proxy object which binds object(*static_cast<U*>(this)) as its target, and object(key) as its key.]]
|
||||
[[Effects][accesses the item of `*this` indicated by key.]]
|
||||
[[Returns][a proxy object which binds `object(*static_cast<U*>(this))` as its target, and object(key) as its key.]]
|
||||
]
|
||||
``
|
||||
template <class T, class V>
|
||||
@@ -354,12 +354,12 @@ template <class T, class V>
|
||||
proxy<object_slice> slice(T const& start; start, V const& finish);
|
||||
``
|
||||
[variablelist
|
||||
[[Effects][accesses the slice of *this indicated by std::make_pair(object(start), object(finish)).]]
|
||||
[[Returns][a proxy object which binds object(*static_cast<U*>(this)) as its target, and std::make_pair(object(start), object(finish)) as its key.]]
|
||||
[[Effects][accesses the slice of `*this` indicated by `std::make_pair(object(start), object(finish))`.]]
|
||||
[[Returns][a proxy object which binds `object(*static_cast<U*>(this))` as its target, and `std::make_pair(object(start), object(finish))` as its key.]]
|
||||
]
|
||||
[endsect]
|
||||
[section Class `object`]
|
||||
The intention is that object acts as much like a Python variable as possible. Thus expressions you'd expect to work in Python should generally work in the same way from C++. Most of object's interface is provided by its base class object_operators<object>, and the free functions defined in this header.
|
||||
The intention is that object acts as much like a Python variable as possible. Thus expressions you'd expect to work in Python should generally work in the same way from C++. Most of object's interface is provided by its base class `object_operators<object>`, and the free functions defined in this header.
|
||||
``
|
||||
namespace boost { namespace python { namespace api
|
||||
{
|
||||
@@ -391,7 +391,7 @@ explicit object(T const& x);
|
||||
``
|
||||
[variablelist
|
||||
[[Effects][converts x to python and manages a reference to it.]]
|
||||
[[Throws][error_already_set and sets a Python TypeError exception if no such conversion is possible.]]
|
||||
[[Throws][[link high_level_components.boost_python_errors_hpp.class_error_already_set error_already_set] and sets a Python TypeError exception if no such conversion is possible.]]
|
||||
]
|
||||
``
|
||||
~object();
|
||||
@@ -409,7 +409,7 @@ explicit object(T const& x);
|
||||
``bool is_none() const;``
|
||||
|
||||
[variablelist
|
||||
[[Returns] [result of (ptr() == Py_None)]]
|
||||
[[Returns] [result of `(ptr() == Py_None)`]]
|
||||
]
|
||||
[endsect]
|
||||
[section Class template `proxy`]
|
||||
@@ -454,7 +454,7 @@ namespace boost { namespace python { namespace api
|
||||
[section Class template `proxy` observer functions]
|
||||
``operator object() const;``
|
||||
[variablelist
|
||||
[[Effects][applies Policies::get(target, key ) with the proxy's target and key objects.]]
|
||||
[[Effects][applies `Policies::get(target, key)` with the proxy's target and key objects.]]
|
||||
]
|
||||
[endsect]
|
||||
[section Class template `proxy` modifier functions]
|
||||
@@ -464,7 +464,7 @@ template <class T>
|
||||
inline proxy const& operator=(T const& rhs) const;
|
||||
``
|
||||
[variablelist
|
||||
[[Effects][ Policies::set(target, key , object(rhs)) with the proxy's target and key objects.]]
|
||||
[[Effects][ `Policies::set(target, key , object(rhs))` with the proxy's target and key objects.]]
|
||||
]
|
||||
``
|
||||
template <class R>
|
||||
@@ -487,7 +487,7 @@ template <class R>
|
||||
proxy operator|=(R const& rhs);
|
||||
``
|
||||
[variablelist
|
||||
[[Effects][for a given operator@=, object(*this) @= rhs;]]
|
||||
[[Effects][for a given `operator@=`, `object(*this) @= rhs;`]]
|
||||
[[Returns][`*this`]]
|
||||
]
|
||||
``void del() const;``
|
||||
@@ -512,7 +512,7 @@ template<class L,class R> object operator==(L const&l,R const&r);
|
||||
template<class L,class R> object operator!=(L const&l,R const&r);
|
||||
``
|
||||
[variablelist
|
||||
[[Effects][returns the result of applying the operator to object(l) and object(r), respectively, in Python.]]
|
||||
[[Effects][returns the result of applying the operator to `object(l)` and `object(r)`, respectively, in Python.]]
|
||||
]
|
||||
``
|
||||
template<class L,class R> object operator+(L const&l,R const&r);
|
||||
@@ -527,7 +527,7 @@ template<class L,class R> object operator^(L const&l,R const&r);
|
||||
template<class L,class R> object operator|(L const&l,R const&r);
|
||||
``
|
||||
[variablelist
|
||||
[[Effects][returns the result of applying the operator to object(l) and object(r), respectively, in Python.]]
|
||||
[[Effects][returns the result of applying the operator to `object(l)` and `object(r)`, respectively, in Python.]]
|
||||
]
|
||||
``
|
||||
template<class R> object& operator+=(object&l,R const&r);
|
||||
@@ -542,7 +542,7 @@ template<class R> object& operator^=(object&l,R const&r);
|
||||
template<class R> object& operator|=(object&l,R const&r);
|
||||
``
|
||||
[variablelist
|
||||
[[Effects][assigns to l the result of applying the corresponding Python inplace operator to l and object(r), respectively.]]
|
||||
[[Effects][assigns to `l` the result of applying the corresponding Python inplace operator to `l` and `object(r)`, respectively.]]
|
||||
[[Returns][l]]
|
||||
]
|
||||
``long len(object const& obj);``
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[section opaque_pointer_converter.hpp]
|
||||
[section boost/python/opaque_pointer_converter.hpp]
|
||||
[section Introduction]
|
||||
opaque<> registers itself as a converter from Python objects to pointers to undefined types and vice versa.
|
||||
`opaque<>` registers itself as a converter from Python objects to pointers to undefined types and vice versa.
|
||||
``
|
||||
namespace boost { namespace python
|
||||
{
|
||||
@@ -11,20 +11,21 @@ namespace boost { namespace python
|
||||
};
|
||||
}}
|
||||
``
|
||||
[section Class template opaque constructor]
|
||||
[endsect]
|
||||
[section Class template `opaque` constructor]
|
||||
``opaque();``
|
||||
[variablelist
|
||||
[[Effects][
|
||||
* Registers the instance as a lvalue_from_pytype converter from Python objects into opaque pointers.
|
||||
* Registers the instance as a [link to_from_python_type_conversion.boost_python_lvalue_from_pytype_.class_template_lvalue_from_pytyp `lvalue_from_pytype`] converter from Python objects into opaque pointers.
|
||||
The Python Objects created are named after the type pointed to by the opaque pointer being wrapped.
|
||||
* Registers the instance as a to_python_converter from opaque pointers to Python objects.
|
||||
* Registers the instance as a [link to_from_python_type_conversion.boost_python_to_python_converter.class_template_to_python_convert `to_python_converter`] from opaque pointers to Python objects.
|
||||
]]
|
||||
]
|
||||
[note If there is already an instance registered by another module, this instance doesn't try to register again in order to avoid warnings about multiple registrations.]
|
||||
|
||||
[endsect]
|
||||
[section Macro `BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID(Pointee)`]
|
||||
This macro must be used to define specializations of the type_id function which can't be instantiated for incomplete types.
|
||||
This macro must be used to define specializations of the [link utility_and_infrastructure.boost_python_type_id_hpp.functions `type_id`] function which can't be instantiated for incomplete types.
|
||||
[note The macro must be invoked in every translation unit which uses the opaque converter.]
|
||||
[endsect]
|
||||
[endsect]
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
[section operators.hpp]
|
||||
[section boost/python/operators.hpp]
|
||||
[section Introduction]
|
||||
<boost/python/operators.hpp> provides types and functions for automatically generating Python special methods from the corresponding C++ constructs. Most of these constructs are operator expressions, hence the name. To use the facility, substitute the self object for an object of the class type being wrapped in the expression to be exposed, and pass the result to class_<>::def(). Much of what is exposed in this header should be considered part of the implementation, so is not documented in detail here.
|
||||
<boost/python/operators.hpp> provides types and functions for automatically generating Python [@http://www.python.org/doc/ref/specialnames.html special methods] from the corresponding C++ constructs. Most of these constructs are operator expressions, hence the name. To use the facility, substitute the [link high_level_components.boost_python_operators_hpp.object_self self] object for an object of the class type being wrapped in the expression to be exposed, and pass the result to [link high_level_components.boost_python_class_hpp.class_template_class_t_bases_hel.class_template_class_modifier_fu class_<>::def()]. Much of what is exposed in this header should be considered part of the implementation, so is not documented in detail here.
|
||||
[endsect]
|
||||
[section Class `self_ns::self_t`]
|
||||
`self_ns::self_t` is the actual type of the self object. The library isolates `self_t` in its own namespace, `self_ns`, in order to prevent the generalized operator templates which operate on it from being found by argument-dependent lookup in other contexts. This should be considered an implementation detail, since users should never have to mention `self_t` directly.
|
||||
`self_ns::self_t` is the actual type of the [link high_level_components.boost_python_operators_hpp.object_self self] object. The library isolates `self_t` in its own namespace, `self_ns`, in order to prevent the generalized operator templates which operate on it from being found by argument-dependent lookup in other contexts. This should be considered an implementation detail, since users should never have to mention `self_t` directly.
|
||||
``
|
||||
namespace boost { namespace python { namespace self_ns {
|
||||
{
|
||||
@@ -58,9 +58,9 @@ namespace boost { namespace python { namespace self_ns {
|
||||
operator_<unspecified> repr(self_t);
|
||||
}}};
|
||||
``
|
||||
The tables below describe the methods generated when the results of the expressions described are passed as arguments to class_<>::def(). x is an object of the class type being wrapped.
|
||||
The tables below describe the methods generated when the results of the expressions described are passed as arguments to [link high_level_components.boost_python_class_hpp.class_template_class_t_bases_hel.class_template_class_modifier_fu class_<>::def()]. `x` is an object of the class type being wrapped.
|
||||
[section `self_t` inplace operators]
|
||||
In the table below, If r is an object of type other<T>, y is an object of type T; otherwise, y is an object of the same type as r.
|
||||
In the table below, If `r` is an object of type [link high_level_components.boost_python_operators_hpp.class_template_other other<T>], `y` is an object of type `T`; otherwise, `y` is an object of the same type as `r`.
|
||||
[table
|
||||
[[C++ Expression][Python Method Name][C++ Implementation]]
|
||||
[[`self += r`][`__iadd__`][`x += y`]]
|
||||
@@ -76,12 +76,12 @@ In the table below, If r is an object of type other<T>, y is an object of type T
|
||||
]
|
||||
[endsect]
|
||||
[section `self_t` comparison functions]
|
||||
In the tables below, if r is of type self_t, y is an object of the same type as x;
|
||||
if l or r is an object of type other<T>, y is an object of type T;
|
||||
otherwise, y is an object of the same type as l or r.
|
||||
l is never of type self_t.
|
||||
In the tables below, if `r` is of type [link high_level_components.boost_python_operators_hpp.class_self_ns_self_t self_t], `y` is an object of the same type as `x`;
|
||||
if `l` or `r` is an object of type [link high_level_components.boost_python_operators_hpp.class_template_other other<T>], `y` is an object of type `T`;
|
||||
otherwise, `y` is an object of the same type as `l` or `r`.
|
||||
`l` is never of type [link high_level_components.boost_python_operators_hpp.class_self_ns_self_t self_t].
|
||||
|
||||
The column of Python Expressions illustrates the expressions that will be supported in Python for objects convertible to the types of x and y. The secondary operation arises due to Python's reflection rules for rich comparison operators, and are only used when the corresponding operation is not defined as a method of the y object.
|
||||
The column of Python Expressions illustrates the expressions that will be supported in Python for objects convertible to the types of x and y. The secondary operation arises due to Python's [@http://www.python.org/doc/ref/customization.html#l2h-89 reflection rules] for rich comparison operators, and are only used when the corresponding operation is not defined as a method of the y object.
|
||||
[table
|
||||
[[C++ Expression][Python Method Name][C++ Implementation][Python Expression (primary, secondary)]]
|
||||
[[`self == r`][`__eq__`][`x == y`][`x == y`, `y == x`]]
|
||||
@@ -99,7 +99,7 @@ The column of Python Expressions illustrates the expressions that will be suppor
|
||||
]
|
||||
[endsect]
|
||||
[section `self_t` non-member operations]
|
||||
The operations whose names begin with "__r" below will only be called if the left-hand operand does not already support the given operation, as described here.
|
||||
The operations whose names begin with "__r" below will only be called if the left-hand operand does not already support the given operation, as described [@http://www.python.org/doc/current/ref/numeric-types.html#l2h-152 here].
|
||||
[table
|
||||
[[C++ Expression][Python Method Name][C++ Implementation]]
|
||||
[[`self + r`][`__add__`][`x + y`]]
|
||||
@@ -148,7 +148,7 @@ The operations whose names begin with "__r" below will only be called if the lef
|
||||
[endsect]
|
||||
[endsect]
|
||||
[section Class template `other`]
|
||||
Instances of other<T> can be used in operator expressions with self; the result is equivalent to the same expression with a T object in place of other<T>. Use other<T> to prevent construction of a T object in case it is heavyweight, when no constructor is available, or simply for clarity.
|
||||
Instances of `other<T>` can be used in operator expressions with [link high_level_components.boost_python_operators_hpp.object_self self]; the result is equivalent to the same expression with a `T` object in place of `other<T>`. Use `other<T>` to prevent construction of a `T` object in case it is heavyweight, when no constructor is available, or simply for clarity.
|
||||
``
|
||||
namespace boost { namespace python
|
||||
{
|
||||
@@ -160,7 +160,7 @@ namespace boost { namespace python
|
||||
``
|
||||
[endsect]
|
||||
[section Class template `detail::operator_`]
|
||||
Instantiations of detail::operator_<> are used as the return type of operator expressions involving self. This should be considered an implementation detail and is only documented here as a way of showing how the result of self-expressions match calls to class_<>::def().
|
||||
Instantiations of `detail::operator_<>` are used as the return type of operator expressions involving [link high_level_components.boost_python_operators_hpp.object_self self]. This should be considered an implementation detail and is only documented here as a way of showing how the result of self-expressions match calls to [link high_level_components.boost_python_class_hpp.class_template_class_t_bases_hel.class_template_class_modifier_fu `class_<>::def()`].
|
||||
``
|
||||
namespace boost { namespace python { namespace detail
|
||||
{
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
[section overloads.hpp]
|
||||
[section boost/python/overloads.hpp]
|
||||
[section Introduction]
|
||||
Defines facilities for generating families of overloaded Python functions and extension class methods from C++ functions and member functions with default arguments, or from similar families of C++ overloads
|
||||
[section overload-dispatch-expressions]
|
||||
An overload-dispatch-expression is used to describe a family of overloaded methods to be generated for an extension class. It has the following properties:
|
||||
[variablelist
|
||||
[[docstring][An ntbs whose value will bound to the methods' __doc__ attribute]]
|
||||
[[keywords][A keyword-expression which will be used to name (a trailing subsequence of) the arguments to the generated methods.]]
|
||||
[[docstring][An [link ntbs] whose value will bound to the methods' `__doc__` attribute]]
|
||||
[[keywords][A [link function_invocation_and_creation.boost_python_args_hpp.introduction.keyword_expressions keyword-expression] which will be used to name (a trailing subsequence of) the arguments to the generated methods.]]
|
||||
[[call policies][An instance of some type which models CallPolicies.]]
|
||||
[[minimum arity][The minimum number of arguments to be accepted by a generated method overload.]]
|
||||
[[maximum arity][The maximum number of arguments to be accepted by a generated method overload.]]
|
||||
@@ -24,9 +24,9 @@ X(docstring)[policies]
|
||||
X(docstring, keywords)[policies]
|
||||
X(keywords, docstring)[policies]
|
||||
``
|
||||
* If policies are supplied, it must be an instance of a type which models CallPolicies, and will be used as the result's call policies. Otherwise the result's call policies will be an instance of default_call_policies.
|
||||
* If docstring is supplied it must be an ntbs, and will be used as the result's docstring. Otherwise the result has an empty docstring.
|
||||
* If keywords is supplied it must be the result of a keyword-expression whose length is no greater than X's maximum arity, and will be used as the result's keywords. Otherwise the result's keywords will be empty.
|
||||
* If policies are supplied, it must be an instance of a type which models [link concepts.callpolicies CallPolicies], and will be used as the result's call policies. Otherwise the result's call policies will be an instance of [link function_invocation_and_creation.models_of_callpolicies.boost_python_default_call_polici `default_call_policies`].
|
||||
* If docstring is supplied it must be an [link ntbs], and will be used as the result's docstring. Otherwise the result has an empty docstring.
|
||||
* If keywords is supplied it must be the result of a [link function_invocation_and_creation.boost_python_args_hpp.introduction.keyword_expressions keyword-expression] whose length is no greater than X's maximum arity, and will be used as the result's keywords. Otherwise the result's keywords will be empty.
|
||||
[endsect]
|
||||
[section Macros]
|
||||
``
|
||||
|
||||
@@ -4,24 +4,24 @@ Pickle is a Python module for object serialization, also known as persistence, m
|
||||
|
||||
It is often necessary to save and restore the contents of an object to a file. One approach to this problem is to write a pair of functions that read and write data from a file in a special format. A powerful alternative approach is to use Python's pickle module. Exploiting Python's ability for introspection, the pickle module recursively converts nearly arbitrary Python objects into a stream of bytes that can be written to a file.
|
||||
|
||||
The Boost Python Library supports the pickle module through the interface as described in detail in the Python Library Reference for pickle. This interface involves the special methods __getinitargs__, __getstate__ and __setstate__ as described in the following. Note that Boost.Python is also fully compatible with Python's cPickle module.
|
||||
The Boost Python Library supports the pickle module through the interface as described in detail in the [@http://www.python.org/doc/current/lib/module-pickle.html Python Library Reference for pickle]. This interface involves the special methods `__getinitargs__`, `__getstate__` and `__setstate__` as described in the following. Note that `Boost.Python` is also fully compatible with Python's cPickle module.
|
||||
[endsect]
|
||||
[section The Pickle Interface]
|
||||
At the user level, the Boost.Python pickle interface involves three special methods:
|
||||
[variablelist
|
||||
[[__getinitargs__][When an instance of a Boost.Python extension class is pickled, the pickler tests if the instance has a __getinitargs__ method. This method must return a Python tuple (it is most convenient to use a boost::python::tuple). When the instance is restored by the unpickler, the contents of this tuple are used as the arguments for the class constructor.
|
||||
[[__getinitargs__][When an instance of a Boost.Python extension class is pickled, the pickler tests if the instance has a `__getinitargs__` method. This method must return a Python `tuple` (it is most convenient to use a [link object_wrappers.boost_python_tuple_hpp.class_tuple `boost::python::tuple`]). When the instance is restored by the unpickler, the contents of this tuple are used as the arguments for the class constructor.
|
||||
|
||||
If __getinitargs__ is not defined, pickle.load will call the constructor (__init__) without arguments; i.e., the object must be default-constructible.]]
|
||||
[[__getstate__][ When an instance of a Boost.Python extension class is pickled, the pickler tests if the instance has a __getstate__ method. This method should return a Python object representing the state of the instance.]]
|
||||
[[__setstate__][When an instance of a Boost.Python extension class is restored by the unpickler (pickle.load), it is first constructed using the result of __getinitargs__ as arguments (see above). Subsequently the unpickler tests if the new instance has a __setstate__ method. If so, this method is called with the result of __getstate__ (a Python object) as the argument.]]
|
||||
If `__getinitargs__` is not defined, `pickle.load` will call the constructor (`__init__`) without arguments; i.e., the object must be default-constructible.]]
|
||||
[[__getstate__][When an instance of a `Boost.Python` extension class is pickled, the pickler tests if the instance has a `__getstate__` method. This method should return a Python object representing the state of the instance.]]
|
||||
[[__setstate__][When an instance of a `Boost.Python` extension class is restored by the unpickler (`pickle.load`), it is first constructed using the result of `__getinitargs__` as arguments (see above). Subsequently the unpickler tests if the new instance has a `__setstate__` method. If so, this method is called with the result of `__getstate__` (a Python object) as the argument.]]
|
||||
]
|
||||
|
||||
The three special methods described above may be .def()'ed individually by the user. However, Boost.Python provides an easy to use high-level interface via the boost::python::pickle_suite class that also enforces consistency: __getstate__ and __setstate__ must be defined as pairs. Use of this interface is demonstrated by the following examples.
|
||||
The three special methods described above may be `.def()`\ 'ed individually by the user. However, `Boost.Python` provides an easy to use high-level interface via the `boost::python::pickle_suite` class that also enforces consistency: `__getstate__` and `__setstate__` must be defined as pairs. Use of this interface is demonstrated by the following examples.
|
||||
[endsect]
|
||||
[section Example]
|
||||
There are three files in boost/libs/python/test that show how to provide pickle support.
|
||||
There are three files in `python/test` that show how to provide pickle support.
|
||||
[section pickle1.cpp]
|
||||
The C++ class in this example can be fully restored by passing the appropriate argument to the constructor. Therefore it is sufficient to define the pickle interface method __getinitargs__. This is done in the following way:
|
||||
The C++ class in this example can be fully restored by passing the appropriate argument to the constructor. Therefore it is sufficient to define the pickle interface method `__getinitargs__`. This is done in the following way:
|
||||
Definition of the C++ pickle function:
|
||||
``
|
||||
struct world_pickle_suite : boost::python::pickle_suite
|
||||
@@ -43,7 +43,7 @@ class_<world>("world", args<const std::string&>())
|
||||
``
|
||||
[endsect]
|
||||
[section pickle2.cpp]
|
||||
The C++ class in this example contains member data that cannot be restored by any of the constructors. Therefore it is necessary to provide the __getstate__/__setstate__ pair of pickle interface methods:
|
||||
The C++ class in this example contains member data that cannot be restored by any of the constructors. Therefore it is necessary to provide the `__getstate__`/`__setstate__` pair of pickle interface methods:
|
||||
|
||||
Definition of the C++ pickle functions:
|
||||
``
|
||||
@@ -80,36 +80,36 @@ Establishing the Python bindings for the entire suite:
|
||||
|
||||
``
|
||||
|
||||
For simplicity, the __dict__ is not included in the result of __getstate__. This is not generally recommended, but a valid approach if it is anticipated that the object's __dict__ will always be empty. Note that the safety guard described below will catch the cases where this assumption is violated.
|
||||
For simplicity, the `__dict__` is not included in the result of `__getstate__`. This is not generally recommended, but a valid approach if it is anticipated that the object's `__dict__` will always be empty. Note that the safety guard described below will catch the cases where this assumption is violated.
|
||||
[endsect]
|
||||
[section pickle3.cpp]
|
||||
This example is similar to pickle2.cpp. However, the object's __dict__ is included in the result of __getstate__. This requires a little more code but is unavoidable if the object's __dict__ is not always empty.
|
||||
This example is similar to pickle2.cpp. However, the object's `__dict__` is included in the result of `__getstate__`. This requires a little more code but is unavoidable if the object's `__dict__` is not always empty.
|
||||
[endsect]
|
||||
[endsect]
|
||||
[section Pitfall and Safety Guard]
|
||||
The pickle protocol described above has an important pitfall that the end user of a Boost.Python extension module might not be aware of:
|
||||
|
||||
[*__getstate__ is defined and the instance's __dict__ is not empty.]
|
||||
[*`__getstate__` is defined and the instance's `__dict__` is not empty.]
|
||||
|
||||
The author of a Boost.Python extension class might provide a __getstate__ method without considering the possibilities that:
|
||||
* his class is used in Python as a base class. Most likely the __dict__ of instances of the derived class needs to be pickled in order to restore the instances correctly.
|
||||
* the user adds items to the instance's __dict__ directly. Again, the __dict__ of the instance then needs to be pickled.
|
||||
The author of a `Boost.Python` extension class might provide a `__getstate__` method without considering the possibilities that:
|
||||
* his class is used in Python as a base class. Most likely the `__dict__` of instances of the derived class needs to be pickled in order to restore the instances correctly.
|
||||
* the user adds items to the instance's `__dict__` directly. Again, the `__dict__` of the instance then needs to be pickled.
|
||||
|
||||
To alert the user to this highly unobvious problem, a safety guard is provided. If __getstate__ is defined and the instance's __dict__ is not empty, Boost.Python tests if the class has an attribute __getstate_manages_dict__. An exception is raised if this attribute is not defined:
|
||||
To alert the user to this highly unobvious problem, a safety guard is provided. If `__getstate__` is defined and the instance's `__dict__` is not empty, `Boost.Python` tests if the class has an attribute `__getstate_manages_dict__`. An exception is raised if this attribute is not defined:
|
||||
|
||||
``
|
||||
RuntimeError: Incomplete pickle support (__getstate_manages_dict__ not set)
|
||||
``
|
||||
|
||||
To resolve this problem, it should first be established that the __getstate__ and __setstate__ methods manage the instances's __dict__ correctly. Note that this can be done either at the C++ or the Python level. Finally, the safety guard should intentionally be overridden. E.g. in C++ (from pickle3.cpp):
|
||||
To resolve this problem, it should first be established that the `__getstate__` and `__setstate__` methods manage the instances's `__dict__` correctly. Note that this can be done either at the C++ or the Python level. Finally, the safety guard should intentionally be overridden. E.g. in C++ (from pickle3.cpp):
|
||||
|
||||
``
|
||||
struct world_pickle_suite : boost::python::pickle_suite
|
||||
{
|
||||
// ...
|
||||
{
|
||||
// ...
|
||||
|
||||
static bool getstate_manages_dict() { return true; }
|
||||
};
|
||||
static bool getstate_manages_dict() { return true; }
|
||||
};
|
||||
``
|
||||
|
||||
Alternatively in Python:
|
||||
@@ -127,9 +127,9 @@ class your_class(your_bpl_module.your_class):
|
||||
[endsect]
|
||||
[section Practical Advice]
|
||||
|
||||
* In Boost.Python extension modules with many extension classes, providing complete pickle support for all classes would be a significant overhead. In general complete pickle support should only be implemented for extension classes that will eventually be pickled.
|
||||
* Avoid using __getstate__ if the instance can also be reconstructed by way of __getinitargs__. This automatically avoids the pitfall described above.
|
||||
* If __getstate__ is required, include the instance's __dict__ in the Python object that is returned.
|
||||
* In `Boost.Python` extension modules with many extension classes, providing complete pickle support for all classes would be a significant overhead. In general complete pickle support should only be implemented for extension classes that will eventually be pickled.
|
||||
* Avoid using `__getstate__` if the instance can also be reconstructed by way of `__getinitargs__`. This automatically avoids the pitfall described above.
|
||||
* If `__getstate__` is required, include the instance's `__dict__` in the Python object that is returned.
|
||||
|
||||
[endsect]
|
||||
[section Light-weight alternative: pickle support implemented in Python]
|
||||
@@ -141,7 +141,7 @@ The pickle4.cpp example demonstrates an alternative technique for implementing p
|
||||
.enable_pickling()
|
||||
// ...
|
||||
``
|
||||
This enables the standard Python pickle interface as described in the Python documentation. By "injecting" a __getinitargs__ method into the definition of the wrapped class we make all instances pickleable:
|
||||
This enables the standard Python pickle interface as described in the Python documentation. By "injecting" a `__getinitargs__` method into the definition of the wrapped class we make all instances pickleable:
|
||||
|
||||
``
|
||||
# import the wrapped world class
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
[section pointee.hpp]
|
||||
[section boost/python/pointee.hpp]
|
||||
[section Introduction]
|
||||
<boost/python/pointee.hpp> introduces a traits metafunction template pointee<T> that can be used to extract the "pointed-to" type from the type of a pointer or smart pointer.
|
||||
<boost/python/pointee.hpp> introduces a traits metafunction `template pointee<T>` that can be used to extract the "pointed-to" type from the type of a pointer or smart pointer.
|
||||
[endsect]
|
||||
[section Class template `pointee`]
|
||||
pointee<T> is used by the class_<...> template to deduce the type being held when a pointer or smart pointer type is used as its HeldType argument.
|
||||
`pointee<T>` is used by the [link high_level_components.boost_python_class_hpp.class_template_class_t_bases_hel `class_<...>`] template to deduce the type being held when a pointer or smart pointer type is used as its HeldType argument.
|
||||
``
|
||||
namespace boost { namespace python
|
||||
{
|
||||
@@ -21,7 +21,7 @@ namespace boost { namespace python
|
||||
``
|
||||
[endsect]
|
||||
[section Examples]
|
||||
Given a 3rd-party smart pointer type smart_pointer<T>, one might partially specialize pointee<smart_pointer<T> > so that it can be used as the HeldType for a class wrapper:
|
||||
Given a 3rd-party smart pointer type `smart_pointer<T>`, one might partially specialize `pointee<smart_pointer<T> >` so that it can be used as the HeldType for a class wrapper:
|
||||
``
|
||||
#include <boost/python/pointee.hpp>
|
||||
#include <boost/python/class.hpp>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
[section ptr.hpp]
|
||||
[section boost/python/ptr.hpp]
|
||||
[section Introduction]
|
||||
<boost/python/ptr.hpp> defines the ptr() function template, which allows users to specify how to convert C++ pointer values to python in the context of implementing overridable virtual functions, invoking Python callable objects, or explicitly converting C++ objects to Python. Normally, when passing pointers to Python callbacks, the pointee is copied to ensure that the Python object never holds a dangling reference. To specify that the new Python object should merely contain a copy of a pointer p, the user can pass ptr(p) instead of passing p directly. This interface is meant to mirror the use of boost::ref(), which can be similarly used to prevent copying of referents.
|
||||
|
||||
ptr(p) returns an instance of pointer_wrapper<>, which can be detected using the is_pointer_wrapper<> metafunction; unwrap_pointer<> is a metafunction which extracts the original pointer type from a pointer_wrapper<>. These classes can be thought of as implementation details.
|
||||
ptr(p) returns an instance of [link function_invocation_and_creation.boost_python_ptr_hpp.class_template_pointer_wrapper `pointer_wrapper<>`], which can be detected using the [link function_invocation_and_creation.boost_python_ptr_hpp.metafunctions.class_template_is_pointer_wrappe `is_pointer_wrapper<>`] metafunction; [link function_invocation_and_creation.boost_python_ptr_hpp.metafunctions.class_template_unwrap_pointer `unwrap_pointer<>`] is a metafunction which extracts the original pointer type from a `pointer_wrapper<>`. These classes can be thought of as implementation details.
|
||||
[endsect]
|
||||
[section Functions]
|
||||
``
|
||||
@@ -16,7 +16,7 @@ pointer_wrapper<T> ptr(T x);
|
||||
]
|
||||
[endsect]
|
||||
[section Class template `pointer_wrapper`]
|
||||
A "type envelope" which is returned by ptr(), used to indicate reference semantics for pointers passed to Python callbacks.
|
||||
A "type envelope" which is returned by `ptr()`, used to indicate reference semantics for pointers passed to Python callbacks.
|
||||
``
|
||||
namespace boost { namespace python
|
||||
{
|
||||
@@ -43,8 +43,8 @@ The type of the pointer being wrapped.
|
||||
explicit pointer_wrapper(Ptr x);
|
||||
``
|
||||
[variablelist
|
||||
[[Requires][Ptr is a pointer type]]
|
||||
[[Effects][Stores x in a the pointer_wrapper<>. ]]
|
||||
[[Requires][`Ptr` is a pointer type]]
|
||||
[[Effects][Stores `x` in a the `pointer_wrapper<>`. ]]
|
||||
[[Throws][nothing.]]
|
||||
]
|
||||
[endsect]
|
||||
@@ -71,7 +71,7 @@ namespace boost { namespace python
|
||||
}}
|
||||
``
|
||||
[variablelist
|
||||
[[Returns][true iff T is a specialization of pointer_wrapper<>.
|
||||
[[Returns][`true` iff `T` is a specialization of `pointer_wrapper<>`.
|
||||
value is an integral constant convertible to bool of unspecified type ]]
|
||||
]
|
||||
[endsect]
|
||||
@@ -87,7 +87,7 @@ namespace boost { namespace python
|
||||
}}
|
||||
``
|
||||
[variablelist
|
||||
[[Returns][T::type if T is a specialization of pointer_wrapper<>, T otherwise ]]
|
||||
[[Returns][`T::type` if `T` is a specialization of `pointer_wrapper<>`, `T` otherwise ]]
|
||||
]
|
||||
[endsect]
|
||||
[endsect]
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
[section pytype_function.hpp]
|
||||
[section boost/python/pytype_function.hpp]
|
||||
[section Introduction]
|
||||
To support Pythonic signatures the converters should supply a get_pytype function returning a pointer to the associated PyTypeObject. See for example ResultConverter or to_python_converter. The classes in this header file are meant to be used when implmenting get_pytype. There are also _direct versions of the templates of class T which should be used with undecorated type parameter, expected to be in the conversion registry when the module loads.
|
||||
To support Pythonic signatures the converters should supply a `get_pytype` function returning a pointer to the associated `PyTypeObject`. See for example [link concepts.resultconverter `ResultConverter`] or [link to_from_python_type_conversion.boost_python_to_python_converter.class_template_to_python_convert.class_template_to_python_convert `to_python_converter`]. The classes in this header file are meant to be used when implmenting `get_pytype`. There are also `_direct` versions of the templates of `class T` which should be used with undecorated type parameter, expected to be in the conversion registry when the module loads.
|
||||
[endsect]
|
||||
[section Class `wrap_pytype`]
|
||||
This template generates a static get_pytype member returning the template parameter.
|
||||
This template generates a static `get_pytype` member returning the template parameter.
|
||||
``
|
||||
namespace boost { namespace python { namespace converter{
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace boost { namespace python { namespace converter{
|
||||
``
|
||||
[endsect]
|
||||
[section Class `registered_pytype`]
|
||||
This template should be used with template parameters which are (possibly decorated) types exported to python using class_. The generated a static get_pytype member returns the corresponding python type.
|
||||
This template should be used with template parameters which are (possibly decorated) types exported to python using [link high_level_components.boost_python_class_hpp.class_template_class_t_bases_hel `class_`]. The generated a static `get_pytype` member returns the corresponding python type.
|
||||
``
|
||||
namespace boost { namespace python { namespace converter{
|
||||
|
||||
@@ -33,7 +33,7 @@ namespace boost { namespace python { namespace converter{
|
||||
``
|
||||
[endsect]
|
||||
[section Class `expected_from_python_type`]
|
||||
This template generates a static get_pytype member which inspects the registered from_python converters for the type T and returns a matching python type.
|
||||
This template generates a static `get_pytype` member which inspects the registered `from_python` converters for the type `T` and returns a matching python type.
|
||||
``
|
||||
namespace boost { namespace python { namespace converter{
|
||||
|
||||
@@ -48,7 +48,7 @@ namespace boost { namespace python { namespace converter{
|
||||
``
|
||||
[endsect]
|
||||
[section Class `to_python_target_type`]
|
||||
This template generates a static get_pytype member returning the python type to which T can be converted.
|
||||
This template generates a static `get_pytype` member returning the python type to which `T` can be converted.
|
||||
``
|
||||
namespace boost { namespace python { namespace converter{
|
||||
|
||||
@@ -63,7 +63,7 @@ namespace boost { namespace python { namespace converter{
|
||||
``
|
||||
[endsect]
|
||||
[section Example]
|
||||
This example presumes that someone has implemented the standard noddy example module from the Python documentation, and placed the corresponding declarations in "noddy.h". Because noddy_NoddyObject is the ultimate trivial extension type, the example is a bit contrived: it wraps a function for which all information is contained in the type of its return value.
|
||||
This example presumes that someone has implemented the standard noddy example module from the Python documentation, and placed the corresponding declarations in "noddy.h". Because `noddy_NoddyObject` is the ultimate trivial extension type, the example is a bit contrived: it wraps a function for which all information is contained in the type of its return value.
|
||||
|
||||
C++ module definition:
|
||||
``
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[section raw_function.hpp]
|
||||
[section boost/python/raw_function.hpp]
|
||||
[section Introduction]
|
||||
raw_function(...) is used to convert a function taking a tuple and a dict into a Python callable object which accepts a variable number of arguments and arbitrary keyword arguments.
|
||||
`raw_function(...)` is used to convert a function taking a [link object_wrappers.boost_python_tuple_hpp.class_tuple `tuple`] and a [link object_wrappers.boost_python_dict_hpp.class_dict `dict`] into a Python callable object which accepts a variable number of arguments and arbitrary keyword arguments.
|
||||
[endsect]
|
||||
[section Function `raw_function`]
|
||||
``
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[section reference_existing_object.hpp]
|
||||
[section boost/python/reference_existing_object.hpp]
|
||||
[section Class `reference_existing_object`]
|
||||
reference_existing_object is a model of ResultConverterGenerator which can be used to wrap C++ functions which return a reference or pointer to a C++ object. When the wrapped function is called, the value referenced by its return value is not copied. A new Python object is created which contains a pointer to the referent, and no attempt is made to ensure that the lifetime of the referent is at least as long as that of the corresponding Python object. Thus, it can be highly dangerous to use reference_existing_object without additional lifetime management from such models of CallPolicies as with_custodian_and_ward. This class is used in the implementation of return_internal_reference.
|
||||
`reference_existing_object` is a model of [link concepts.resultconverter.resultconvertergenerator_concept ResultConverterGenerator] which can be used to wrap C++ functions which return a reference or pointer to a C++ object. When the wrapped function is called, the value referenced by its return value is not copied. A new Python object is created which contains a pointer to the referent, and no attempt is made to ensure that the lifetime of the referent is at least as long as that of the corresponding Python object. Thus, it can be *highly dangerous* to use `reference_existing_object` without additional lifetime management from such models of [link concepts.callpolicies CallPolicies] as [link function_invocation_and_creation.models_of_callpolicies.boost_python_with_custodian_and_.class_with_custodian_and_ward `with_custodian_and_ward`]. This class is used in the implementation of [link function_invocation_and_creation.models_of_callpolicies.boost_python_return_internal_ref.class_template_return_internal_r `return_internal_reference`].
|
||||
``
|
||||
namespace boost { namespace python
|
||||
{
|
||||
@@ -15,7 +15,7 @@ namespace boost { namespace python
|
||||
``template <class T> struct apply``
|
||||
[variablelist
|
||||
[[Requires][`T` is `U&` or `U*` for some `U`.]]
|
||||
[[Returns][`typedef to_python_indirect<T, V> type;`, where V is a class whose static execute function constructs an instance holder containing an unowned U* pointing to the referent of the wrapped function's return value.]]
|
||||
[[Returns][`typedef to_python_indirect<T, V> type;`, where V is a class whose static execute function constructs an instance holder containing an unowned `U*` pointing to the referent of the wrapped function's return value.]]
|
||||
]
|
||||
[endsect]
|
||||
[section Example]
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
[section register_ptr_to_python.hpp]
|
||||
[section boost/python/register_ptr_to_python.hpp]
|
||||
[section Introduction]
|
||||
<boost/python/register_ptr_to_python.hpp> supplies register_ptr_to_python, a function template which registers a conversion for smart pointers to Python. The resulting Python object holds a copy of the converted smart pointer, but behaves as though it were a wrapped copy of the pointee. If the pointee type has virtual functions and the class representing its dynamic (most-derived) type has been wrapped, the Python object will be an instance of the wrapper for the most-derived type. More than one smart pointer type for a pointee's class can be registered.
|
||||
<boost/python/register_ptr_to_python.hpp> supplies `register_ptr_to_python`, a function template which registers a conversion for smart pointers to Python. The resulting Python object holds a copy of the converted smart pointer, but behaves as though it were a wrapped copy of the pointee. If the pointee type has virtual functions and the class representing its dynamic (most-derived) type has been wrapped, the Python object will be an instance of the wrapper for the most-derived type. More than one smart pointer type for a pointee's class can be registered.
|
||||
|
||||
Note that in order to convert a Python X object to a smart_ptr<X>& (non-const reference), the embedded C++ object must be held by smart_ptr<X>, and that when wrapped objects are created by calling the constructor from Python, how they are held is determined by the HeldType parameter to class_<...> instances.
|
||||
Note that in order to convert a Python `X` object to a `smart_ptr<X>&` (non-const reference), the embedded C++ object must be held by `smart_ptr<X>`, and that when wrapped objects are created by calling the constructor from Python, how they are held is determined by the HeldType parameter to `class_<...>` instances.
|
||||
[endsect]
|
||||
[section Function `register_ptr_to_python`]
|
||||
``
|
||||
@@ -10,13 +10,12 @@ template <class P>
|
||||
void register_ptr_to_python()
|
||||
``
|
||||
[variablelist
|
||||
[[Requires][`P` is Dereferenceable.]]
|
||||
[[Requires][`P` is [link concepts.dereferenceable Dereferenceable].]]
|
||||
[[Effects][Allows conversions to-python of P instances. ]]
|
||||
]
|
||||
[endsect]
|
||||
[endsect]
|
||||
[section Example]
|
||||
Here is an example of a module that contains a class A with virtual functions and some functions that work with boost::shared_ptr<A>.
|
||||
Here is an example of a module that contains a class A with virtual functions and some functions that work with boost::shared_ptr<A>.
|
||||
|
||||
In C++:
|
||||
``
|
||||
@@ -85,4 +84,3 @@ TypeError: No to_python (by-value) converter found for C++ type: class boost::sh
|
||||
>>>
|
||||
``
|
||||
[endsect]
|
||||
[endsect]
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
[section return_arg.hpp]
|
||||
[section boost/python/return_arg.hpp]
|
||||
[section Introduction]
|
||||
return_arg and return_self instantiations are models of CallPolicies which return the specified argument parameter (usually *this) of a wrapped (member) function.
|
||||
`return_arg` and `return_self` instantiations are models of [link concepts.callpolicies `CallPolicies`] which return the specified argument parameter (usually `*this`) of a wrapped (member) function.
|
||||
[endsect]
|
||||
[section Class `return_arg`]
|
||||
[table
|
||||
[[Parameter][Requirements][Description][Default]]
|
||||
[[arg_pos][A positive compile-time constant of type std::size_t.][the position of the argument to be returned.][1]]
|
||||
[[Base][A model of CallPolicies][Used for policy composition. Any result_converter it supplies will be overridden by return_arg, but its precall and postcall policies are composed as described here CallPolicies.][default_call_policies]]
|
||||
[[arg_pos][A positive compile-time constant of type `std::size_t`.][the position of the argument to be returned.][1]]
|
||||
[[Base][A model of [link concepts.callpolicies `CallPolicies`]][Used for policy composition. Any `result_converter` it supplies will be overridden by `return_arg`, but its `precall` and `postcall` policies are composed as described here [link concepts.callpolicies `CallPolicies`].][default_call_policies]]
|
||||
]
|
||||
``
|
||||
namespace boost { namespace python
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[section return_by_value.hpp]
|
||||
[section boost/python/return_by_value.hpp]
|
||||
[section Class `return_by_value`]
|
||||
return_by_value is a model of ResultConverterGenerator which can be used to wrap C++ functions returning any reference or value type such that the return value is copied into a new Python object.
|
||||
`return_by_value` is a model of [link concepts.resultconverter.resultconvertergenerator_concept ResultConverterGenerator] which can be used to wrap C++ functions returning any reference or value type such that the return value is copied into a new Python object.
|
||||
``
|
||||
namespace boost { namespace python
|
||||
{
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
[section return_internal_reference.hpp]
|
||||
[section boost/python/return_internal_reference.hpp]
|
||||
[section Introduction]
|
||||
return_internal_reference instantiations are models of CallPolicies which allow pointers and references to objects held internally by a free or member function argument or from the target of a member function to be returned safely without making a copy of the referent. The default for its first template argument handles the common case where the containing object is the target (*this) of a wrapped member function.
|
||||
`return_internal_reference` instantiations are models of [link concepts.callpolicies `CallPolicies`] which allow pointers and references to objects held internally by a free or member function argument or from the target of a member function to be returned safely without making a copy of the referent. The default for its first template argument handles the common case where the containing object is the target (`*this`) of a wrapped member function.
|
||||
[endsect]
|
||||
[section Class template `return_internal_reference`]
|
||||
[table
|
||||
[[Parameter][Requirements][Description][Default]]
|
||||
[[owner_arg][A positive compile-time constant of type std::size_t.][The index of the parameter which contains the object to which the reference or pointer is being returned. If used to wrap a member function, parameter 1 is the target object (*this). Note that if the target Python object type doesn't support weak references, a Python TypeError exception will be raised when the function being wrapped is called.][]]
|
||||
[[Base][A model of CallPolicies][Used for policy composition. Any result_converter it supplies will be overridden by return_internal_reference, but its precall and postcall policies are composed as described here CallPolicies.][default_call_policies]]
|
||||
[[owner_arg][A positive compile-time constant of type `std::size_t`.][The index of the parameter which contains the object to which the reference or pointer is being returned. If used to wrap a member function, parameter 1 is the target object (`*this`). Note that if the target Python object type doesn't support weak references, a Python TypeError exception will be raised when the function being wrapped is called.][]]
|
||||
[[Base][A model of [link concepts.callpolicies `CallPolicies`]][Used for policy composition. Any `result_converter` it supplies will be overridden by `return_internal_reference`, but its `precall` and `postcall` policies are composed as described here [link concepts.callpolicies `CallPolicies`].][default_call_policies]]
|
||||
]
|
||||
``
|
||||
namespace boost { namespace python
|
||||
@@ -24,7 +24,7 @@ namespace boost { namespace python
|
||||
``PyObject* postcall(PyObject* args, PyObject* result);``
|
||||
[variablelist
|
||||
[[Requires][`PyTuple_Check(args) != 0`]]
|
||||
[[Returns][ `with_custodian_and_ward_postcall::postcall(args, result)`]]
|
||||
[[Returns][[link function_invocation_and_creation.models_of_callpolicies.boost_python_with_custodian_and_.class_with_custodian_and_ward_st `with_custodian_and_ward_postcall::postcall(args, result)`]]]
|
||||
]
|
||||
[endsect]
|
||||
[section Example]
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
[section return_opaque_pointer.hpp]
|
||||
[section boost/python/return_opaque_pointer.hpp]
|
||||
[section Class `return_opaqe_pointer`]
|
||||
return_opaque_pointer is a model of ResultConverterGenerator which can be used to wrap C++ functions returning pointers to undefined types such that the return value is copied into a new Python object.
|
||||
return_opaque_pointer is a model of [link concepts.resultconverter.resultconvertergenerator_concept ResultConverterGenerator] which can be used to wrap C++ functions returning pointers to undefined types such that the return value is copied into a new Python object.
|
||||
|
||||
In addition to specifying the return_opaque_pointer policy the BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID macro must be used to define specializations for the type_id function on the type pointed to by returned pointer.
|
||||
In addition to specifying the `return_opaque_pointer` policy the [link to_from_python_type_conversion.boost_python_opaque_pointer_conv.macro_boost_python_opaque_specia `BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID`] macro must be used to define specializations for the [link utility_and_infrastructure.boost_python_type_id_hpp.functions `type_id`] function on the type pointed to by returned pointer.
|
||||
``
|
||||
namespace boost { namespace python
|
||||
{
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
[section return_value_policy.hpp]
|
||||
[section boost/python/return_value_policy.hpp]
|
||||
[section Introduction]
|
||||
return_value_policy instantiations are simply models of CallPolicies which are composed of a ResultConverterGenerator and optional Base CallPolicies.
|
||||
return_value_policy instantiations are simply models of [link concepts.callpolicies `CallPolicies`] which are composed of a [link concepts.resultconverter.resultconvertergenerator_concept `ResultConverterGenerator`] and optional `Base` [link concepts.callpolicies `CallPolicies`].
|
||||
[endsect]
|
||||
[section Class template `return_value_policy`]
|
||||
[table
|
||||
[[Parameter][Requirements][Default]]
|
||||
[[ResultConverterGenerator][A model of ResultConverterGenerator][]]
|
||||
[[Base][A model of CallPolicies][default_call_policies]]
|
||||
[[ResultConverterGenerator][A model of [link concepts.resultconverter.resultconvertergenerator_concept `ResultConverterGenerator`]][]]
|
||||
[[Base][A model of [link concepts.callpolicies `CallPolicies`]][default_call_policies]]
|
||||
]
|
||||
``
|
||||
namespace boost { namespace python
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[section scope.hpp]
|
||||
[section boost/python/scope.hpp]
|
||||
[section Introduction]
|
||||
Defines facilities for querying and controlling the Python scope (namespace) which will contain new wrapped classes and functions.
|
||||
[endsect]
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
[section slice.hpp]
|
||||
[section boost/python/slice.hpp]
|
||||
[section Introduction]
|
||||
Exposes a TypeWrapper for the Python slice type.
|
||||
Exposes a [link concepts.objectwrapper.typewrapper_concept_requirements TypeWrapper] for the Python [@http://www.python.org/doc/2.3.3/api/slice-objects.html `slice`] type.
|
||||
[endsect]
|
||||
[section Class `slice`]
|
||||
Exposes the extended slicing protocol by wrapping the built-in slice type. The semantics of the constructors and member functions defined below can be fully understood by reading the TypeWrapper concept definition. Since slice is publicly derived from object, the public object interface applies to slice instances as well.
|
||||
Exposes the extended slicing protocol by wrapping the built-in slice type. The semantics of the constructors and member functions defined below can be fully understood by reading the [link concepts.objectwrapper.typewrapper_concept_requirements TypeWrapper] concept definition. Since `slice` is publicly derived from [link object_wrappers.boost_python_object_hpp.class_object `object`], the public `object` interface applies to `slice` instances as well.
|
||||
``
|
||||
namespace boost { namespace python
|
||||
{
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
[section ssize_t.hpp]
|
||||
[section boost/python/ssize_t.hpp]
|
||||
[section Introduction]
|
||||
Python 2.5 introduces a new Py_ssize_t typedef and two related macros (PEP 353). The <boost/python/ssize_t.hpp> header imports these definitions into the boost::python namespace as ssize_t, ssize_t_max, and ssize_t_min. Appropriate definitions are provided for backward compatibility with previous Python versions.
|
||||
Python 2.5 introduces a new `Py_ssize_t` typedef and two related macros ([@http://www.python.org/dev/peps/pep-0353/ PEP 353]). The <boost/python/ssize_t.hpp> header imports these definitions into the `boost::python` namespace as `ssize_t`, `ssize_t_max`, and `ssize_t_min`. Appropriate definitions are provided for backward compatibility with previous Python versions.
|
||||
[endsect]
|
||||
[section Typedefs]
|
||||
Imports Py_ssize_t into the boost::python namespace if available, or provides an appropriate typedef for backward compatibility:
|
||||
Imports `Py_ssize_t` into the `boost::python` namespace if available, or provides an appropriate typedef for backward compatibility:
|
||||
``
|
||||
#if PY_VERSION_HEX >= 0x02050000
|
||||
typedef Py_ssize_t ssize_t;
|
||||
@@ -13,7 +13,7 @@ typedef int ssize_t;
|
||||
``
|
||||
[endsect]
|
||||
[section Constants]
|
||||
Imports PY_SSIZE_T_MAX and PY_SSIZE_T_MIN as constants into the boost::python namespace if available, or provides appropriate constants for backward compatibility:
|
||||
Imports `PY_SSIZE_T_MAX` and `PY_SSIZE_T_MIN` as constants into the `boost::python` namespace if available, or provides appropriate constants for backward compatibility:
|
||||
``
|
||||
#if PY_VERSION_HEX >= 0x02050000
|
||||
ssize_t const ssize_t_max = PY_SSIZE_T_MAX;
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
[section stl_iterator.hpp]
|
||||
[section boost/python/stl_iterator.hpp]
|
||||
[section Introduction]
|
||||
<boost/python/stl_iterator.hpp> provides types for creating C++ Iterators from Python iterables.
|
||||
<boost/python/stl_iterator.hpp> provides types for creating C++ Iterators from [@http://www.python.org/doc/current/lib/typeiter.html Python iterables].
|
||||
[endsect]
|
||||
[section Class template `stl_input_iterator`]
|
||||
Instances of stl_input_iterator<T> hold a Python iterator and adapt it for use with STL algorithms. stl_input_iterator<T> satisfies the requirements for an Input Iterator.
|
||||
Instances of `stl_input_iterator<T>` hold a Python iterator and adapt it for use with STL algorithms. `stl_input_iterator<T>` satisfies the requirements for an Input Iterator.
|
||||
[table
|
||||
[[Template Parameter][Requirements][Semantics][Default]]
|
||||
[[ValueType][ValueType must be CopyConstructible.][Dereferencing an instance of stl_input_iterator<ValueType> will return an rvalue of type ValueType.][None]]
|
||||
[[ValueType][ValueType must be CopyConstructible.][Dereferencing an instance of `stl_input_iterator<ValueType>` will return an rvalue of type ValueType.][None]]
|
||||
]
|
||||
``
|
||||
namespace boost { namespace python
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
[section str.hpp]
|
||||
[section boost/python/str.hpp]
|
||||
[section Introduction]
|
||||
Exposes a TypeWrapper for the Python str type.
|
||||
Exposes a [link concepts.objectwrapper.typewrapper_concept_requirements TypeWrapper] for the Python [@http://www.python.org/dev/doc/devel/lib/string-methods.html `str`] type.
|
||||
[endsect]
|
||||
[section Class `str`]
|
||||
Exposes the string methods of Python's built-in str type. The semantics of the constructors and member functions defined below, except for the two-argument constructors which construct str objects from a range of characters, can be fully understood by reading the TypeWrapper concept definition. Since str is publicly derived from object, the public object interface applies to str instances as well.
|
||||
Exposes the [@http://www.python.org/dev/doc/devel/lib/string-methods.html string methods] of Python's built-in `str` type. The semantics of the constructors and member functions defined below, except for the two-argument constructors which construct str objects from a range of characters, can be fully understood by reading the [link concepts.objectwrapper.typewrapper_concept_requirements TypeWrapper] concept definition. Since str is publicly derived from [link object_wrappers.boost_python_object_hpp.class_object `object`], the public `object` interface applies to `str` instances as well.
|
||||
``
|
||||
namespace boost { namespace python
|
||||
{
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
[section to_python_converter.hpp]
|
||||
[section boost/python/to_python_converter.hpp]
|
||||
[section Introduction]
|
||||
to_python_converter registers a conversion from objects of a given C++ type into a Python object.
|
||||
`to_python_converter` registers a conversion from objects of a given C++ type into a Python object.
|
||||
[endsect]
|
||||
[section Class template `to_python_converter`]
|
||||
to_python_converter adds a wrapper around a static member function of its second template parameter, handling low-level details such as insertion into the converter registry.
|
||||
`to_python_converter` adds a wrapper around a static member function of its second template parameter, handling low-level details such as insertion into the converter registry.
|
||||
|
||||
In the table below, x denotes an object of type T
|
||||
[table
|
||||
In the table below, x denotes an object of type T
|
||||
[table
|
||||
[[Parameter][Requirements][Description]]
|
||||
[[T][][The C++ type of the source object in the conversion]]
|
||||
[[Conversion][PyObject* p = Conversion::convert(x),
|
||||
if p == 0, PyErr_Occurred() != 0.][A class type whose static member function convert does the real work of the conversion.]]
|
||||
[[bool has_get_pytype=false][]
|
||||
[Optional member - if Conversion has get_pytype member supply true for this parameters. If present get_pytype is used to document the return type of functions using this conversion. The get_pytype may be implemented using the classes and functions from pytype_function.hpp NOTE : For backward compatibility this parameter may be passed after checking if BOOST_PYTHON_SUPPORTS_PY_SIGNATURES is defined (see here).]
|
||||
]
|
||||
[[Conversion][`PyObject* p = Conversion::convert(x)`,
|
||||
`if p == 0`, `PyErr_Occurred() != 0`.][A class type whose static member function convert does the real work of the conversion.]]
|
||||
[[bool has_get_pytype=false][`PyTypeObject const * p = Conversion::get_pytype()`]
|
||||
[Optional member - if Conversion has `get_pytype` member supply `true` for this parameters. If present `get_pytype` is used to document the return type of functions using this conversion. The `get_pytype` may be implemented using the classes and functions from pytype_function.hpp NOTE : For backward compatibility this parameter may be passed after checking if BOOST_PYTHON_SUPPORTS_PY_SIGNATURES is defined (see [link function_invocation_and_creation.function_documentation.boost_python_pytype_function_hpp.example here]).]
|
||||
]]
|
||||
|
||||
``
|
||||
namespace boost { namespace python
|
||||
@@ -27,12 +28,12 @@ namespace boost { namespace python
|
||||
[section Class template `to_python_converter` constructor]
|
||||
``to_python_converter();``
|
||||
[variablelist
|
||||
[[Effects][Registers a to_python converter which uses Conversion::convert() to do its work.]]
|
||||
[[Effects][Registers a `to_python` converter which uses `Conversion::convert()` to do its work.]]
|
||||
]
|
||||
[endsect]
|
||||
[endsect]
|
||||
[section Example]
|
||||
This example presumes that someone has implemented the standard noddy example module from the Python documentation, and placed the corresponding declarations in "noddy.h". Because noddy_NoddyObject is the ultimate trivial extension type, the example is a bit contrived: it wraps a function for which all information is contained in the type of its return value.
|
||||
This example presumes that someone has implemented the standard noddy example module from the Python documentation, and placed the corresponding declarations in "noddy.h". Because noddy_NoddyObject is the ultimate trivial extension type, the example is a bit contrived: it wraps a function for which all information is contained in the type of its return value.
|
||||
|
||||
In C++:
|
||||
``
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
[section to_python_indirect.hpp]
|
||||
[section boost/python/to_python_indirect.hpp]
|
||||
[section Introduction]
|
||||
<boost/python/to_python_indirect.hpp> supplies a way to construct new Python objects that hold wrapped C++ class instances via a pointer or smart pointer.
|
||||
[endsect]
|
||||
[section Class `to_python_indirect`]
|
||||
Class template to_python_indirect converts objects of its first argument type to python as extension class instances, using the ownership policy provided by its 2nd argument.
|
||||
Class template `to_python_indirect` converts objects of its first argument type to python as extension class instances, using the ownership policy provided by its 2nd argument.
|
||||
[table
|
||||
[[Parameter][Requirements][Description]]
|
||||
[[T][Either U cv& (where cv is any optional cv-qualification) or a Dereferenceable type such that *x is convertible to U const&, where U is a class type. ][A type deferencing a C++ class exposed to Python using class template class_. ]]
|
||||
[[MakeHolder][h = MakeHolder::execute(p); ][A class whose static execute() creates an instance_holder. ]]
|
||||
[[T][Either `U cv&` (where cv is any optional cv-qualification) or a [link concepts.dereferenceable Dereferenceable] type such that `*x` is convertible to `U const&`, where `U` is a class type. ][`A` type deferencing a C++ class exposed to Python using class template [link high_level_components.boost_python_class_hpp.class_template_class_t_bases_hel `class_`]. ]]
|
||||
[[MakeHolder][`h = MakeHolder::execute(p);` ][A class whose static `execute()` creates an `instance_holder`. ]]
|
||||
]
|
||||
Instantiations of to_python_indirect are models of ResultConverter.
|
||||
Instantiations of to_python_indirect are models of [link concepts.resultconverter `ResultConverter`].
|
||||
``
|
||||
namespace boost { namespace python
|
||||
{
|
||||
@@ -39,7 +39,7 @@ namespace boost { namespace python
|
||||
[endsect]
|
||||
[endsect]
|
||||
[section Example]
|
||||
This example replicates the functionality of reference_existing_object, but without some of the compile-time error checking.
|
||||
This example replicates the functionality of [link function_invocation_and_creation.models_of_resultconvertergenerat.boost_python_reference_existing_.class_reference_existing_object `reference_existing_object`], but without some of the compile-time error checking.
|
||||
``
|
||||
struct make_reference_holder
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[section to_python_value.hpp]
|
||||
[section boost/python/to_python_value.hpp]
|
||||
[section Introduction]
|
||||
to_python_value is a model of ResultConverter which copies its argument into a new Python object.
|
||||
`to_python_value` is a model of [link concepts.resultconverter ResultConverter] which copies its argument into a new Python object.
|
||||
[endsect]
|
||||
[section Class template `to_python_value`]
|
||||
``
|
||||
@@ -22,13 +22,13 @@ namespace boost { namespace python
|
||||
[section Class `to_python_value` observers]
|
||||
``static bool convertible();``
|
||||
[variablelist
|
||||
[[Returns][true iff a converter has been registered which can convert T to python by-value. ]]
|
||||
[[Returns][`true` iff a converter has been registered which can convert `T` to python by-value. ]]
|
||||
]
|
||||
``PyObject* operator()(argument_type x) const;``
|
||||
[variablelist
|
||||
[[Requires][`convertible() == true`]]
|
||||
[[Effects][converts `x` to python]]
|
||||
[[Returns][the resulting Python object iff a converter for T has been registered, 0 otherwise. ]]
|
||||
[[Returns][the resulting Python object iff a converter for `T` has been registered, `0` otherwise. ]]
|
||||
]
|
||||
[endsect]
|
||||
[endsect]
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
[section tuple.hpp]
|
||||
[section boost/python/tuple.hpp]
|
||||
[section Introduction]
|
||||
Exposes a TypeWrapper for the Python tuple type.
|
||||
Exposes a [link concepts.objectwrapper.typewrapper_concept_requirements TypeWrapper] for the Python [@http://www.python.org/doc/current/tut/node7.html#SECTION007300000000000000000`tuple`] type.
|
||||
[endsect]
|
||||
[section Class `tuple`]
|
||||
Exposes the interface of Python's built-in tuple type. The semantics of the constructors and member functions defined below can be fully understood by reading the TypeWrapper concept definition. Since tuple is publicly derived from object, the public object interface applies to tuple instances as well.
|
||||
Exposes the interface of Python's built-in tuple type. The semantics of the constructors and member functions defined below can be fully understood by reading the [link concepts.objectwrapper.typewrapper_concept_requirements TypeWrapper] concept definition. Since tuple is publicly derived from [link object_wrappers.boost_python_object_hpp.class_object `object`], the public `object` interface applies to `tuple` instances as well.
|
||||
``
|
||||
namespace boost { namespace python
|
||||
{
|
||||
|
||||
@@ -1,43 +1,43 @@
|
||||
[section type_id.hpp]
|
||||
[section boost/python/type_id.hpp]
|
||||
[section Introduction]
|
||||
<boost/python/type_id.hpp> provides types and functions for runtime type identification like those of of <typeinfo>. It exists mostly to work around certain compiler bugs and platform-dependent interactions with shared libraries.
|
||||
<boost/python/type_id.hpp> provides types and functions for runtime type identification like those of of `<typeinfo>`. It exists mostly to work around certain compiler bugs and platform-dependent interactions with shared libraries.
|
||||
[endsect]
|
||||
[section Class template `type_info`]
|
||||
type_info instances identify a type. As std::type_info is specified to (but unlike its implementation in some compilers), boost::python::type_info never represents top-level references or cv-qualification (see section 5.2.8 in the C++ standard). Unlike std::type_info, boost::python::type_info instances are copyable, and comparisons always work reliably across shared library boundaries.
|
||||
`type_info` instances identify a type. As `std::type_info` is specified to (but unlike its implementation in some compilers), `boost::python::type_info` never represents top-level references or cv-qualification (see section 5.2.8 in the C++ standard). Unlike `std::type_info`, `boost::python::type_info` instances are copyable, and comparisons always work reliably across shared library boundaries.
|
||||
``
|
||||
namespace boost { namespace python
|
||||
{
|
||||
class type_info : totally_ordered<type_info>
|
||||
{
|
||||
public:
|
||||
// constructor
|
||||
type_info(std::type_info const& = typeid(void));
|
||||
public:
|
||||
// constructor
|
||||
type_info(std::type_info const& = typeid(void));
|
||||
|
||||
// comparisons
|
||||
bool operator<(type_info const& rhs) const;
|
||||
bool operator==(type_info const& rhs) const;
|
||||
// comparisons
|
||||
bool operator<(type_info const& rhs) const;
|
||||
bool operator==(type_info const& rhs) const;
|
||||
|
||||
// observers
|
||||
char const* name() const;
|
||||
// observers
|
||||
char const* name() const;
|
||||
};
|
||||
}}
|
||||
``
|
||||
[section Class template `type_info` constructor]
|
||||
``type_info(std::type_info const& = typeid(void));``
|
||||
[variablelist
|
||||
[[Effects][`constructs a type_info object which identifies the same type as its argument.`]]
|
||||
[[Rationale][Since it is occasionally necessary to make an array of type_info objects a benign default argument is supplied. Note: this constructor does not correct for non-conformance of compiler typeid() implementations. See type_id, below.]]
|
||||
[[Effects][constructs a `type_info` object which identifies the same type as its argument.]]
|
||||
[[Rationale][Since it is occasionally necessary to make an array of `type_info` objects a benign default argument is supplied. Note: this constructor does not correct for non-conformance of compiler `typeid()` implementations. See `type_id`, below.]]
|
||||
]
|
||||
[endsect]
|
||||
[section Class template `type_info` comparison]
|
||||
``bool operator<(type_info const &rhs) const;``
|
||||
[variablelist
|
||||
[[Effects][yields a total order over type_info objects.]]
|
||||
[[Effects][yields a total order over `type_info` objects.]]
|
||||
]
|
||||
``bool operator==(type_info const &rhs) const;``
|
||||
[variablelist
|
||||
[[Returns][true iff the two values describe the same type.]]
|
||||
[[Note][The use of totally_ordered<type_info> as a private base class supplies operators <=, >=, >, and !=]]
|
||||
[[Returns][`true` iff the two values describe the same type.]]
|
||||
[[Note][The use of `totally_ordered<type_info>` as a private base class supplies operators `<=`, `>=`, `>`, and `!=`]]
|
||||
]
|
||||
[endsect]
|
||||
[section Class template `type_info` observers]
|
||||
@@ -45,7 +45,7 @@ namespace boost { namespace python
|
||||
char const* name() const;
|
||||
``
|
||||
[variablelist
|
||||
[[Returns][The result of calling name() on the argument used to construct the object.]]
|
||||
[[Returns][The result of calling `name()` on the argument used to construct the object.]]
|
||||
]
|
||||
[endsect]
|
||||
[endsect]
|
||||
@@ -54,13 +54,20 @@ char const* name() const;
|
||||
std::ostream& operator<<(std::ostream&s, type_info const&x);
|
||||
``
|
||||
[variablelist
|
||||
[[Effects][Writes a description of the type described by to x into s.]]
|
||||
[[Rationale][Not every C++ implementation provides a truly human-readable type_info::name() string, but for some we may be able to decode the string and produce a reasonable representation.]]
|
||||
[[Effects][Writes a description of the type described by to `x` into s.]]
|
||||
[[Rationale][Not every C++ implementation provides a truly human-readable `type_info::name()` string, but for some we may be able to decode the string and produce a reasonable representation.]]
|
||||
[[Note][On some non-conforming C++ implementations, the code is not actually as simple as described above; the semantics are adjusted to work as-if the C++ implementation were conforming.]]
|
||||
]
|
||||
``
|
||||
template <class T> type_info type_id()
|
||||
``
|
||||
[variablelist
|
||||
[[Returns][`type_info(typeid(T))`]]
|
||||
[[Note][On some non-conforming C++ implementations, the code is not actually as simple as described above; the semantics are adjusted to work as-if the C++ implementation were conforming.]]
|
||||
]
|
||||
[endsect]
|
||||
[section Example]
|
||||
The following example, though silly, illustrates how the type_id facility might be used
|
||||
The following example, though silly, illustrates how the type_id facility might be used
|
||||
``
|
||||
#include <boost/python/type_id.hpp>
|
||||
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
[section with_custodian_and_ward.hpp]
|
||||
[section boost/python/with_custodian_and_ward.hpp]
|
||||
[section Introduction]
|
||||
This header provides facilities for establishing a lifetime dependency between two of a function's Python argument or result objects. The ward object will not be destroyed until after the custodian as long as the custodian object supports weak references (Boost.Python extension classes all support weak references). If the custodian object does not support weak references and is not None, an appropriate exception will be thrown. The two class templates with_custodian_and_ward and with_custodian_and_ward_postcall differ in the point at which they take effect.
|
||||
This header provides facilities for establishing a lifetime dependency between two of a function's Python argument or result objects. The ward object will not be destroyed until after the custodian as long as the custodian object supports [@http://www.python.org/doc/current/lib/module-weakref.html weak references] (Boost.Python extension classes all support weak references). If the custodian object does not support weak references and is not `None`, an appropriate exception will be thrown. The two class templates `with_custodian_and_ward` and `with_custodian_and_ward_postcall` differ in the point at which they take effect.
|
||||
|
||||
In order to reduce the chance of inadvertently creating dangling pointers, the default is to do lifetime binding before the underlying C++ object is invoked. However, before invocation the result object is not available, so with_custodian_and_ward_postcall is provided to bind lifetimes after invocation. Also, if a C++ exception is thrown after with_custodian_and_ward<>::precall but before the underlying C++ object actually stores a pointer, the lifetime of the custodian and ward objects will be artificially bound together, so one might choose with_custodian_and_ward_postcall instead, depending on the semantics of the function being wrapped.
|
||||
In order to reduce the chance of inadvertently creating dangling pointers, the default is to do lifetime binding before the underlying C++ object is invoked. However, before invocation the result object is not available, so `with_custodian_and_ward_postcall` is provided to bind lifetimes after invocation. Also, if a C++ exception is thrown after `with_custodian_and_ward<>::precall` but before the underlying C++ object actually stores a pointer, the lifetime of the custodian and ward objects will be artificially bound together, so one might choose `with_custodian_and_ward_postcall` instead, depending on the semantics of the function being wrapped.
|
||||
|
||||
Please note that this is not the appropriate tool to use when wrapping functions which transfer ownership of a raw pointer across the function-call boundary. Please see the FAQ if you want to do that.
|
||||
[endsect]
|
||||
[section Class `with_custodian_and_ward`]
|
||||
[table
|
||||
[[Parameter][Requirements][Description][Default]]
|
||||
[[custodian][ A positive compile-time constant of type std::size_t. ][ The 1-based index of the parameter which is the dependency in the lifetime relationship to be established. If used to wrap a member function, parameter 1 is the target object (*this). Note that if the target Python object type doesn't support weak references, a Python TypeError exception will be raised when the C++ object being wrapped is called. ][]]
|
||||
[[ward][ A positive compile-time constant of type std::size_t. ][ The 1-based index of the parameter which is the dependent in the lifetime relationship to be established. If used to wrap a member function, parameter 1 is the target object (*this). ][]]
|
||||
[[Base][ A model of CallPolicies ][ Used for policy composition. ][default_call_policies]]
|
||||
[[custodian][ A positive compile-time constant of `type std::size_t`. ][ The 1-based index of the parameter which is the dependency in the lifetime relationship to be established. If used to wrap a member function, parameter 1 is the target object (`*this`). Note that if the target Python object type doesn't support weak references, a Python TypeError exception will be raised when the C++ object being wrapped is called. ][]]
|
||||
[[ward][ A positive compile-time constant of type `std::size_t`. ][ The 1-based index of the parameter which is the dependent in the lifetime relationship to be established. If used to wrap a member function, parameter 1 is the target object (`*this`). ][]]
|
||||
[[Base][ A model of [link concepts.callpolicies `CallPolicies`]][ Used for policy [link concepts.callpolicies.callpolicies_composition composition]. ][default_call_policies]]
|
||||
]
|
||||
``
|
||||
namespace boost { namespace python
|
||||
@@ -35,9 +35,9 @@ namespace boost { namespace python
|
||||
[section Class `with_custodian_and_ward_postcall`]
|
||||
[table
|
||||
[[Parameter][Requirements][Description][Default]]
|
||||
[[custodian][ A positive compile-time constant of type std::size_t. ][ The index of the parameter which is the dependency in the lifetime relationship to be established. Zero indicates the result object; 1 indicates the first argument. If used to wrap a member function, parameter 1 is the target object (*this). Note that if the target Python object type doesn't support weak references, a Python TypeError exception will be raised when the C++ object being wrapped is called. ][]]
|
||||
[[ward][ A positive compile-time constant of type std::size_t. ][ The index of the parameter which is the dependent in the lifetime relationship to be established. Zero indicates the result object; 1 indicates the first argument. If used to wrap a member function, parameter 1 is the target object (*this). ][]]
|
||||
[[Base][ A model of CallPolicies ][ Used for policy composition. ][default_call_policies]]
|
||||
[[custodian][ A positive compile-time constant of type `std::size_t`. ][ The index of the parameter which is the dependency in the lifetime relationship to be established. Zero indicates the result object; 1 indicates the first argument. If used to wrap a member function, parameter 1 is the target object (`*this`). Note that if the target Python object type doesn't support weak references, a Python TypeError exception will be raised when the C++ object being wrapped is called. ][]]
|
||||
[[ward][ A positive compile-time constant of type `std::size_t`. ][ The index of the parameter which is the dependent in the lifetime relationship to be established. Zero indicates the result object; 1 indicates the first argument. If used to wrap a member function, parameter 1 is the target object (`*this`). ][]]
|
||||
[[Base][ A model of [link concepts.callpolicies `CallPolicies`]][ Used for policy [link concepts.callpolicies.callpolicies_composition composition]. ][default_call_policies]]
|
||||
]
|
||||
``
|
||||
namespace boost { namespace python
|
||||
@@ -55,11 +55,11 @@ namespace boost { namespace python
|
||||
[variablelist
|
||||
[[Requires][`PyTuple_Check(args) != 0`, `result != 0`]]
|
||||
[[Effects][Makes the lifetime of the object indicated by ward dependent on the lifetime of the object indicated by custodian. ]]
|
||||
[[Returns][0 and PyErr_Occurred() != 0 upon failure, true otherwise. ]]
|
||||
[[Returns][`0` and `PyErr_Occurred() != 0` upon failure, `true` otherwise. ]]
|
||||
]
|
||||
[endsect]
|
||||
[section Example]
|
||||
The following example shows how with_custodian_and_ward_postcall is used by the library to implement return_internal_reference
|
||||
The following example shows how `with_custodian_and_ward_postcall` is used by the library to implement `return_internal_reference`
|
||||
``
|
||||
template <std::size_t owner_arg = 1, class Base = default_call_policies>
|
||||
struct return_internal_reference
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
[section wrapper.hpp]
|
||||
[section boost/python/wrapper.hpp]
|
||||
[section Introduction]
|
||||
To wrap a class T such that its virtual functions can be "overridden in Python"—so that the corresponding method of a Python derived class will be called when the virtual function is invoked from C++—you must create a C++ wrapper class derived from ``T`` that overrides those virtual functions so that they call into Python. This header contains classes that can be used to make that job easier.
|
||||
To wrap a class T such that its virtual functions can be "overridden in Python"—so that the corresponding method of a Python derived class will be called when the virtual function is invoked from C++—you must create a C++ wrapper class derived from `T` that overrides those virtual functions so that they call into Python. This header contains classes that can be used to make that job easier.
|
||||
[endsect]
|
||||
[section Class override]
|
||||
Encapsulates a Python override of a C++ virtual function. An override object either holds a callable Python object or None.
|
||||
[section Class `override`]
|
||||
Encapsulates a Python override of a C++ virtual function. An override object either holds a callable Python object or `None`.
|
||||
``
|
||||
namespace boost
|
||||
{
|
||||
@@ -22,7 +22,7 @@ namespace boost
|
||||
};
|
||||
``
|
||||
[endsect]
|
||||
[section Class override observer functions]
|
||||
[section Class `override` observer functions]
|
||||
``
|
||||
unspecified operator() const;
|
||||
template <class A0>
|
||||
@@ -34,11 +34,11 @@ template <class A0, class A1, ...class An>
|
||||
unspecified operator(A0, A1, ...An) const;
|
||||
``
|
||||
[variablelist
|
||||
[[Effects][If *this holds a callable Python object, it is invoked with the specified arguments in the manner specified here. Otherwise, throws error_already_set .]]
|
||||
[[Returns][An object of unspecified type that holds the Python result of the invocation and, when converted to a C++ type R, attempts to convert that result object to R. If that conversion fails, throws error_already_set.]]
|
||||
[[Effects][If *this holds a callable Python object, it is invoked with the specified arguments in the manner specified here. Otherwise, throws [link high_level_components.boost_python_errors_hpp.class_error_already_set error_already_set].]]
|
||||
[[Returns][An object of unspecified type that holds the Python result of the invocation and, when converted to a C++ type R, attempts to convert that result object to R. If that conversion fails, throws [link high_level_components.boost_python_errors_hpp.class_error_already_set error_already_set].]]
|
||||
]
|
||||
[endsect]
|
||||
[section Class template wrapper]
|
||||
[section Class template `wrapper`]
|
||||
Deriving your wrapper class from both `T` and `wrapper<T>` makes writing that derived class easier.
|
||||
``
|
||||
namespace boost
|
||||
@@ -51,11 +51,11 @@ namespace boost
|
||||
};
|
||||
``
|
||||
[endsect]
|
||||
[section Class wrapper observer functions]
|
||||
[section Class template `wrapper` observer functions]
|
||||
``override get_override(char const* name) const;``
|
||||
[variablelist
|
||||
[[Requires][name is a ntbs.]]
|
||||
[[Returns][If *this is the C++ base class subobject of a Python derived class instance that overrides the named function, returns an override object that delegates to the Python override. Otherwise, returns an override object that holds None.]]
|
||||
[[Requires][name is a [link ntbs].]]
|
||||
[[Returns][If `*this` is the C++ base class subobject of a Python derived class instance that overrides the named function, returns an override object that delegates to the Python override. Otherwise, returns an override object that holds `None`.]]
|
||||
]
|
||||
[endsect]
|
||||
[section Example]
|
||||
|
||||
Reference in New Issue
Block a user