Search code examples
c++boostboost-python

How to create a numpy array of boost::python::object types


I'm trying to create a 2x2 numpy array of python objects:

#include <boost/python.hpp>
#include <boost/python/numpy.hpp>
int main()
{
    Py_Initialize();
    boost::python::numpy::initialize();
    boost::python::tuple shape = boost::python::make_tuple(2, 2);
    boost::python::object obj;
    boost::python::numpy::dtype dt = boost::python::numpy::dtype(obj);
    boost::python::numpy::ndarray array = boost::python::numpy::empty(shape, dt);
    std::cout << "Datatype is: " << boost::python::extract<char const *> boost::python::str(array.get_dtype())) << std::endl;
}

But the output is "Datatype is: float64" rather than a python object type.

What am I doing wrong?

I suspect I'm misusing the dtype constructor.


Solution

  • You're using the dtype constructor correctly; it's obj that's causing the trouble.

    The default construction boost::python::object obj; sets obj as the 'None' Python object. The dtype associated with 'None' is a NPY_DEFAULT array descriptor type. And that maps to a double when creating the numpy array, which explains your output. (That makes sense from a Python perspective - the default numpy array type is a double precision floating point type.)

    You can constuct a dtype with an object type (NPY_OBJECT) using

    boost::python::numpy::dtype dt = boost::python::numpy::dtype(boost::python::object("O"));
    

    which, in your case, is the fix. I've also taken the liberty of using an anonymous temporary which is how it's done in the Boost documentation. The "O" denotes the object type.