Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

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?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading