Python

The Range library supports lazy ranges, which maps relatively well to Python iterators. The communication layer to allow this uses Boost.Python.

Using a Python iterator as a C++ range

It is often useful to pass in Python iterators as arguments to a C++ function.

TODO give a complete example.

template <class... Types>
class range::python_range

Represent a Python iterable as a range.

Python iterables are such things as lists, tuples, and generators. The range is lazy; the length of the iterable is not checked. The elements are extracted as the correct type only as they are queried.

If its elements should be returned as boost::python::object, then give no template parameters. If its elements are all one type, then give that type as the template parameter. If its elements have different types, then give the sequence of types as template parameters.

Even if a sequence of types is given, empty() will happily return true when the Python iterable is exhausted.

To use this class, it must be registered with Boost.Python. For example, your BOOST_PYTHON_MODULE could contain:

using namespace range;
python::convert_object_to_range <python_range <double>>();
def <void (python_range <double>)> ("my_function", my_function);

Python exceptions are propagated.

Templates
  • Types -

    The types that the iterable contains. If none are given, first() will return values of boost::python::object. If one or more are given, those types will be extracted from the Python iterable in order. The last type will be repeated indefinitely.

This class is defined to call next() on the Python iterator lazily. However, it is not defined when it is called exactly; it may be called earlier than expected. This may yield unexpected results if the Python iterator has side effects or raises exceptions.

template <class Range>
class range::python::convert_object_to_range

Construct an object of this class to register a python_range. This should be done in the BOOST_PYTHON_MODULE function.

Templates

Exposing a C++ range as a Python iterator

It is often useful to traverse a C++ range from Python. For example, when a C++ function returns a range and is exposed to Python.

TODO give a complete example.

class range::python::python_iterator

Present a view of a range as something that can act like a Python iterator.

The underlying range must implement empty() and chop_in_place().

If you want to use a full-fledged container, instead of using this, see http://www.boost.org/doc/libs/release/libs/python/doc/v2/indexing.html

void initialise_iterator()

Initialise support for Python iterators.

This must be called once in your BOOST_PYTHON_MODULE.

template <class View>
void register_view()

Register a view type to be exposes to Python as an iterator.

This must be called in your BOOST_PYTHON_MODULE, once for each type of View.

The element type of the view must be convertible to boost::python::object. The view will be traversed in direction front, which must be the default direction.

template <class BasePolicy = boost::python::default_call_policies>
struct range::python::return_view

A call policy for Boost.Python to return a view as a Python iterator.

Use this call policy for a function that returns a view. The Python iterator that the view is converted to will be traversed in direction front, which must be the default direction. The view must be homogeneous.

The view can be movable but not copyable. This may depend on the implementation of Boost.Python and be a bit lucky, but our luck is unlikely to change since any new version of Boost.Python will surely consider rvalue references.

You must call range::python::initialise_iterator() once in your BOOST_PYTHON_MODULE for this call policy to work.

See
return_view_of_internal_reference

template <std::size_t owner_argument_index, class BasePolicy = boost::python::default_call_policies>
struct range::python::return_view_of_internal_reference

A call policy for Boost.Python to return a reference to a range as a Python iterator.

This assumes that the range that the return value references is contained in argument owner_argument_index of the function. After the function is called, range::view will called on the range. The Python iterator that the view is converted to will be traversed in direction front, which must be the default direction. The view must be homogeneous.

This is similar to the standard boost::python::return_internal_reference in that it keeps an argument alive at least until the return value goes out of scope. Additionally, however, the return value is converted into a view.

You must call range::python::initialise_iterator() once in your BOOST_PYTHON_MODULE for this call policy to work.

See
return_view

Exposing a C++ range as a Python tuple

It is often useful to convert a C++ tuple to a Python tuple. This can be used for any C++ range that has a fixed number of elements.

TODO give a complete example.

template <class Tuple>
void register_tuple()

Register a C++ tuple type to be exposed to Python as a tuple.

This must be called in your BOOST_PYTHON_MODULE, once for each type of Tuple.

The tuple can be of any range that has fixed-length type and random access. The element types of the view must be convertible to boost::python::object. The elements of the C++ tuple are copied to Python.

Table Of Contents

Previous topic

Interfaces

Next topic

Calling functions

This Page