...one of the most highly
regarded and expertly designed C++ library projects in the
world. — Herb Sutter and Andrei
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.
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
always has semantics equivalent to:
(see caveat below).
TypeWrapper is a refinement of ObjectWrapper
which is associated with a particular Python type
For a given TypeWrapper
a valid constructor expression
builds a new T object managing the result of invoking X with arguments corresponding to
. 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.
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
an object of type list.
Now suppose the user defines this
subclass in Python:
>>> class mydict(dict): ... def items(self): ... return tuple(dict.items(self)) # return a tuple
Since an instance of
is also an instance of
when used as an argument to a wrapped C++ function, boost::python::dict
can accept objects of Python type
on this object can result in an instance of boost::python::list
which actually holds a Python
Subsequent attempts to use
any other mutating operation) on this object will raise the same exception
that would occur if you tried to do it from Python.