Search code examples
pythonc++pybind11

Mixing type conversions and opaque types with pybind11


I am making use of opaque types with pybind11. For example, I defined one for the stl container std::vector<uint32_t>, which is a argument type of the method FromVec:

void FromVec(std::vector<uint32_t> vec);

PYBIND11_MAKE_OPAQUE(std::vector<uint32_t>);

PYBIND11_MODULE(tmap, m)
{
    py::bind_vector<std::vector<uint32_t>>(m, "VectorUint", 
      "Unsigned 32-bit int vector.");

    m.def("from_vec", &FromVec, py::arg("vec")
}

With this I can now (in Python) do the following:

vec = VectorUint([2, 66, 262, 662, 26, 62])
from_vec(vec)

However, type conversion does not work anymore, as the function now expects a VectorUint and doesn't accept list anymore, e.g.:

l = [2, 66, 262, 662, 26, 62]
from_vec(l)

Is there a way to allow for both, oblique types and type conversion? That is, when a list is passed instead of a oblique bound VectorUint it is converted to a std::vector<uint32_t> rather than Python throwing "incompatible function arguments"?


Solution

  • If you need automatic conversion to std::vector from list you can add such overload to your binding code:

    m.def("from_vec", &FromVec, py::arg("vec")); // accepts VectorUnit 
    m.def("from_vec", [](py::list& list){ /* do conversion manually and call FromVec */ } ); // accepts python list