cooperation of buitlin methods usingtsuper

Bengt Richter bokr at oz.net
Thu Jul 3 22:29:33 CEST 2003


On 3 Jul 2003 07:52:44 -0700, mis6 at pitt.edu (Michele Simionato) wrote:

>> In <2259b0e2.0307020855.478300c2 at posting.google.com> Michele Simionato wrote:
>> > Matthias Oberlaender <matthias.oberlaender at REMOVE.daimlerchrysler.com> 
>> wrote in message news:<bduh36$rgn$1 at news.sns-felb.debis.de>...> I would like  
>> to adopt the cooperation paradigm in conjunction with builtin 
>> > > methods and operators, such as len, iter, +, * etc. 
>> > 
>> > Fine.
>> > 
>> > > But the direct approach does not work with the current implementation of 
>> > > super. For example, 'len(super(Y, y)' will always result in 'len() of 
>> > > unsized object'.
>> > 
>> > Of course, it must give an error! I think you do not understand how 
>> > super works. But don't worry, that's quite common ;)
>> 
>> Oh, wait a minute. I think this "of course" is a bit presumptuous. 
>
>Uhm... I do realize now that what I wrote sounds quite presumptuous
>indeed.
>It was not my intention. The "of course" refers to the current
>implementation
>of ``super`` which does not do what you ask for. To me this was well
>known
>because of recent threads on the subject by Bjorn Pettersen:
>
>http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&frame=right&th=a385e6aa839a9538&seekm=2259b0e2.0304210750.5eaf5df0%40posting.google.com#link1
>
>http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&threadm=2259b0e2.0304300625.4e0ebace%40posting.google.com&rnum=3&prev=/groups%3Fhl%3Den%26lr%3D%26ie%3DISO-8859-1%26q%3Dsuper%2Bpettersen%26meta%3Dgroup%253Dcomp.lang.python.*
>
>You see that for sure you are not the only one who is confused about
>``super`` and there are dark corners about it. I myself do not know
>nothing about its
>implementation.
>
>> > 
>> > I think you should re-read the documentation and
>> > google on the newsgroup for 'super'. The use case
>> > for super is in multiple inheritance, as in this example:
>> > 
>> > class B(object):
>> >     def __len__(self):
>> >       print 'called B.__len__'   return 1111
>> >     
>> > class C(B):
>> >   def __len__(self):
>> >       print 'called C.__len__'
>> >       return super(C,self).__len__()
>> 
>> This is exactly the style of syntax I want to avoid! I'd rather write more 
>> concisely 'len(super(C,self))'.  
>
>I see now what's your point, which is the same of Pettersen: why 
>
>>>> class B(object):
>	def __len__(self): return 1111
>>>> class C(B): pass
>...
>>>> c=C()
>>>> super(C,c).__len__()
>1111
>
>works, whereas
>
>>>> len(super(C,c))
>Traceback (most recent call last):
>  File "<pyshell#7>", line 1, in ?
>    len(super(C,c))
>TypeError: len() of unsized object
>
>does not work? As you say, the reason is that
>
>> at least in Python 2.2.1, its is 
>> a matter of fact that builtins/special method names are treated differently 
>> from ordinary class methods in conjunction with super objects. Do you agree? 
>> My implementation of super seems to fix this gap. Perhaps there are some 
>> other people who would appreciate that too. Or are there good 
>> logical/conceptual reasons againts it? This is what I would like to know.
>
>BTW, the same is true for Python2.3b2. I always use the longest form
>of ``super``,so this problems does not bother me, nevertheless I
>understand
>your point.
>
>I think you should submit the issue to python-dev; maybe there are
>technical reasons such that it is necessary to treat special methods
>differently and this cannot be avoided. In such a case the
>documentation should report that
>only the long form ``super(C,c).__len__()`` is correct and that users
>should
>not use ``len(super(C,c))`` (idem for other special methods).
>
>I would also submit a bug report on sourceforge, since at the best
>this is
>a documentation bug. It does not seem to have been reported before and
>has
>already bitten at least two persons on c.l.py., therefore it should be
>made
>known to the developers  
>
ISTM (and I don't know super much) that in the above, if you factor out
    x = super(C,c)
and then compare
    len(x)
vs
    x.__len__()

then the results above suggest that implementation is not
    getattr(x,'__len__')()
but effectively more like
    getattr(x.__class__,'__len__')(x)

Note:

 >>> class B(object):
 ...     def __len__(self): return 1111
 ...
 >>> class C(B): pass
 ...
 >>> c=C()
 >>> super(C,c).__len__()
 1111
 >>> len(super(C,c))
 Traceback (most recent call last):
   File "<stdin>", line 1, in ?
 TypeError: len() of unsized object

Ok, now let's look at c vs x:

 >>> getattr(c,'__len__')()
 1111
 >>> getattr(c.__class__,'__len__')(c)
 1111

vs

 >>> getattr(x,'__len__')()
 1111
 >>> getattr(x.__class__,'__len__')(x)
 Traceback (most recent call last):
  File "<stdin>", line 1, in ?
 AttributeError: type object 'super' has no attribute '__len__'

I guess generally continuing a failed method lookup in x.__class__.__dict__ or equivalent
and trying to find it as an instance attribute might make this super problem
work, but weren't instance methods intentionally bypassed for the new style?

That would mean solving the problem specifically in super somehow, but how? I guess by
fiddling with lookup of methods of/via super instances? I guess it could be done in C.
I'll have to look in typeobject.c more sometime. It looks already tricky ;-)

Regards,
Bengt Richter




More information about the Python-list mailing list