The Python Oracle

When can calls to a callable() still fail?

--------------------------------------------------
Rise to the top 3% as a developer or hire one of them at Toptal: https://topt.al/25cXVn
--------------------------------------------------

Music by Eric Matyas
https://www.soundimage.org
Track title: Lost Meadow

--

Chapters
00:00 When Can Calls To A Callable() Still Fail?
00:34 Accepted Answer Score 4
02:46 Thank you

--

Full question
https://stackoverflow.com/questions/5097...

--

Content licensed under CC BY-SA
https://meta.stackexchange.com/help/lice...

--

Tags
#python

#avk47



ACCEPTED ANSWER

Score 4


First, it's trivially true that any function call can fail. Maybe you mutated the object between checking callable and calling it. Or maybe the object is callable, but you passed it invalid arguments, or it raised an exception during operation, or the user just hit ^C, …

But that's not what the docs are warnings about. They're telling you that you can get a TypeError: <something> is not callable from doing func() even if callable(func) returned True.

While this isn't exactly documented (maybe to allow other implementations to optimize things?), callable is essentially implemented as:

def callable(object):
    return hasattr(object, '__call__')

And this is at least implied, if not directly stated:

Note that classes are callable (calling a class returns a new instance); instances are callable if their class has a __call__() method.

The key is that really everything is an instance. (Classes are instances of their metaclass, which always has a __call__ method.)


So, it's very easy to create something that breaks the test. One way is to just give it a non-callable __call__:

>>> class C:
...     __call__ = 0
>>> c = C()
>>> callable(c)
True
>>> c()
TypeError: 'int' object is not callable

Also, notice that claiming that false negatives are impossible ("if it is false, calling object will never succeed") implies that special method lookup on the __call__ method must use the same mechanism as callable (or a strictly weaker one). So, for example, if a Python implementation chooses not to ignore metaclass __getattribute__ lookup or instance __dict__ lookup for __call__, its callable must do the same. And you can see this (at least in CPython 3.7):

>>> class D:
...     pass
>>> d = D()
>>> d.__call__ = 0
>>> callable(d)
False
>>> d()
TypeError: 'D' object is not callable

(Testing the other special method lookup possibilities is left as an exercise for the reader, meaning I'm too lazy to write them all and happy enough guessing they'll all go the same way…)


In CPython, callable actually just calls the C API method PyCallable_Check. And that function just checks that the object's type has a tp_call slot. For types implemented in Python, that will be true iff __call__ was defined directly on the class or a base class.