5

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?

Santosh Kumar
  • 26,475
  • 20
  • 67
  • 118
GDICommander
  • 1,273
  • 3
  • 15
  • 27

2 Answers2

5

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);
}
Community
  • 1
  • 1
GDICommander
  • 1,273
  • 3
  • 15
  • 27
  • 2
    Why don't you simply call `PyObject_GetAttrString()` instead of `PyModule_GetDict()` + `PyDict_GetItemString()` ? Also, `PyRef` is not in the Python/C-API reference. Where did it came from? – gog Mar 13 '17 at 08:18
1

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))
Mad Physicist
  • 107,652
  • 25
  • 181
  • 264
Lucas
  • 738
  • 7
  • 19