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