From: Brian Victor on
Steven D'Aprano wrote:
> On Sat, 31 Jul 2010 14:25:39 +1200, Gregory Ewing wrote:
>
>> Steven D'Aprano wrote:
>>
>>> A
>>> / \
>>> C B
>>> \ /
>>> D
>>> / \
>>> E F
>>>
>>> Yes, a super call might jog left from C to B, but only when being
>>> called from one of the lower classes D-F. That's still an upwards call
>>> relative to the originator, not sidewards.
>>
>> But it's not an upward call relative to the class mentioned in the
>> super() call, which is why I say it's misleading.
>
> Which class would that be?
>
> I think I'm going to need an example that demonstrates what you mean,
> because I can't make heads or tails of it. Are you suggesting that a call
> to super(C, self).method() from within C might call B.method(self)?

Yes, it would.

class A(object):
def test_mro(self):
print "In A"

class B(A):
def test_mro(self):
print "In B"
super(B, self).test_mro()
raise Exception()

class C(A):
def test_mro(self):
print "In C"
super(C, self).test_mro()

class D(C, B):
def test_mro(self):
print "In D"
super(D, self).test_mro()

D().test_mro()

Notice the exception being raised in B. This results in the following traceback:

Traceback (most recent call last):
File "mro.py", line 21, in <module>
D().test_mro()
File "mro.py", line 19, in test_mro
super(D, self).test_mro()
File "mro.py", line 14, in test_mro
super(C, self).test_mro()
File "mro.py", line 9, in test_mro
raise Exception()
Exception

Since the idea of super() as I understand it is to make sure every class
in an object's hierarchy gets its method called, there's really no way
to implement super() in a way that didn't involve a non-superclass being
called by some class's super() call.

--
Brian

From: Ian Kelly on
On Sat, Jul 31, 2010 at 4:22 AM, Steven D'Aprano
<steve(a)remove-this-cybersource.com.au> wrote:
> On Fri, 30 Jul 2010 21:40:21 -0600, Ian Kelly wrote:
>
>> I have to chime in and agree that the name "super" is problematic. I'm
>> reading this thread with a sense of alarm because I apparently never
>> read the super() documentation too closely (why would I?  "Oh, it just
>> accesses an attribute from a superclass.  Moving on.") and have been
>> writing code for the past four years under the impression that super()
>> will always refer to a superclass of the current class.
>
> In Python 2.x, super() doesn't know what the current class is. You have
> to explicitly tell it. If you tell it a lie, surprising things will
> happen.
>
> Assuming you accurately tell it the current class, can you give an
> example where super() doesn't refer to a superclass of the current class?

Brian gave a good example, so I refer you to that.

>> On a tangent, is it just me, or is the super() documentation incorrect,
>> or at least unclear?  Quoting from the first two paragraphs:
>
> Yes, it's a bit unclear, because it's a complex function for dealing with
> a complicated situation. But if you have single inheritance, it's simple.
> Anywhere you would write
>
> class C(B):
>    def method(self, *args):
>        B.method(*args)
>
> you can write
>
> class C(B):
>    def method(self, *args):
>        super(C, self).method(*args)
>
>
> and it will Just Work.

Until somebody else comes along and creates class E that inherits from
both C and D and also uses super(), and now suddenly the super() call
in C becomes equivalent to "D.method(*args)" instead for instances of
E, potentially with unexpected results. Or worse, E.method
incorrectly calls both C.method and D.method explicitly, and now
D.method gets invoked twice, once implicitly from C.method, and once
explicitly from E.method.

I realize that it is the responsibility of the person writing class E
to make sure they're working with class C correctly, but in order for
them to do that, ultimately every method in class C should be
documented as to whether it calls super() or not, and if so whether it
is designed only for single inheritance or with the MRO in mind. That
really shouldn't be necessary, and in my current view from a
maintenance perspective, best practice is to only use super() in the
multiple-inheritance scenarios it was specifically designed for

>> super(type[, object-or-type])
>>
>>     Return a proxy object that delegates method calls to a parent or
>> sibling class of type.
>
> I think that the bit about sibling class refers to super(type, type2)
> calls, rather than the super(type, instance) calls which I've been
> discussing. I've never needed, and don't understand, the two type version
> of super(), so I can't comment on it.

I understand the two-type version works the same way, but is intended
for class methods, like so:

class A(object):
@classmethod
def f(cls, *args):
print "A.f"

class B(A):
@classmethod
def f(cls, *args):
print "B.f"
return super(B, cls).f(*args)

class C(A):
@classmethod
def f(cls, *args):
print "C.f"
return super(C, cls).f(*args)

class D(B, C):
@classmethod
def f(cls, *args):
print "D.f"
return super(D, cls).f(*args)

Cheers,
Ian
From: Jean-Michel Pichavant on
Paul Rubin wrote:
> Michele Simionato <michele.simionato(a)gmail.com> writes:
>
>> I am actually more radical than that. From
>> http://www.artima.com/weblogs/viewpost.jsp?thread=237121:
>> In this series I have argued that super is tricky; I think nobody can...
>>
>
> When I look at that URL, I see a Java stack dump:
>
> java.lang.RuntimeException: com.jivesoftware.forum.ForumThreadNotFoundException: ID -1 is not valid
> at com.artima.jivecoupled.skins.weblogs.ViewPostPage.process(ViewPostPage.java:112)
> ...
>
> Seems appropriate.
>
remove the ending double dot.

JM
From: Mark Lawrence on
On 02/08/2010 10:23, Jean-Michel Pichavant wrote:
> Paul Rubin wrote:
>> Michele Simionato <michele.simionato(a)gmail.com> writes:
>>> I am actually more radical than that. From
>>> http://www.artima.com/weblogs/viewpost.jsp?thread=237121:
>>> In this series I have argued that super is tricky; I think nobody can...
>>
>> When I look at that URL, I see a Java stack dump:
>>
>> java.lang.RuntimeException:
>> com.jivesoftware.forum.ForumThreadNotFoundException: ID -1 is not valid
>> at
>> com.artima.jivecoupled.skins.weblogs.ViewPostPage.process(ViewPostPage.java:112)
>>
>> ...
>>
>> Seems appropriate.
> remove the ending double dot.
>
> JM

aka the colon. :)

Cheers.

Mark Lawrence

From: Mark Lawrence on
On 02/08/2010 07:15, Michele Simionato wrote:
> On Jul 31, 5:08 am, Steven D'Aprano<st...(a)REMOVE-THIS-
> cybersource.com.au> wrote:
>> I have read Michelle Simionato's articles on super in Python.
>
> One "l" please! I am a man! ;-)
>
Please prove it, get your bits out!!! :)
>
> M. Simionato