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