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. Stefan _______________________________________________ cython-devel mailing list cython-devel@python.org http://mail.python.org/mailman/listinfo/cython-devel