[Cython] callable() optimization

Stefan Behnel stefan_ml at behnel.de
Wed May 9 10:02:51 CEST 2012


Vitja Makarov, 09.05.2012 09:43:
> 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;
>     }
> }

That's the Py2 version. In Py3, it looks as follows, because old-style
"instances" no longer exist:

"""
int
PyCallable_Check(PyObject *x)
{
        if (x == NULL)
                return 0;
        return x->ob_type->tp_call != NULL;
}
"""

That's what I had initially based my optimisation on.

Stefan


More information about the cython-devel mailing list