Uthay Kumar
Uthay Kumar

Reputation: 141

Find the type of boost python object

I have been embedding python into c++ and I would like to know if there is a way to find the type of the boost::python::object which is a result after executing a function of a python module. I have my code like this:

boost::python::object module_ = boost::python::import("..libName");
boost::python::object result_ = module_.attr("..functionName")(arg1, arg2,...);
//suppose if the result is int,
int a_ = boost::python::extract<int>(result_);

From the above code snippet, what i would like to know is if there is way to find the type of the result before extracting it. In the above code, the result_ might be any type like list, tuple...

Upvotes: 14

Views: 8289

Answers (3)

csl
csl

Reputation: 11358

Since you seem to want to check if it's an integer, you can use extract<T> x(o):

boost::python::extract<int> n(o);

if ( n.check() )
    // it's an integer, or at least convertible to one
else
    // not an integer

The documentation says:

extract x(o); constructs an extractor whose check() member function can be used to ask whether a conversion is available without causing an exception to be thrown.

This may sound as if a float may be deemed convertible to integer, but I tried it, and it doesn't. In other words, I wouldn't really trust that it does the right thing every time!

For built-in types, in this case an integer, I think it's more safe to use PyInt_Check, but at least when I tested some code here, it wasn't immediately available.

In other words, if you need to determine the type of objects that are not Python built-ins, I'd follow @Aereaux's suggestion of using PyObject_IsInstance. (But I'd personally like better to have a clean Boost Python code base, rather than a mix.)

Upvotes: 5

user1886376
user1886376

Reputation:

You can try this

std::vector<std::string> list_to_vector(boost::python::list& l)
{
    for (int i = 0; i < len(n); ++i)
    {
        boost::python::extract<boost::python::object> objectExtractor(l[i]);
        boost::python::object o=objectExtractor();
        std::string object_classname = boost::python::extract<std::string>(o.attr("__class__").attr("__name__"));
        std::cout<<"this is an Object: "<<object_classname<<std::endl;
    }
    ...................................................
    ...................................................
 }

It works for me.

Upvotes: 13

Aereaux
Aereaux

Reputation: 855

There are a couple ways to get the type of an object. Which one you use depends on what format you want the result to be. You could use result_.attr("__class__") to get the class as a boost::python::object. You could also use the PyObject_IsInstance function to check if it is the type you think it is. Last, you could use the PyObject_Type function to get the type of it as a PyObject*.

Upvotes: 4

Related Questions