Search code examples
pythonc++11boost

Boost Python C++ boost::python::list input Python argument types did not match C++ signature


Created a test function to test if Boost Python can pass a Python list to a C++ method. However, it results in the following error:

Boost.Python.ArgumentError: Python argument types in boost_cpp.test_list() did not match C++ signature: test_list(boost::python::list)

I have been stuck on this issue for a really long time and there is no clear path forward. Any guidance is greatly appreciated.

#include <boost/python.hpp>

// Test that passing boost::python::list to C++ works.
boost::python::list test_list(boost::python::list input_list) {
    boost::python::ssize_t size = boost::python::len(input_list);
    boost::python::list output_list;
    output_list.append(boost::python::object()); // Append Python None type.
    output_list *= size;
    double value;

    for (unsigned int i = 0; i < size; i++) {
        value = boost::python::extract<double>(input_list[i]);
        output_list[i] = value;
    }

    return output_list;
}

BOOST_PYTHON_MODULE(boost_cpp) {
    using namespace boost::python;
    def("test_list", test_list);
}

Created a setup.py for building the extension by running python3 setup.py build_ext --inplace

from distutils.core import setup
from distutils.extension import Extension


# Boost Python test build of C++ extension methods.
boost_cpp = Extension(
    name="boost_cpp",
    sources=["./boost.cpp"],
    include_dirs=["/usr/include"],  # C++ header files.
    library_dirs=["/usr/lib"],  # C++ libs.
    libraries=["boost_python39"],
    extra_compile_args=[
        "-shared",
        "-export-dynamic",
    ],
)

setup(
    name="boost_cpp",
    version="0.1",
    ext_modules=[boost_cpp],
)
import boost_cpp

list_0 = [i for i in range(100)]
list_1 = boost_cpp.test_list(input_list = list_0)

Solution

  • I'm not 100% sure why this works but this is what solved the problem in this test example:

    
    using namespace boost::python;
    
    list test_list(list input_list) {
        ssize_t size = len(input_list);
        list output_list;
        output_list.append(object()); // Append Python None type.
        output_list *= size;
        double value;
    
        for (unsigned int i = 0; i < size; i++) {
            value = extract<double>(input_list[i]);
            output_list[i] = value;
        }
    
        return output_list;
    }