[Cython] callable() optimization

Vitja Makarov vitja.makarov at gmail.com
Wed May 9 09:43:58 CEST 2012


2012/5/9 Stefan Behnel <stefan_ml at behnel.de>:
> Vitja Makarov, 08.05.2012 13:27:
>> I've noticed regression related to callable() optimization.
>>
>> https://github.com/cython/cython/commit/a40112b0461eae5ab22fbdd07ae798d4a72ff523
>>
>> class C:
>>     pass
>> print callable(C())
>>
>> It prints True optimized version checks ((obj)->ob_type->tp_call !=
>> NULL) condition that is True for both class and instance.
>>
>> >>> help(callable)
>> callable(...)
>>     callable(object) -> bool
>>
>>     Return whether the object is callable (i.e., some kind of function).
>>     Note that classes are callable, as are instances with a __call__() method.
>
> Ah, right - old style classes are special cased in Py2.
>
> I'll make this a Py3-only optimisation then.
>

I don't see difference between py2 and py3 here:

Python 3.2.3 (default, May  3 2012, 15:51:42)
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> class Foo: pass
...
>>> callable(Foo())
False
>>>

There is PyCallable_Check() CPython function:

int
PyCallable_Check(PyObject *x)
{
    if (x == NULL)
        return 0;
    if (PyInstance_Check(x)) {
        PyObject *call = PyObject_GetAttrString(x, "__call__");
        if (call == NULL) {
            PyErr_Clear();
            return 0;
        }
        /* Could test recursively but don't, for fear of endless
           recursion if some joker sets self.__call__ = self */
        Py_DECREF(call);
        return 1;
    }
    else {
        return x->ob_type->tp_call != NULL;
    }
}



-- 
vitja.


More information about the cython-devel mailing list