pythonc++instancecallablepython-embedding

Why PyCallable_Check() returns 0 on global class instances?


Rigth now I'm working on embedding python into a larger C++ application. Despite I'm not a python specialist, I understand that with the builtin PyCallable_Check() I can check if a python object is actually callable. From What is a "callable"? I found that it depends on an available __call__ method within classes or on types that have a non null tp_call member.

Now whats bothering me is that if I get a object reference (in C++) to a specific global instance of some class (within the python script), PyCallable_Check() gives me 0 as return when checking this reference, even when I'm actually able to call it. And since this is possible I would suppose having a tp_call member here (since I've got no __call__ method in my example).

So what am I missing? Why am I getting 0 as return?

Example C++ snippet:

//...

PyObject* pModule = PyImport_Import( PyUnicode_DecodeFSDefault("testfile") );
PyObject* pGlobalObj = PyObject_GetAttrString( pModule, "globalObj" );

int ok = PyCallable_Check(pGlobalObj)
if( !ok )
{
     std::cerr << "Not a callable?!" << std::endl;
     std::cerr << "PyCallable_Check() gives: " << ok << std::endl;
}
//call class method anyway...
PyObject* pValue = PyObject_CallMethod( pGlobalObj , "add", "(ii)", 45, 55 );
std::cout << "Global object result: " << PyLong_AsLong(pValue) << std::endl;

//...

with following testfile.py:

class TestClass:
    def add(self, a, b):
        return a + b

globalObj = TestClass()

which gives:

>> Not a callable?!
>> PyCallable_Check() gives: 0
>> Global object result: 100

Solution

  • That's not a callable. You may be misunderstanding what "callable" means.

    If globalObj were callable, you would be able to do globalObj(), perhaps with some appropriate arguments between the parentheses. You can't.