[Python-ideas] Fix that broken callable builtin
Christian Heimes
christian at python.org
Sat Apr 18 19:43:02 CEST 2015
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512
On 2015-04-17 23:39, Guido van Rossum wrote:
> I think you've found an unintended and undocumented backdoor. I
> admit I don't understand how this works in CPython. Overloaded
> operators like __add__ or __call__ should be methods in the class,
> and we don't look for them in the instance. But somehow defining
> them with @property works (I guess because @property is in the
> class).
>
> What's different for __call__ is that callable() exists. And this
> is probably why I exorcised it Python 3.0 -- but apparently it's
> back. :-(
>
> In the end callable() doesn't always produce a correct answer; but
> maybe we can make it work in this case by first testing the class
> and then the instance? Something like (untested):
>
> def callable(x): return hasattr(x.__class__, '__call__') and
> hasattr(x, '__call__')
The code behind callable() is very simple and very fast:
int
PyCallable_Check(PyObject *x)
{
if (x == NULL)
return 0;
return x->ob_type->tp_call != NULL;
}
IMHO the behavior is well in range of the documentation. It also
conforms to my gut feeling and the behavior of PyPy and Jython (tested
with Jython 2.7b3+ and PyPy 2.4.0). The three major Python
implementation agree on callable(o) == hasattr(type(o), '__call__')
for new style classes.
Because PyCallable_Check() is so fast with just two pointer derefs, it
may be used in several hot paths. Any modification may cause a slow
down. This aspect must be thoroughly investigates before the code is
changed.
For all this reasons I'm -1 on the proposed change.
Christian
-----BEGIN PGP SIGNATURE-----
iQEcBAEBCgAGBQJVMpecAAoJEIZoUkkhLbaJyjAH/AiueFdO0wECxZkc53f10Txk
Kjb1RB2SRyNIwcvOR5sXJVCP4OrazlTyDSOeCxQ50I8IBXk2vAbdKVEfjuNW4SqQ
Dr6xijhA2JjAq/TfBHdMJkcGUySBPkBNTn7Dd50TvJm+PE+D4zlGXpgI7rfZXGM5
MwWrphk0/sB6bZ6WSDjdoCQ40V6CZ1uWTU2N5yd/+vtpA91Yl/FB5Xu7x3sRwt0Y
A24GbJHqwgwgnQ7kFozBIbilN3dpcI+Pn5LC6KbqldlNvdp9IMCZh0dm+psnKHVq
2kClbv8f03EahScnKzVh3PblJZ2DB8AEq+PRalmi/v4m0BvWT8a073708BQLocg=
=VJMz
-----END PGP SIGNATURE-----
More information about the Python-ideas
mailing list