2.2: __call__ method via __getattr__ not working
Roeland Rengelink
r.b.rigilink at chello.nl
Wed Aug 15 03:07:35 EDT 2001
Drew Csillag wrote:
>
> I don't know if this is a known bug in the current CVS version of 2.2
> but the following code breaks.
>
> class bar(object):
> def __call__(self, args):
> print args
>
> b = bar()
> b(1) #works ok here
>
> class foo(object):
> def _call_(self, args):
> print args
> def __getattr__(self, attr):
> if attr == '__call__':
> return self._call_
> raise AttributeError, attr
>
> f = foo()
> f(1) #dies here
>
Well, I think this is (currently) a feature:
This works:
class foo(object):
def __call__(): pass # Convince Py foo is callable
def _call_(self, args):
print args
def __getattr__(self, attr):
if attr == '__call__':
attr = attr[1:-1]
return object.__getattr__(self, attr)
The reason this works is that when the this class definition is executed
def __call__():pass will fill the tp_call slot of the newly defined foo
type with a wrapper
that basically does an attribute lookup for __call__. If that def is not
present execution of the class definition will erroneously conclude that
tp_call needs not be set. When f(1) is then executed Python will check
this slot and conclude that a foo object is not callable.
Believe me, the previous sentences make sense when you look at the C
code
Hope this helps,
Roeland
--
r.b.rigilink at chello.nl
"Half of what I say is nonsense. Unfortunately I don't know which half"
More information about the Python-list
mailing list