[Python-Dev] 'hasattr' is broken by design

P.J. Eby pje at telecommunity.com
Wed Aug 25 21:57:12 CEST 2010


At 08:58 PM 8/25/2010 +0300, Michael Foord wrote:
>If your proxy class defines __call__ then callable returns True, 
>even if the delegation to the proxied object would cause an 
>AttributeError to be raised.

Nope.  You just have to use delegate via __getattribute__ (since 2.2) 
instead of __getattr__:

 >>> from peak.util.proxies import ObjectProxy
 >>> o=ObjectProxy(lambda:1)
 >>> o()
1
 >>> o.__call__
<method-wrapper '__call__' of function object at 0x00E004B0>

 >>> o=ObjectProxy(1)
 >>> o()
Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
   File 
"c:\cygwin\home\pje\projects\proxytypes\peak\util\proxies.py", line 6, in
  __call__
     return self.__subject__(*args,**kw)
TypeError: 'int' object is not callable

 >>> o.__call__
Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
   File 
"c:\cygwin\home\pje\projects\proxytypes\peak\util\proxies.py", line 12, i
n __getattribute__
     return getattr(subject,attr)
AttributeError: 'int' object has no attribute '__call__'


As you can see, the __call__ attribute in each case is whatever the 
proxied object's __call__ attribute is, even though the proxy itself 
has a __call__ method, that is invoked when the proxy is called.

This is actually pretty straightforward stuff since the introduction 
of __getattribute__.

(The code is at http://pypi.python.org/pypi/ProxyTypes, btw.)



More information about the Python-Dev mailing list