datarekha
Python Medium Asked at GoogleAsked at MetaAsked at Stripe

How does Python's Method Resolution Order (MRO) work, and what is the C3 linearization algorithm?

The short answer

Python resolves method lookups by computing a linearized list of classes called the MRO using the C3 linearization algorithm, which guarantees that a class always appears before its parents and that the local precedence order declared in each class definition is preserved. You can inspect it via `ClassName.__mro__` or `ClassName.mro()`.

How to think about it

What the interviewer is really checking

MRO questions show up when interviewers probe whether you understand multiple inheritance — a corner of Python that’s easy to get wrong. The key is explaining why C3 exists (naive depth-first search breaks diamond inheritance) and being able to read the MRO of a class rather than reciting the algorithm mechanically.

The problem C3 solves

Before C3, Python used depth-first, left-to-right search. For diamond inheritance:

    A
   / \
  B   C
   \ /
    D

Depth-first would give D → B → A → C. This means if A defines a method, C’s override is never reachedA is visited before C. C3 fixes this by pushing base classes toward the end so all immediate subclasses are checked first.

C3 linearization — two rules

C3 merges the parent MROs while enforcing:

  1. A class always appears before all of its parents.
  2. The left-to-right order of bases in the class definition is preserved.

For class D(B, C) where both B and C inherit from A, the result is [D, B, C, A, object].

Working through the diamond example

Cooperative inheritance with super()

super() does not call “the parent class” — it calls the next class in the MRO. This enables the cooperative pattern above where every class in a chain calls the next without needing to know what it is:

class B(A):
    def greet(self) -> str:
        return "B+" + super().greet()  # calls C.greet next, not A.greet

class C(A):
    def greet(self) -> str:
        return "C+" + super().greet()  # calls A.greet

print(D().greet())  # "B+C+A"

The key insight

Without C3, multiple inheritance in Python was fragile. With C3, the MRO is deterministic and consistent. The practical takeaway: when you call super(), you are not calling your parent — you are calling the next class in the linearized MRO, which may be a sibling class you did not write. This is why every class in a cooperative hierarchy must call super().

Learn it properly Inheritance vs Composition

Keep practising

All Python questions

Explore further

Skip to content