2

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).

Community
  • 1
  • 1
koriander
  • 3,110
  • 2
  • 15
  • 23

1 Answers1

6

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.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343