C++ Boost

Boost.Python

ObjectWrapper and TypeWrapper Concepts


Introduction
Concept Requirements
ObjectWrapper Concept
TypeWrapper Concept
Caveat

Introduction

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.

Concept Requirements

ObjectWrapper Concept

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)))()
When the R is an TypeWrapper, the result type may be constructed by taking direct posession of:
x.attr("some_function")(object(a1), object(a2),...object(an)).ptr()
[see caveat below]

TypeWrapper Concept

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.

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:
>>> 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.

Revised 13 November, 2002

© Copyright Dave Abrahams 2002.