Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 21 additions & 13 deletions Doc/reference/datamodel.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2825,19 +2825,27 @@ Determining the appropriate metaclass
.. index::
single: metaclass hint

The appropriate metaclass for a class definition is determined as follows:

* if no bases and no explicit metaclass are given, then :func:`type` is used;
* if an explicit metaclass is given and it is *not* an instance of
:func:`type`, then it is used directly as the metaclass;
* if an instance of :func:`type` is given as the explicit metaclass, or
bases are defined, then the most derived metaclass is used.

The most derived metaclass is selected from the explicitly specified
metaclass (if any) and the metaclasses (i.e. ``type(cls)``) of all specified
base classes. 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``.
The appropriate metaclass for a class definition is determined in two steps:

1) a candidate metaclass is determined as follows:

* if no bases and no explicit metaclass are given, then :func:`type` is used
as candidate;
* if an explicit metaclass is given and it is an instance of :func:`type`,
then it is used as candidate;
* if bases are defined but no explicit metaclass, the class of the first
base is used as candidate;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Technically it would be the class (or type) of the first base (itself a class), not its metaclass, but not sure how to phrase that elegantly…

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, a good point. I would've interpreted "the metaclass of a class C" as type(C) and not the technically correct type(type(C)). I think "class of the first base" and similar is better here. It's more accurate and still comprehensible, I find.

* if an explicit metaclass is given and it is *not* an instance of
:func:`type`, then it is used directly as the metaclass and step 2 is skipped.

2) bases, if present, are traversed left-to-right, and the most derived
metaclass is determined as follows:

* if the current candidate is a subclass of the class of the current base,
continue with the next base;
* if the class of the current base is a subclass of the current candidate ,
continue with the next base;
* else raise a :exc:`TypeError`.


.. _prepare:
Expand Down
Loading