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
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.