# Python MRO

Amit Kumar |       @aktech |      me@iamit.in

v2.0

• SymPy Developer
• Mathematics and Computing undergrad
• Pythonista
• FOSS enthusiast!

# MRO

Method Resolution Order

defines the class search path used by Python to search for the right method to use in classes having multi-inheritance.

# MRO?

``````class A:
def whoami(self):
print("I am A")

class B(A):
def whoami(self):
print("I am B")

class C(A, B):
pass``````

# The Problem

``````object_c = C()
object_c.whoami()``````

?

# Solution

Two algorithms to find Method Resolution Order

Old MRO

New MRO

Old Classes

New Classes

(C3 Algorithm)

# Old Classes

``````class A :
pass
class B :
pass
class C(A, B) :
pass``````

# New Classes

``````class A(object) :
pass
class B(object) :
pass``````
• doesn't inherits from Python root object class.

• uses old mro algorithm
• first parent inherits from python root object class
• uses new mro algorithm
• introduced in python 2.3

(Brief History)

# 2002

It all started in

with a post by Samuele Pedroni to the Python development mailing list

Samuele Pedroni to the Python-dev mailing list.

There was a long discussion regarding this...

Guido after Discussion

# Python 2.2

The method resolution order is not monotonic

## What is Monotonic?

The mro of a subclass is an extension without re-ordering of the mros of the superclasses.

A

B

C

D

X

(C A B)

(D B A)

MRO of C

MRO of D

Subclass

A B or B A?

# NO!

Can't decide, right?

1            2               2                1

# MRO in Python3

• Inherits from 'object' implicitly
• uses new mro

## Old MRO algorithm

Deep first, from Left to Right

DLR

# Example:

``````class A:
def whoami(self):
print("I am A")

class B(A):
def whoami(self):
print("I am B")

class C(A):
def whoami(self):
print("I am C")

class D(B, C):
def whoami(self):
print("I am D")

d = D()
d.whoami()``````

Rule: DLR

D

B

A

C

A

D  B  A  C

Depth first, from left to right

(Remove duplicates from end)

# Summary

So in our example, algorithm search path is : D, B, A, C.

• Looking in D
• If not found, looking in B
• If not found, looking in B's first parent A
• If not found, going back in B others parents (none)
• If not found, looking in D's others parents : C

# The C3 Algorithm

(Linearization of a Class)

### Lets learn some notations first!

C1  C2  C3  C4  C5  C6  ........  CN

Head

Tail

• List of classes, head, tail

List of classes

• Sum of the list

### Lets learn some notations first!

C + (C1 C2 ... CN) = C C1 C2 ... CN

(Notation for adding two lists)

### The C3 Method Resolution Order

The list of the ancestors of a class C, including the class itself, ordered from the nearest ancestor to the furthest, is called the class precedence list or the linearization of C.

(Linearization of a Class C)

or

The MRO of C

### The C3 Method Resolution Order

How to find Linearization of a Class C?

or MRO of class C

The linearization of C is the sum of C plus the merge of the linearizations of the parents and the list of the parents.

L[C(B1 ... BN)] = C + merge(L[B1] ... L[BN], B1 ... BN)

### The C3 Method Resolution Order

Finding Merge

• take the head of the first list.

• if this head is not in the tail of any of the other lists, then add it to the linearization of C and remove it from the lists in the merge,

• otherwise look at the head of the next list and take it, if it is a good head.

• Then repeat the operation until all the class are removed or it is impossible to find good heads.

## Example

``````O = object
class F(O): pass
class E(O): pass
class D(O): pass
class C(D,F): pass
class B(D,E): pass
class A(B,C): pass``````

O

D

E

F

B

C

A

O

D

E

F

B

C

A

• L[O] = O
• L[D] = D O
• L[E] = E O
• L[F] = F O

## Example 1

O

D

E

F

B

C

A

L[B]  = B + merge(DO, EO, DE)

L[B]

= B +

merge(

L(D), L(E),

DE )

L[B]  = B + D + merge(O, EO, E)

L[B]  = B + D + E + merge(O, O)

L[B]  = B + D + E + O

L[B]  = B  D  E  O

L[O] = O | L[D] = D O | L[E] = E O | L[F] = F O

There is no tail

here

## Example 2

O

D

E

F

B

C

A

L[C] = C + merge(L[D], L[F], DF)

= C + D + merge(O, FO, F)

= C + D + F + merge(O,O)

= C D F O

= C + merge(DO, FO, DF)

L[O] = O | L[D] = D O | L[E] = E O | L[F] = F O

L[B]  = B  D  E  O

## Example 3

O

D

E

F

B

C

A

L[A] = A + merge(BDEO, CDFO,BC)

= A + B + merge(DEO, CDFO,C)

= A + B + C + merge(DEO, DFO)

= A + B + C + D + merge(EO, FO)

= A + B + C + D + E + merge(O, FO)

= A + B + C + D + E + F + merge(O, O)

= A B C D E F O

L[O] = O | L[D] = D O | L[E] = E O | L[F] = F O

L[B]  = B  D  E  O | L[C] = C D F O

# Thank You!

@iaktech       me@iamit.in

This work is licensed under a Creative Commons