[Python-ideas] [Python-Dev] python and super

Carl Meyer carl at oddbird.net
Fri Apr 15 18:42:18 CEST 2011


(Moving this thread to python-ideas, as it seems better suited for here).

On 04/15/2011 11:02 AM, Michael Foord wrote:
> Well yes, but it is also a bug in the copy of unittest2 embedded in
> django - so whilst it can be fixed in unittest2 (simply deleting the
> setUp and tearDown methods which do nothing but override
> unittest.TestCase.setUp and tearDown) it *also* needs to be fixed in
> django.

Yup.

> This particular issue does illustrate the problem well though - the
> methods in unittest2 don't call up to their parent class (which is fine
> because those methods are empty), but in not calling up also they
> prevent sibling methods being called in a multiple inheritance situation.
> 
> So for those who have been saying that not wanting to call up to parents
> is a valid use case, yes I quite agree.  But you have to be aware that
> because of the semantics of super, not calling up to your parents
> basically prevents those methods being used in the presence of multiple
> inheritance.

Right. I agree that the current behavior of super in that regard is
surprising, but I don't see how the "go ahead and call sibling methods
anyway" fix is plausible. What happens to the return value of that call?
There's nowhere for it to go - super() would have to somehow implicitly
integrate two different return values, which is all kinds of bad magic.
Consider these classes:

class UncooperativeBase:
    def method(self):
        # look Ma, no super() call!
        return ["UncooperativeBase"]


class OtherBase:
    def method(self):
        return ["OtherBase"] + super().method()


class Child(UncooperativeBase):
    def method(self):
        return ["Child"] + super().method()


class GrandChild(Child, OtherBase):
    def method(self):
        return ["GrandChild"] + super().method()


Currently, OtherBase.method() is never called, because
UncooperativeBase.method() breaks the super() chain. Any proposal to
have super() ensure that OtherBase.method() is called needs to explain
what exactly happens to its return value. This would normally be handled
explicitly by UncooperativeBase, since it would call super() and do
something with the return value. But with the explicit chain broken, you
end up with two different chains, and at some point their return values
would need integrating.

Carl



More information about the Python-ideas mailing list