What causes Python's "Cannot create a consistent method resolution order" TypeError?
answer
- Two ordering rules in contradiction
- Raised while the class statement runs
- A base listed ahead of its own subclass
- Message names the ancestors in conflict
- Derived first, generic last
basics
~20 sThe base list demands two contradictory orderings. Writing class C(A, B) when B already subclasses A asks for A before B, while B must precede its own base — no consistent order exists, so class creation fails.
solid answer
~40 sPython linearizes a class at creation time under two constraints: the direct bases keep the order written in the class statement, and no class may appear before one of its own subclasses. When those conflict, there is no valid order, and rather than guessing Python raises `TypeError: Cannot create a consistent method resolution order (MRO) for bases ...` while the class statement executes — so it surfaces at import, not at call time. The textbook trigger is `class C(A, B)` where `B` is already a subclass of `A`: the base order wants A first, inheritance wants B first. The mechanical fix is to list the more derived class first, `class C(B, A)`. It also fires when two bases order shared ancestors incompatibly — one inherits `(A, B)`, the other `(B, A)`.
code
python · 13 linesclass A: pass
class B(A): pass
try:
class C(A, B):
pass
except TypeError as exc:
print(exc)
class C(B, A):
pass
print([c.__name__ for c in C.__mro__])go deeper
Recognise the message and know the common cause: a base class listed ahead of one of its own subclasses. Reordering the bases so the more derived class comes first usually clears it.
Explain the two ordering rules that collide, state that the error is raised while the class statement executes, and read the class names in the message as the ancestors in conflict rather than as your bases.
Show you can diagnose the upstream case — two bases linearizing shared ancestors in opposite directions — by comparing their MROs, and that you treat it as a design signal to delegate rather than a reordering puzzle.
Own the position that failing loudly at import is preferable to a silently chosen order, and that hierarchies producing these conflicts are telling you the inheritance graph, not the base list, needs changing.
### What the error actually means At class creation the interpreter tries to produce a single linear order over the new class and all of its ancestors, subject to two constraints: * **Local precedence order** — the direct bases appear in the order written in the class statement. * **Monotonicity** — the new order is consistent with every base's own order, which in particular means no class ever precedes one of its own subclasses. If no sequence satisfies all of the constraints simultaneously, the algorithm has nothing valid to return, and Python refuses to build the class: ```python class A: pass class B(A): pass class C(A, B): # TypeError pass ``` The base list says A comes before B. B's own inheritance says B comes before A. Both cannot hold, so the class statement raises `TypeError: Cannot create a consistent method resolution order (MRO) for bases A, B` and no class object is created. Note *when* this happens: while the class statement runs — i.e. at import time for a module-level class — not when a method is called and not when an instance is made. A single bad base list can therefore take down a whole import. ### The two shapes you actually meet **A base listed before its own subclass.** Usually a refactor artefact: a class that used to be a sibling becomes a subclass, and a base list somewhere else silently becomes illegal. Consider a route-optimisation job whose planner mixes in an ETA formatter and a locale-dependent formatter. It worked while the two were independent; the moment the locale class is made a subclass of the plain formatter, `class Planner(Formatter, LocaleFormatter)` stops importing. The fix is mechanical: list the more derived class first, `class Planner(LocaleFormatter, Formatter)`, which is also the order that actually gives the specialised behaviour precedence. **Two bases that order shared ancestors differently.** ```python class A: pass class B: pass class X(A, B): pass class Y(B, A): pass class Z(X, Y): # TypeError: ... for bases A, B pass ``` Here neither base list is wrong on its own, but X insists A precedes B while Y insists the reverse, and Z would have to honour both. The error message names the pair of *ancestors* it could not order — A and B — rather than the bases you wrote, which is the single most useful piece of information in the message: it tells you exactly which two classes are in disagreement, not merely that something is wrong. ### How to diagnose it 1. Read the two class names in the message; they are the ancestors in conflict, not necessarily the classes in your base list. 2. Print the MRO of each base — `[c.__name__ for c in X.__mro__]` — and find where the two disagree about the relative order of the named pair. 3. If the conflict is "a class and its own subclass in one base list", reorder: derived first, generic last. 4. If two bases genuinely disagree about shared ancestors, no reordering of *this* class's bases can help — the contradiction lives upstream. Change one of the upstream base lists so the two agree, or stop inheriting from both and delegate to one instead. ### Why refusing is the right behaviour Python could pick some order and move on. It does not, because every alternative is worse: silently dropping local precedence would make base order meaningless, and silently dropping monotonicity would let a class be shadowed by the very base it overrides, so an override would vanish depending on which subclass you looked from. A loud failure at import beats a hierarchy whose behaviour changes by inheritance path, and it is a compile-time-ish guarantee: if the class object exists, its lookup order is coherent. One practical corollary: this error is a design signal, not just a syntax nuisance. Two bases that disagree about their shared ancestors have effectively been designed as alternatives to one another, and combining them is not a reordering problem. That is the point to consider holding one as an attribute and delegating instead of inheriting from both. ### Guarding against it Because the failure is at class creation, an import of every module is a complete check — no test needs to call anything. That makes it worth having a test that simply imports the package, especially in a codebase with mixins, since the classic trigger is a refactor elsewhere: one class quietly becomes a subclass of another and every base list that mentioned both in the old order becomes illegal at once. Before writing a base list with two related classes, `issubclass(B, A)` answers whether one must come first. And note what the error is *not*: it is not a name clash, not a complaint about diamonds — an ordinary diamond linearizes fine — and not something a metaclass fixes, since a metaclass conflict raises a different error about metaclasses entirely.
- At what moment is this TypeError raised, and why does that matter operationally?While the class statement executes, which for a module-level class means at import. The class object is never created, so the failure takes out the whole module rather than one code path. A test that merely imports the package catches it, which is why it is cheap to guard against.
- The message names two classes you never listed as bases. What does that tell you?It names the pair of ancestors whose relative order could not be reconciled. Two of your bases linearize that pair in opposite directions. Print each base's `__mro__`, find the two conflicting positions, and fix the upstream base list — reordering the failing class's own bases will not help.
- Is there a case where no reordering of the bases can fix it?Yes — when two bases genuinely disagree about shared ancestors, as with one inheriting `(A, B)` and another `(B, A)`. The contradiction is upstream, so either make the two agree or stop inheriting from both and hold one as a collaborator you delegate to instead.
saying these in an interview costs you the question
- Thinks it fires when a method is first called
- Says any diamond inheritance triggers it
- Believes adding a metaclass resolves the conflict
- Claims the two named classes are always the direct bases
- Suggests deleting or reassigning `__mro__` as the fix