Description
I cannot figure out how to invoke a C function with an std::initializer_list argument from Python. I posted this question first on Stackoverflow then in the Gitter chat room. I also looked around for a relevant test case and could not find one. Perhaps this is not supported? The C function is:
#include <iostream>
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
using namespace std;
namespace py = pybind11;
void list_ints(const std::initializer_list<int> &il) {
std::cout << "Got to list_ints ..." << std::endl;
for (const auto &elem : il)
std::cout << to_string(elem) << " ";
std::cout << std::endl;
};
PYBIND11_MODULE(initializer, m) {
// This does not match anything
m.def("list_ints", &list_ints);
// This matches a list argument and invokes the function, then BOOM.
m.def("list_ints", (void (*) (const std::vector<int>&)) &list_ints);
}
The python code to invoke this function is:
from initializer import list_ints
l = [1,2]
# Call succeeds but function Seg Faults!
list_ints(l)
print(l)
The function only succeeds with the addition of the second m.def() above. Using only m.def("list_ints", &list_ints)
results in a TypeError: list_ints(): incompatible function arguments whether I'm passing *args or a single list. With the second binding in place, the output is:
Got to list_ints ...
1 2 0 -1073741824 0 0 259188368 ...
and then BOOM. It iterates off the end of the initializer list. I'm running on MacOS/llvm, --std=c++14, Python 3.4. I can call this same function in C with list_ints({1,2,3,4,5})
and it works as expected.