Metaclasses: the six steps of class creation, which show what a metaclass is for and what no longer needs one
A metaclass is the type of a class, and the whole protocol follows from that alone. The order of the steps is scattered across three sections of the documentation; collected into one column it answers every practical question at once — including the one that makes most metaclasses unnecessary.
Full technical treatment
TL;DR
A class has a type too, and that type is type. An object is an instance
of its class; a class is an instance of its metaclass. A metaclass governs how
classes are created in much the same way a class governs how instances are
created. The language has no separate entity for this: to write your own
metaclass you subclass type.
Hence the main consequence: Class(...) is a call on an instance of the
metaclass, which is why instance creation is intercepted on the metaclass
rather than on the class. And creating a class is itself a chain of steps whose
order matters more than the list: __set_name__ on descriptors and
__init_subclass__ on the parent are called inside the creation of the
class object, that is, before the metaclass's __init__, while a class
decorator runs after everything else. The real price of a metaclass is also not
the one expected: not time, but a metaclass conflict raised for someone who
never chose your metaclass.
Beyond that is what separates knowing from having read. There are six steps:
Meta.__prepare__— hands out the mapping for the body- the class body runs
Meta.__new__— the class object is created__set_name__on descriptors ← insidetype.__new____init_subclass__on the parent ← insidetype.__new__Meta.__init__
Steps 4 and 5 happen inside the third, that is, before the sixth. A metaclass by
itself costs nothing: a class with an empty metaclass is created in 7.09 µs
against 6.98 µs without one. The one thing charged for is intercepting
__call__: 223.3 ns per instance against 59.6 (3.13.7). Which is why, since 3.6
(PEP 487), most tasks are solved with __init_subclass__ and __set_name__. A
metaclass is still needed when you must intercept the execution of the class
body or instance creation.
- how a class is declared and how an instance is made from it;
- that one class can inherit from another;
- that a class in Python is a value like a number or a string: it can be stored in a variable and passed to a function;
- that a decorator is a function that receives an object and returns an object.
typeas a metaclass,__prepare__,type.__new__,__init_subclass__,__set_name__;- descriptors, the method resolution order, metaclass conflicts, PEP 487.
Base: a class has a type too
The word "metaclass" frightens people more than it should, and nearly always because of one skipped step. The step is this: a class has a type too.
For objects this is familiar. Write x = 5 and x has a type, int. Declare
class Order and make order = Order(), and order has a type, Order. The
question nobody asks: what is the type of Order itself?
The answer is type. A class is an object like a number or a string, and it has
a type as well. That type of a class is what a metaclass is.
From there the model fits into two lines, and these are the two to remember:
- an object is an instance of its class;
- a class is an instance of its metaclass.
Hence the junior-level answer, sayable in an interview as it stands: a metaclass governs how classes are created in much the same way a class governs how instances are created. A class decides what an object will be like; a metaclass decides what a class will be like.
That level is enough. If an interview asks "what is a metaclass", the answer above is a correct answer rather than a simplified one: it distorts nothing and promises nothing beyond what is there, and there is no obligation to go further. That is not why this lesson is marked advanced. Everything below is about which steps "creating a class" is made of, where each of them can be interfered with, and why in practice interfering is almost never necessary.
Mechanism 1: a class is an instance of its metaclass, and the protocol follows
One line checks it — and shows that the chain stops at type:
class Plain:
pass
print(type(Plain)) # <class 'type'>
print(type(type)) # <class 'type'>Plain is an object. Its type is type. A metaclass is simply a type whose
instances are classes; to write one you subclass type. The language has no
separate “metaclass” entity at all.
Something non-obvious follows immediately: Class(...) is a call on an
instance of the metaclass. That is why instance creation is intercepted by
defining __call__ on the metaclass rather than on the class. This is exactly
how singletons are made:
class Singleton(type):
_instances = {}
def __call__(cls, *args, **kwargs):
if cls not in cls._instances:
cls._instances[cls] = super().__call__(*args, **kwargs)
return cls._instances[cls]Mechanism 2: six steps, and the order matters more than the list
The reference lists the steps briefly.
When a class definition is executed, the following steps occur: MRO entries are
resolved; the appropriate metaclass is determined; the class namespace is
prepared; the class body is executed; the class object is created.
And the two most useful hooks are described elsewhere, in a different section — which is exactly why their place in the order usually gets guessed at.
The type.__new__ method collects all of the attributes in the class namespace
that define a __set_name__ method; Those __set_name__ methods are called
with the class being defined and the assigned name of that particular
attribute; The __init_subclass__ hook is called on the immediate parent of
the new class in its method resolution order.
The key part is whose action this is: both hooks are called by type.__new__
itself, which means they happen inside the third step rather than after
it.
What follows in practice:
__init_subclass__will not see what the metaclass does in__init__— that step is still ahead. The metaclass in__init__, on the other hand, already sees the result of both hooks.- The name, the bases and the namespace can be changed only up to the third step. After that they stop being arguments and become properties of an existing class.
- A class decorator runs last, when everything is already in place: "After the class object is created, it is passed to the class decorators included in the class definition."
What "last" means for a class decorator
From "runs last" it is easy to derive "and therefore can do nothing", which is
wrong. It receives a finished class object — and with a finished class you
can do almost anything. A run of bench/metaclass/decorator_capabilities.py:
__name__ after the decorator Renamed
the new attribute is visible added by the decorator
the decorator returned another class: its name Replacement
a class on object: __bases__ = (Base,) TypeError
a class on Base: __bases__ = (Another,) Another
Rename it — it can. Add and rewrite attributes — it can. Return an entirely
different object in place of the class, so the name in the module binds to that
instead — it can do that too. Bases are trickier, but the restriction is not
about decorators: assigning __bases__ is not always allowed (on a class
inheriting straight from object it raises TypeError), and that is a rule of
type itself, not a consequence of when the decorator runs.
The real boundary runs somewhere else — through time, not power:
before type.__new__ | the finished class | |
|---|---|---|
__prepare__: the mapping the body is written into | metaclass | — |
the arguments of type.__new__ (name, bases, namespace) | metaclass | — |
what __set_name__ and __init_subclass__ will see | metaclass | — |
| attributes, the name, replacing the object entirely | metaclass | decorator |
The same run prints the order of events, and in it the class body is executed
in the mapping from __prepare__ long before the decorator:
__prepare__ supplied its own mapping
the namespace is given 'a'
the namespace is given 'b'
Meta.__new__ sees the names: ['a', 'b']
decorator: the body has already run, the class is assembled
Mechanism 3: what only a metaclass can do
Three things, and all three follow from the order.
First — intercept the execution of the class body. __prepare__ hands out
the mapping the body will be written into, and therefore sees each assignment
separately. Nothing else can do this: by the time __init_subclass__ runs the
body has already executed and only the result is available.
class NoDuplicates(dict):
def __setitem__(self, key, value):
if key in self:
raise TypeError(f"the name {key!r} is defined twice in the class body")
super().__setitem__(key, value)
class StrictMeta(type):
@classmethod
def __prepare__(mcls, name, bases, **kwargs):
return NoDuplicates()An ordinary class accepts a duplicated name silently — the last assignment
simply wins. With this metaclass you get a TypeError while the class is being
defined.
Second — intercept instance creation through __call__. This is what
singletons, instance caches and substituting the returned object are built on.
Third — substitute the name, the bases or the namespace. All three are
arguments to Meta.__new__, that is, to the third step; by the time
__init_subclass__ runs — let alone the decorator — the class already exists
and it is too late.
Everything else people reach for a metaclass to do — registering subclasses, checking required attributes, giving descriptors their names — is covered by the two hooks from PEP 487.
The row about the name, the bases and the namespace deserves a precise reading. It is about them as arguments of class creation: only a metaclass can slip its own mapping under the body, or substitute the name or the bases before the class is assembled. A finished class a decorator will happily rename — the run above shows it doing so. The boundary between the two tools runs through time, not through power.
Mechanism 4: the boundary of __init_subclass__
The hook is called on the parent when a child is created. The reference compares it with a decorator directly:
This is closely related to class decorators, but where class decorators only
affect the specific class they're applied to, __init_subclass__ solely applies
to future subclasses of the class defining the method.
The word "future" is the boundary:
class Registry:
registered = []
def __init_subclass__(cls, **kwargs):
super().__init_subclass__(**kwargs)
Registry.registered.append(cls.__name__)
class First(Registry): pass
class Second(Registry): pass
print(Registry.registered) # ['First', 'Second'] — Registry itself is absentA metaclass, by contrast, fires for the class that named it too:
Meta.__new__ runs for the base class exactly as it does for the subclasses.
If a registry must include the base class, that is one of the few reasons to
take a metaclass.
One more thing: super().__init_subclass__(**kwargs) on the first line is not
a formality. Without it the nearest parent's hook runs and every class further along the
MRO is skipped — silently, with no error and no warning.
Deeper: what a metaclass actually costs
__call__, not for having a metaclass.Not time. A class with an empty metaclass is created in 7.09 µs against 6.98 µs without one (3.13.7, best of seven runs) — a difference within the noise, and paid once per class rather than per instance.
Time is charged for exactly one thing: intercepting __call__ adds a Python
method call to a path that otherwise runs entirely in C. 223.3 ns per
instance against 59.6 — 3.7 times, on every creation. The measurement is on
an empty class, so the addition here is a constant: on a class that actually
does something in __init__ the same overhead weighs noticeably less. A singleton
built with a metaclass pays that on every access, including the ones where the
object already exists.
The real price is this one:
The most derived metaclass is one which is a subtype of all of these candidate
metaclasses. If none of the candidate metaclasses meets that criterion, then the
class definition will fail with TypeError.
TypeError: metaclass conflict: the metaclass of a derived class must be
a (non-strict) subclass of the metaclasses of all its bases
Note where the error appears: in someone else's file, for whoever writes
the subclass and never chose your metaclass. All they wanted was to inherit
from your class and from something else with a metaclass of its own — ABC,
say, or Enum. They can fix it in two ways only: by not inheriting, or by
writing a third metaclass that merges the other two.
How to answer in an interview
The short answer: a metaclass is the type of a class. A class is an instance
of its metaclass exactly as an object is an instance of its class, and a
metaclass governs how classes are created in much the same way a class governs
how instances are created. Hence Class(...) calling the metaclass's
__call__: the class is its instance.
That is enough for a correct answer. What follows is what you add when the interviewer digs.
If the interviewer digs deeper
On its own a metaclass can do two things nothing else can: intercept the
execution of the class body through __prepare__, and intercept instance
creation through __call__. The commonest tasks — registering subclasses,
validating their fields, giving a descriptor its name — have been done since 3.6
with __init_subclass__ and __set_name__, more cheaply and without a metaclass
conflict. That is design advice, not an equality of powers: preparing the
namespace, replacing the bases and intercepting instance creation stay with the
metaclass alone.
One phrasing that is easy to get wrong out loud concerns the class decorator.
"A decorator cannot replace the class" is false: replacing it is exactly what it
may do — it is free to return a different object in the class's place, and the
name in the module binds to that. Its boundary lies elsewhere: it takes no
part in creating the class. The mapping the body ran in, and the arguments of
type.__new__, are history by the time it arrives, and it cannot influence what
__set_name__ and __init_subclass__ will see. The difference between it and a
metaclass is when it intervenes, not how much it can do.
If asked "when did you last write a metaclass", the honest answer is usually "I haven't", and it is the right one. A good sign the question is understood: name the conflict, not the runtime cost, as the price, and add that the one who pays it is someone else's code. And keep the boundary on the measurements: 7.09 against 6.98 µs and 223.3 against 59.6 ns were taken on one machine and on an empty class (3.13.7) — what they carry is not the number but what exactly is being charged for.
Next they ask
Could all of this be done with __init_subclass__ instead?
Almost everything usually wanted, yes — and then a metaclass is unnecessary. The
boundary is where you need to intervene in the creation of the class itself
rather than react to an already-created subclass: __init_subclass__ runs when
the class is already assembled.
Does a metaclass slow down working with the class?
By itself, no; it charges at class creation, not at attribute access. What slows things down is a specific act, not the presence of a metaclass — and the lesson separates the two by measurement.
Common misconceptions
Metaclasses are slow
Creating a class with an empty metaclass takes 7.09 µs against 6.98 without one — a difference within the noise, paid once per class. Time is charged only for intercepting __call__: 223.3 ns per instance against 59.6 (3.13.7), that is, 3.7 times, and that on EVERY creation. The real price of a metaclass is not in time at all but in the metaclass conflict raised in someone else's code.
__init_subclass__ is simply a convenient replacement for a metaclass
A replacement in the most common cases, but not a complete one. It does not fire for the class it is declared on — a base class never lands in its own registry. It takes no part in creating the class: the namespace the body runs in, and the arguments of type.__new__, are behind it by the time it is called (changing attributes of the finished class it can do, just as a decorator can). And it does not see the body executing: __prepare__ belongs to metaclasses alone.
__set_name__ and __init_subclass__ run after the class is finished
They run INSIDE type.__new__, that is, between the creation of the class object and Meta.__init__. This is written in the reference and can be checked with a counter. Hence the practical answer: __init_subclass__ will not see what the metaclass does in __init__ — while a class decorator, on the contrary, runs after everything.
A metaclass is the same as a class decorator, only harder
A decorator applies to exactly the class it is written above: a subclass does not get it, and in the call order for the subclass the decorator does not appear at all. A metaclass is inherited. And the difference between them is not power but time: a decorator receives a finished class — it can rename it, add attributes, even return a different object in its place — but the namespace the body ran in, and the arguments of type.__new__, are history by the time it arrives.
A metaclass conflict is a rare edge case
It happens when someone tries to inherit both from your class and from something with a metaclass of its own — which means ABC and Enum, that is, the standard library. And it happens in SOMEONE ELSE'S file, for the author of the subclass: the “metaclass conflict” message goes to them, not to you.
Version history
| Version | Change | What this means for your code |
|---|---|---|
| 3.0 | PEP 3115 introduces __prepare__ and today's metaclass= syntax in place of the __metaclass__ attribute. From this point a metaclass has the one ability nothing else has: intercepting the execution of the class body. | |
| 3.6 | PEP 487: __init_subclass__ and __set_name__ appear. This is the key row of the table — after it most metaclasses no longer need writing. Registering subclasses, checking required attributes and handing a descriptor its name are all solved without a metaclass and without the risk of a conflict. | |
| 3.11 | The lesson's baseline: the order of the six steps, the behaviour of __prepare__, the boundary of __init_subclass__ and the text of the conflict error are the same on 3.11 as on 3.14.7. Verified by running one script on four versions. | |
| 3.12 | The class C[T] syntax arrives (PEP 695) — and the metaclass starts seeing things the class author never wrote. Verified: __prepare__ receives bases of (typing.Generic,) for a class declared with no bases at all, and the namespace gains __type_params__ and __orig_bases__. | |
| 3.13 | The namespace handed to the metaclass gains __firstlineno__ and __static_attributes__. On 3.11 and 3.12 it held exactly __module__, __qualname__ and whatever the body defined. A metaclass that walks the namespace and fails on an unknown key breaks on this upgrade — the only row in the table capable of breaking existing code. |
Practice
Two exercises. Answer first, then check against the real output: in both, the right answer comes from a recorded run rather than from an editor.
Practice · predict the output
class Base:
registry = []
def __init_subclass__(cls, **kwargs):
super().__init_subclass__(**kwargs)
Base.registry.append(cls.__name__)
class A(Base):
pass
class B(A):
pass
print(Base.registry)Practice · estimate
Check yourself
In what order are the parent's __init_subclass__ and Meta.__init__ called when a class is created?
What measured this
The numbers in this article come from these scripts. Each one opens from here, together with the record of the run: what it was measured on, what came out, and with what spread.
This is neither a retelling nor a separate text: everything below is taken from the article itself — its own summary, the section headings, the “actually” column and the version table. Which is why these theses cannot drift from the article.
The gist
- A class has a type too, and that type is
type. An object is an instance of its class; a class is an instance of its metaclass. A metaclass governs how classes are created in much the same way a class governs how instances are created. The language has no separate entity for this: to write your own metaclass you subclasstype. - Hence the main consequence:
Class(...)is a call on an instance of the metaclass, which is why instance creation is intercepted on the metaclass rather than on the class. And creating a class is itself a chain of steps whose order matters more than the list:__set_name__on descriptors and__init_subclass__on the parent are called inside the creation of the class object, that is, before the metaclass's__init__, while a class decorator runs after everything else. The real price of a metaclass is also not the one expected: not time, but ametaclass conflictraised for someone who never chose your metaclass. - Beyond that is what separates knowing from having read. There are six steps:
- 1.
Meta.__prepare__— hands out the mapping for the body 2. the class body runs 3.Meta.__new__— the class object is created 4.__set_name__on descriptors ← insidetype.__new__5.__init_subclass__on the parent ← insidetype.__new__6.Meta.__init__ - Steps 4 and 5 happen inside the third, that is, before the sixth. A metaclass by itself costs nothing: a class with an empty metaclass is created in 7.09 µs against 6.98 µs without one. The one thing charged for is intercepting
__call__: 223.3 ns per instance against 59.6 (3.13.7). Which is why, since 3.6 (PEP 487), most tasks are solved with__init_subclass__and__set_name__. A metaclass is still needed when you must intercept the execution of the class body or instance creation.
In fact
- Creating a class with an empty metaclass takes 7.09 µs against 6.98 without one — a difference within the noise, paid once per class. Time is charged only for intercepting
__call__: 223.3 ns per instance against 59.6 (3.13.7), that is, 3.7 times, and that on EVERY creation. The real price of a metaclass is not in time at all but in the metaclass conflict raised in someone else's code. - A replacement in the most common cases, but not a complete one. It does not fire for the class it is declared on — a base class never lands in its own registry. It takes no part in creating the class: the namespace the body runs in, and the arguments of
type.__new__, are behind it by the time it is called (changing attributes of the finished class it can do, just as a decorator can). And it does not see the body executing:__prepare__belongs to metaclasses alone. - They run INSIDE
type.__new__, that is, between the creation of the class object andMeta.__init__. This is written in the reference and can be checked with a counter. Hence the practical answer:__init_subclass__will not see what the metaclass does in__init__— while a class decorator, on the contrary, runs after everything. - A decorator applies to exactly the class it is written above: a subclass does not get it, and in the call order for the subclass the decorator does not appear at all. A metaclass is inherited. And the difference between them is not power but time: a decorator receives a finished class — it can rename it, add attributes, even return a different object in its place — but the namespace the body ran in, and the arguments of
type.__new__, are history by the time it arrives. - It happens when someone tries to inherit both from your class and from something with a metaclass of its own — which means
ABCandEnum, that is, the standard library. And it happens in SOMEONE ELSE'S file, for the author of the subclass: the “metaclass conflict” message goes to them, not to you.
By version
- 3.0
- PEP 3115 introduces
__prepare__and today'smetaclass=syntax in place of the__metaclass__attribute. From this point a metaclass has the one ability nothing else has: intercepting the execution of the class body.< - 3.6
- PEP 487:
__init_subclass__and__set_name__appear. This is the key row of the table — after it most metaclasses no longer need writing. Registering subclasses, checking required attributes and handing a descriptor its name are all solved without a metaclass and without the risk of a conflict.< - 3.11
- The lesson's baseline: the order of the six steps, the behaviour of
__prepare__, the boundary of__init_subclass__and the text of the conflict error are the same on 3.11 as on 3.14.7. Verified by running one script on four versions.< - 3.12
- The
class C[T]syntax arrives (PEP 695) — and the metaclass starts seeing things the class author never wrote. Verified:__prepare__receives bases of(typing.Generic,)for a class declared with no bases at all, and the namespace gains__type_params__and__orig_bases__.< - 3.13
- The namespace handed to the metaclass gains
__firstlineno__and__static_attributes__. On 3.11 and 3.12 it held exactly__module__,__qualname__and whatever the body defined. A metaclass that walks the namespace and fails on an unknown key breaks on this upgrade — the only row in the table capable of breaking existing code.<
What is covered
- Base: a class has a type too
- Mechanism 1: a class is an instance of its metaclass, and the protocol follows
- Mechanism 2: six steps, and the order matters more than the list
- Mechanism 3: what only a metaclass can do
- Mechanism 4: the boundary of `__init_subclass__`
- Deeper: what a metaclass actually costs
- How to answer in an interview
- Next they ask
- Common misconceptions
- Version history
- Practice
- Check yourself
- What measured this
Sources & further reading
6 SOURCES
- Data model — creating a classOfficial documentation. The primary source for the order of the steps, verbatim: «When a class definition is executed, the following steps occur: MRO entries are resolved; the appropriate metaclass is determined; the class namespace is prepared; the class body is executed; the class object is created». The key part is that the body runs AFTER the namespace is prepared and BEFORE the class object is created.https://docs.python.org/3.14/reference/datamodel.html#metaclasses
- Data model — what happens inside type.__new__Official documentation. Where the fact that __set_name__ and __init_subclass__ run inside class creation, not after it, comes from: «The type.__new__ method collects all of the attributes in the class namespace that define a __set_name__ method; Those __set_name__ methods are called with the class being defined and the assigned name of that particular attribute; The __init_subclass__ hook is called on the immediate parent of the new class in its method resolution order». The same page on decorators: «After the class object is created, it is passed to the class decorators included in the class definition».https://docs.python.org/3.14/reference/datamodel.html#creating-the-class-object
- Data model — determining the metaclass, and the conflictOfficial documentation. The exact wording of the condition behind a metaclass conflict: «The most derived metaclass is one which is a subtype of all of these candidate metaclasses. If none of the candidate metaclasses meets that criterion, then the class definition will fail with TypeError». It also follows from here that the error surfaces when the SUBCLASS is defined.https://docs.python.org/3.14/reference/datamodel.html#determining-the-appropriate-metaclass
- Data model — __init_subclass__ and how it differs from a decoratorOfficial documentation. A direct comparison of the two tools, taken into the lesson whole: «This is closely related to class decorators, but where class decorators only affect the specific class they're applied to, __init_subclass__ solely applies to future subclasses of the class defining the method». The word “future” is what explains why the defining class never lands in its own registry.https://docs.python.org/3.14/reference/datamodel.html#object.__init_subclass__
- PEP 3115 — Metaclasses in Python 3000PEP. The document that introduced __prepare__ — the one hook giving a metaclass something no other tool has. Author Talin, status Final, Python 3.0. It is here to show that intercepting the execution of the class body is a stated goal, not a side effect of the implementation.https://peps.python.org/pep-3115/
- PEP 487 — Simpler customisation of class creationPEP. The document that added __init_subclass__ and __set_name__ in 3.6. Martin Teichmann and Nick Coghlan, Final. This is precisely why most metaclasses no longer need writing: two hooks cover the most common uses without dragging the class into a metaclass conflict.https://peps.python.org/pep-0487/