Is this a super bug?
Bjorn Pettersen
BPettersen at NAREX.com
Sun Apr 20 01:38:48 EDT 2003
> From: Bjorn Pettersen
Hate to reply to myself, but...
If this isn't the __getattribute__ bug I read about, it needs to be
documented that super only supports _direct_ access to attributes, but
not properties (although the Python version does), of a class in the
__mro__, but will not access any attribute the language defines as
"hooks" for various functionality indirectly... (i.e. all the __xx__
methods -- I could understand __getattribute__ would be a problem, but
even __getattr__ should have been possible to implement).
Sort of a special purpose proxy for the superclass... not what I
expected from the name. And there doesn't seem there is a way to
implement it in Python either. If I understand correctly, these
attributes are looked for directly in the instance's class, skipping
lookup in the instance itself, which is why the super instance's
__getattr__ or __getattribute__ aren't called. Question: are __getattr__
and __getattribute__ ever called on the metaclass? Why not/why not in
this case?
-- bjorn
> > From: Terry Reedy [mailto:tjreedy at udel.edu]
> >
> > "Bjorn Pettersen" <BPettersen at NAREX.com> wrote in message
> >
> > >>> class ff(str):
> > ... def foo(self):
> [...]
> > ... print 'super(ff, self)[0]', super(ff, self)[0]
> > ...
> > >>> f = ff('asdf')
> > >>> f.foo()
> > super(ff, self)[0]
> > Traceback (most recent call last):
> > File "<stdin>", line 1, in ?
> > File "<stdin>", line 5, in foo
> > TypeError: unsubscriptable object
> > ----------
> > I suspect that printing type(super(ff,self)) might answer your
> > question.
>
> I'm afraid not :-) I allready did that, and from what I can
> tell, this
> is the sequence that "should" happen:
>
> 1 super(ff, f)[0] # f == self
> 2 superinst(type:<class ff>, obj:f)[0]
> 3 si.__getitem__(0)
> 4 si.__getattr__('__getitem__')
> 5 .. return str.__dict__['__getitem__'].__get__(f)
> 6 boundmethod(str.__getitem__, f)
> 7 bmeth(0)
> 8 'a'
>
> well, the transition from 3 to 4 doesn't happen which surprised me a
> little. What surprised me more was that I couldn't get
> __getattribute__
> to be called either (neither in the class or its metaclass...
> I've only
> got 2.3a2, and I read a note about this not working before a4. Is this
> what is happening? If not, the only other reason I could see would be
> from the refMan 5.3.2, "The primary must evaluate to an object of a
> sequence or mapping type." If that is the case, then I still
> think it's
> a super bug, i.e. there is no reason super should assume that it's not
> "going to be" a sequence, in fact the direct superclass of ff _is_ a
> sequence. To fix it simply add:
>
> def __getitem__(self, v):
> m = self.__getattr__('__getitem__')
> return m(v)
>
> to the definition of super. This will change the exception to
> AttributeError if a superclass isn't a sequence. To keep the current
> semantics, add the lookup to only instances that are sequence proxies
> (example below, refactor between __getattr__ as desired...)
>
> -- bjorn
>
> class Super(object):
> def __init__(self, type, obj=None):
> self.__type__ = type
> self.__obj__ = obj
>
> if isinstance(self.__obj__, self.__type__):
> starttype = self.__obj__.__class__
> else:
> starttype = self.__obj__
> mro = iter(starttype.__mro__)
>
> for cls in mro:
> if cls is self.__type__:
> break
>
> for cls in mro:
> if '__getitem__' in cls.__dict__:
> def getitem(v):
> m = self.__getattr__('__getitem__')
> return m(v)
> self.__possibleGetitem = getitem
> break
>
> def __possibleGetitem(self, v):
> raise TypeError("unindexable object")
>
> def __getitem__(self, v):
> return self.__possibleGetitem(v)
>
> --
> http://mail.python.org/mailman/listinfo/python-list
>
More information about the Python-list
mailing list