[Python] in pybind11, how do you test if py::object is a complex number or a callable?

Discussão em 'Python' iniciado por Stack, Junho 20, 2025.

  1. Stack

    Stack Membro Participativo

    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::eek:bject (user input in python) to a class in my code that acts a lot like py::eek:bject (call it myobject), I need to detect the type of py::eek:bject. 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::eek:bject 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::eek:bject builtins = py::module_::import("builtins");
    py::eek:bject eval = builtins.attr("eval");
    py::eek:bject 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?

    Continue reading...

Compartilhe esta Página