Let’s figure out why this Python code raises a TypeError:
class A:
def process(self):
print("From: A")
class B(A):
def process(self):
print("From: B")
super().process()
class C(A):
def process(self):
print("From: C")
super().process()
class First(B, C): pass
class Second(C, B): pass
class Combined(First, Second): pass # TypeError- MRO stands for Method Resolution Order. It’s the sequence Python uses to look for methods or attributes in a class and its parents. For example, if
Combinedneeds a method, Python follows the MRO to decide where to look first, second, and so on. - When a class inherits from multiple parents (like
FirstandSecondhere), Python uses an algorithm called C3 linearization to build this sequence. It has to be consistent and make sense. - In C3, we merge lists (the MROs of the parent classes plus the list of parents) into one order. Each list has a head (the first item) and a tail (everything after the head). The rule is: Pick a head only if it’s not in any other list’s tail. If we can’t pick anything, the merge fails, and we get a
TypeError.
let’s figure out the MROs for its parents: First and Second.
-
Firstisclass First(B, C):- It inherits from
BandC, in that order. Binherits fromA.Cinherits fromA.- Python starts with
First, then follows the order of parents:B, thenC, thenA(since bothBandClead toA), and finallyobject(the ultimate base class in Python). - So, the MRO is:
[First, B, C, A, object].
- It inherits from
-
Secondisclass Second(C, B):- It inherits from
CandB, in that order. Cinherits fromA.Binherits fromA.- Starting with
Second, it goesC, thenB, thenA, andobject. - So, the MRO is:
[Second, C, B, A, object].
- It inherits from
Notice the difference: First has B before C, while Second has C before B.
Now, Combined is defined as class Combined(First, Second). Python needs to build its MRO by merging:
- The MRO of
First:[First, B, C, A, object] - The MRO of
Second:[Second, C, B, A, object] - The list of parents:
[First, Second]
The MRO starts with Combined, then merges these three lists using the C3 rule. Let’s do it step by step:
L1 = [First, B, C, A, object] # MRO of First
L2 = [Second, C, B, A, object] # MRO of Second
L3 = [First, Second] # Parents of Combined
- Heads:
First(L1),Second(L2),First(L3). - Check
First:- Tail of L1:
[B, C, A, object]→ noFirst. - Tail of L2:
[C, B, A, object]→ noFirst. - Tail of L3:
[Second]→ noFirst. Firstisn’t in any tail, so pick it.
- Tail of L1:
- New MRO:
[Combined, First]. - Update lists:
L1 = [B, C, A, object] L2 = [Second, C, B, A, object] L3 = [Second]
- Heads:
B(L1),Second(L2),Second(L3). - Check
B:- Tail of L1:
[C, A, object]→ noB. - Tail of L2:
[C, B, A, object]→ hasB. - Tail of L3:
[]→ noB. Bis in L2’s tail, so we can’t pick it.
- Tail of L1:
- Check
Second:- Tail of L1:
[C, A, object]→ noSecond. - Tail of L2:
[C, B, A, object]→ noSecond. - Tail of L3:
[]→ noSecond. Secondisn’t in any tail, so pick it.
- Tail of L1:
- New MRO:
[Combined, First, Second]. - Update lists:
L1 = [B, C, A, object] L2 = [C, B, A, object] L3 = [] # Empty now
- Heads:
B(L1),C(L2). (L3 is empty, so ignore it.) - Check
B:- Tail of L1:
[C, A, object]→ noB. - Tail of L2:
[B, A, object]→ hasB. Bis in L2’s tail, so we can’t pick it.
- Tail of L1:
- Check
C:- Tail of L1:
[C, A, object]→ hasC. - Tail of L2:
[B, A, object]→ noC. Cis in L1’s tail, so we can’t pick it.
- Tail of L1:
Bcan’t be picked because it’s in L2’s tail ([B, A, object]).Ccan’t be picked because it’s in L1’s tail ([C, A, object]).- There’s no head we can choose! The merge gets stuck.
Python’s C3 algorithm fails when it can’t find a consistent order. Here:
FirstwantsBbeforeC(from[First, B, C, A, object]).SecondwantsCbeforeB(from[Second, C, B, A, object]).Combinedinherits from both, butBandCcan’t agree on who comes first, and neither can be skipped or ignored.
Since Python can’t resolve this conflict, it raises:
TypeError: Cannot create a consistent method resolution order (MRO) for bases First, Second
Bones: Java doesn't support multiple inheritance specifically to avoid the complexity and ambiguity caused by the Diamond Problem.