Reputation: 3258
I am testing the simpleTAL templating library which makes use of callable to test if an object passed into the template is a function or not. The definition of callable says that an object is callable if it contains the magic method __call__
. See also What is a "callable" in Python?.
However, an object created with the following class definition (python 2.7.4)
class H:
def __init__(self, val):
self.a = val
def __getattr__(self, name):
return 'blah'
h = H(1)
callable(h)
will return True. If, however, __getattr__
raises AttributeError, which does not make sense to do systematically, it will return False!
Can someone shed some light on this issue and possibly a solution? (I don't want h to be callable).
Upvotes: 2
Views: 87
Reputation: 1123400
Your __getattr__
hook returns a value for all attributes:
>>> h.__call__
'blah'
and thus a test for hasattr(h, '__call__')
returns True
:
>>> hasattr(h, '__call__')
True
Make sure you raise a AttributeError
for attributes the object doesn't support instead.
Note: this applies only to old-style instances; instances for new-style classes (the default in Python 3, and any class inheriting from object
in Python 2) are not tested for the __call__
attribute; instead the class itself is consulted.
You could thus switch to new-style classes as well to mitigate this, but your __getattr__
should still not be too broad.
Upvotes: 6