mark florisson, 09.05.2012 10:37: > On 9 May 2012 09:02, Stefan Behnel <stefan...@behnel.de> wrote: >> Vitja Makarov, 09.05.2012 09:43: >>> 2012/5/9 Stefan Behnel <stefan...@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. > > Huh, so __call__ in a user defined new style class could never end up > in ob_type.tp_call right?
Yes it does. CPython special cases these method names. Stefan _______________________________________________ cython-devel mailing list cython-devel@python.org http://mail.python.org/mailman/listinfo/cython-devel