What are metaclasses?
A metaclass is a class that describes the construction and behavior of other classes, similarly to how classes describe the construction and behavior of objects. The default metaclass istype, but it’s possible to use other metaclasses. Metaclasses allow you to create “a different kind of class”, such as Enums, NamedTuples, and singletons.
Mypy has special understanding of
ABCMeta and EnumMeta.Defining a metaclass
Metaclass usage example
Mypy supports the lookup of attributes in the metaclass:The
make() method is defined on the metaclass M and can be called on class A itself (not on instances of A).Metaclass conflicts
Metaclasses pose requirements on the inheritance structure:- Conflicting metaclasses
- Solution: Common metaclass
Limitations
Mypy has several limitations when working with metaclasses:No dynamic metaclasses
No dynamic metaclasses
Mypy does not understand dynamically-computed metaclasses:
No arbitrary metaclass code
No arbitrary metaclass code
Mypy does not and cannot understand arbitrary metaclass code. Only simple, straightforward metaclasses are supported.
Only type subclasses
Only type subclasses
Mypy only recognizes subclasses of
type as potential metaclasses.Self not allowed
Self not allowed
Self is not allowed as an annotation in metaclasses as per PEP 673.Working around builtin type issues
For some builtin types, mypy may think their metaclass isABCMeta even if it’s type at runtime:
- The problem
- Option 1: Use ABCMeta
- Option 2: type: ignore
Common metaclass patterns
Singleton pattern
Registry pattern
Best practices
Avoid mixing metaclasses
Avoid mixing metaclasses
It’s better not to combine metaclasses and complex class hierarchies. Keep inheritance simple when using metaclasses.
Use ABCMeta when appropriate
Use ABCMeta when appropriate
If you need both abstract base classes and custom metaclass behavior, inherit from
ABCMeta instead of type.Document metaclass behavior
Document metaclass behavior
Metaclasses can be confusing. Add clear documentation explaining what your metaclass does and why it’s needed.
Consider alternatives
Consider alternatives
Before using metaclasses, consider if class decorators or
__init_subclass__ would work better for your use case.