[C++-sig] Convert Python tuple to boost::tuple? (was Re: easy method for converting boost::tuple to python tuple?)

François Duranleau duranlef at iro.umontreal.ca
Mon Jan 30 17:24:46 CET 2006


On Mon, 23 Jan 2006, David Abrahams wrote:

> http://www.boost.org/libs/python/doc/v2/to_python_converter.html
>
> should set you on the right path.
>
>  // Untested!
>  #include <boost/python/tuple.hpp>
>  #include <boost/python/module.hpp>
>  #include <boost/python/refcount.hpp>
>
>
>  namespace python = boost::python;
>  namespace tuples = boost::tuples;
>
>  namespace my
>  {
>    template <class H, class T>
>    python::tuple tuple_to_python(tuples::cons<H,T> const& x)
>    {
>        return python::make_tuple(x) + my::tuple_to_python(x.tail);
>    }
                                   ^^^

I guess it should rather be:

          return python::make_tuple(x.head) + my::tuple_to_python(x.tail);
                                    ^^^^^^

>    python::tuple tuple_to_python(tuples::null_type)
>    {
>        return python::tuple();
>    }
>
>    template <class T>
>    struct tupleconverter
>    {
>        static PyObject* convert(T const& x)
>        {
>            return python::incref(my::tuple_to_python(x).ptr());
>        }
>    };
>  }
>
>  BOOST_PYTHON_MODULE(whatever)
>  {
>      to_python_converter<my_tuple_type, tupleconverter<my_tuple_type> >();
>  }
>
> Something like this really should be in the library already, though,
> shouldn't it?

It would certainly be very helpful.

But how about doing the opposite? That is, how to easily convert a Python 
tuple to a boost::tuple automatically?

I have a couple of functions with a boost::tuple as an argument (and 
others returning a tuple), and of course, I would prefer to use python 
tuples in python. The code above helps the case of return values, but what 
about function arguments? I could do something like this (not tested as 
well):

namespace py = boost::python ;

// function to export
void func( const boost::tuple< int , int >& t )
{
     // ...
}

void wrapped_func( py::tuple t )
{
     func( boost::make_tuple( py::extract< int >( t[ 0 ] )() ,
                              py::extract< int >( t[ 1 ] )() ) ) ;
}

BOOST_PYTHON_MODULE( test )
{
     py::def( "func" , & wrapped_func ) ;
}

But it is somewhat inconvenient to write wrappers like this for every such 
function. Could we do something with boost::python::lvalue_from_pytype?

-- 
François Duranleau
LIGUM, Université de Montréal

"There, now you have a top and a bottom! But you've lost a degree of your
  freedom. Now you must stand on the ground. But now you feel easier, don't
  you? You have less to trouble your mind."
                                           - from _Neon Genesis Evangelion_


More information about the Cplusplus-sig mailing list