[Python-ideas] Fix that broken callable builtin

Paul Moore p.f.moore at gmail.com
Sun Apr 19 01:09:48 CEST 2015


On 18 April 2015 at 22:40, Ionel Cristian Mărieș <contact at ionelmc.ro> wrote:
> On Sun, Apr 19, 2015 at 12:34 AM, Chris Angelico <rosuav at gmail.com> wrote:
>>
>>
>> Uhh, that's not exactly true. Maybe it's true of the other three of
>> the Big Four (Jython, IronPython, PyPy), but there are several other
>> Pythons which are compliant with a version 3.x spec; MicroPython and
>> Brython come to mind.
>
>
> Ok, but what's reasonable here? I think you're implying here that this small
> change should go through a PEP process.
>
> So a question for the list, does this seemingly small change warrant a PEP?

Note that the docs for callable() explicitly allow for false positives
- callable(x) is true, but x() fails. See
https://docs.python.org/3/library/functions.html#callable ("If this
returns true, it is still possible that a call fails").

The "bug" you mentioned earlier in the thread is precisely that - a
case where callable() returns True but calling the object fails:

>It doesn't really work because of the incomplete checks done in `callable_builtin`. This is what I've tried:
>
>> >>> class DynamicCallable:
>> ...     is_callable = True
>> ...
>> ...     def __init__(self, target):
>> ...         self.target = target
>> ...
>> ...     @property
>> ...     def __call__(self):
>> ...         if self.is_callable:
>> ...             return self.target
>> ...         else:
>> ...             raise AttributeError("Not really ...")
>> ...
>> >>> dc = DynamicCallable(print)
>> >>> dc(1, 2, 3)
>> 1 2 3
>> >>> callable(dc)
>> True
>> >>> dc.is_callable = False
>> >>> callable(dc)
>> True ###### This should be False :(
>
>
> If the "bug" is fixed, then the last thing in the above example would return False..

So I'm not clear what "small change" you're referring to here:

* A change to CPython to reduce the number of false positives by
making this case return False? If that, then no, I don't think a PEP
is needed. But note that user code still can't assume that the above
behaviour couldn't still happen in *other* cases, so the change would
be of limited value (and whether it gets accepted depends on whether
the complexity is justified by the benefit).
* A change to the definition of callable() to remove the possibility
of false positives at all? In that case, yes, a PEP probably *is*
needed, as that's going to affect an awful lot of corner cases, and
will impact all implementations. It's probably not correct to call
this a "small change".
* Something else?

Paul


More information about the Python-ideas mailing list