Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I use PyObject_IsInstance with a non-builtin class as second argument?

In C/C++, I want to see if a PyObject is an instance. Unfortunately, the PyInstance_Check macro doesn't work with new-style classes.

So, according to forums posts that I read, PyObject_IsInstance could solve the problem. However, all the examples that I have found are demonstrating comparisons with built-in types, like ints and strings.

I want to know how I can construct a PyObject that represents a class of a type, so I can pass it to the second argument of PyObject_IsInstance. Can you help me?

like image 230
GDICommander Avatar asked Aug 08 '12 14:08

GDICommander


2 Answers

I have finally found the answer myself, based on the contents of that page: Create instance of a python class , declared in python, with C API

// PyInstance_Check works only for old-style classes.
qBool isInstance = PyInstance_Check(pyInstance);
if (!isInstance)
{
    // It might be an instance of a new-style class.
    //
    PyRef module = PyImport_ImportModule("module.where.myclass.is");
    PyObject* moduleDict = PyModule_GetDict(module.Get());
    PyObject* protocolClass = PyDict_GetItemString(moduleDict, "MyClass");

    int returnValue = PyObject_IsInstance(pyObject, protocolClass);
}
like image 166
GDICommander Avatar answered Sep 28 '22 05:09

GDICommander


You could use the corresponding PyTypeObject if it is defined in the same module. If the type object (let's say it's called ProtocolType) is not visible from where you want to use PyObject_IsInstance, first declare a prototype with:

extern PyTypeObject ProtocolType;

And then use it like this:

PyObject_IsInstance(object, reinterpret_cast<PyObject*>(&ProtocolType))
like image 23
Lucas Avatar answered Sep 28 '22 04:09

Lucas