Context: I've recently been using pybind11 to put a python frontend on an old c++ project of mine. This has mostly been a breeze (thanks pybind11 devs!), but there are some areas where I've had to resort to some really ugly hacks that I'd rather like to avoid.
Question: When translating from py::object (user input in python) to a class in my code that acts a lot like py::object (call it myobject), I need to detect the type of py::object. This is trivial for int, float, string, list etc, but I can't see an obvious way for complex numbers and function handles. Here's my current workaround for complex numbers:
bool isComplex(py::object src)
{
// put src into a buffer accessible from both C++ and python (i is an index in this buffer)
int i = pyosetsrc(src);
// Build a python function to do the "is it complex" test
std::string fn;
fn = "isinstance(mycode.pyogetsrc("; // pyogetsrc(i) gets src back out of the shared buffer
fn += std::to_string(i);
fn += "), complex)";
// Wrap this in an eval statement
std::string evalfn;
evalfn = "eval('";
evalfn += fn;
evalfn += "')";
// Run the eval statement
py::object builtins = py::module_::import("builtins");
py::object eval = builtins.attr("eval");
py::object res = eval(evalfn);
// Process the result
return py::isinstance<py::bool_>(res) && py::cast<py::bool_>(res);
}
and for function handles there's a similar hack, this time with:
fn = "callable(mycode.pyogetsrc(";
fn += std::to_string(i);
fn += "))";
is there a less awful alternative I'm missing here?