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

Nick Coghlan ncoghlan at gmail.com
Sun Apr 17 15:09:15 CEST 2011


On Sun, Apr 17, 2011 at 3:22 AM, Michael Foord
<fuzzyman at voidspace.org.uk> wrote:
>
> No, not as I described. Where a method does not call up to its parent class
> then super would *not* auto call the parent class (I'm *not* suggesting a
> fully auto-call super as the original poster did), but a method not calling
> super still wouldn't halt the chain of calls. To achieve this a call into a
> method that doesn't call super (and would normally end the chain) instead
> removes itself and its unique parents [1] from the mro for this call.
>
> It would make the semantics more complex, but it would solve this problem
> and the original posters problem. For this specific example, if no classes
> call up to object.__init__ then it won't be called. It would permit you to
> have methods that can participate in multiple inheritance whilst still
> blocking calls (overriding) up to their parent classes.

Could you elaborate on the MRO data structure and super()
implementation changes you would propose in order to actually make it
possible to implement this idea?

The current MRO is calculated as a linear list at class definition
time (using the C3 algorithm), throwing away a lot of the original
tree information regarding the actual structure of the classes.

For example, the MRO "C, B, A, object" could come from a class
hierarchy that looked like:

class A: ...
class B(A): ...
class C(B): ...

Or one that looked like:

class A: ...
class B(A): ...
class C(B, A): ...

Or one that looked like:
class A: ...
class B: ...
class C(B, A): ...

If you add a "class D(C, B)" to the bottom of that hierarchy, then any
one of those 3 structures could apply across the parent classes, but D
would have the same MRO (i.e. "D, C, B, A, object"). And, of course,
there are now even *more* scenarios that could produce the same MRO
for D.

So if the only information you have available is D's MRO (which is the
current situation for super()), then you *don't know* whether B is C's
parent, sibling or both - the calculation of the MRO discards too much
detail about the class hierarchy.

Creating a dynamic MRO for every single method call just so people can
fail to think correctly about cooperative super() designs is a huge
price to pay to gain something that probably won't help in practice.

Auto-chaining of super calls just opens up a whole can of worms, and
if it can even be done at all, I definitely don't see how it could be
done in a backwards compatible way.

Cheers,
Nick.

-- 
Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia



More information about the Python-ideas mailing list