Issue with new-style classes and operators
Terry Reedy
tjreedy at udel.edu
Mon Nov 25 18:36:45 EST 2002
"Jan Decaluwe" <jan at jandecaluwe.com> wrote in message
news:3DE215D1.D9A3FEF9 at jandecaluwe.com...
> Hi:
>
> I'm confused by the following behavior of new-style classes
> and operators:
I think you have a right to be.
>
> class MyInt(object):
> def __init__(self, val):
> self.val = val
> def __getattr__(self, attr):
> return getattr(self.val, attr)
> >>> a = MyInt(3)
> >>> a.__add__(4)
> 7
This works because '__add__' is seen as just an attribute name,
nothing special, which is resolved because of __gettattr__ booting
attribute lookup to self.val. As far as the interpreter is concerned,
this might as well have been a.whatever(4).
> >>> a + 4
> Traceback (most recent call last):
> File "<stdin>", line 1, in ?
> TypeError: unsupported operand types for +: 'MyInt' and 'int'
Lookup of special methods invoked by syntax other than explicit
instance.attr appears to have been changed for new classes by stopping
the lookup process before calling __getattr__.
This appears to contradict the current new-class doc at
http://python.org/2.2/descrintro.html
"Note that while in general operator overloading works just as for
classic classes, there are some differences. "
Which are...?
"(The biggest one is the lack of support for __coerce__; new-style
classes should always use the new-style numeric API, which passes the
other operand uncoerced to the __add__ and __radd__ methods, etc.) "
what else? but then
"There's a new way of overriding attribute access. The __getattr__
hook, if defined, works the same way as it does for classic classes:
it is only called if the regular way of searching for the attribute
doesn't find it. But you can now also override __getattribute__, a
new operation that is called for *all* attribute references."
But you found a difference in __getattr__. Contrary to inplication of
doc, __getattribute__ is also not called for a+4. (Not a big loss
since attempt to access any attribute, including .__dict__, causes
infinite loop.) I opened sf bug report 643841.
>I don't think is can be the intention. Or can it?
Beats me. We'll see.
Terry J. Reedy
More information about the Python-list
mailing list