MRO inconsistency: why?

Terry Reedy tjreedy at udel.edu
Wed Oct 8 15:49:38 EDT 2008


Ravi wrote:
> Why the following code gives inconsistent method resolution order 
> error:
> 
> class X(object): x = 4 def f(self): print 'f in X' print dir(X) 
> X.g(self) def g(self): print 'g in X'
> 
> class Y(object, X): def g(self): print 'g in Y'
> 
> o = Y() o.f()

Calculating a linear MRO from a non-tree inheritance graph is a fairly
arcane subject.  Here, I believe, are the two rule relevant here:
1. Direct superclass must remain in the same order as in the class header.
2. A class cannot appear before any of its subclasses.
Violation of these rules can lead to unexpected anomalies.

(object, X) violates rule 2.
(X, object) violates rule 1.
There are no other possible orders.

The only reason to add object to the header first would be if you want Y 
to only inherit new methods defined in X but not object methods 
redefined in X.  To do that, define a class Z that at least copies from 
object those redefined methods and "class Y(Z,X)" should work.

> While this code doesn't:
> 
> class X(object): x = 4 def f(self): print 'f in X' print dir(X) 
> X.g(self) def g(self): print 'g in X'
> 
> class Y(X, object): def g(self): print 'g in Y'
> 
> o = Y() o.f()

(X, object) satifies both rules.  That said, putting object in the class 
Y header is redundant since object would follow X in the MRO anyway!

Terry Jan Reedy




More information about the Python-list mailing list