From 0335b69b25e3e8eeddeb63ad78305004b2d5df2c Mon Sep 17 00:00:00 2001 From: Robsdedude Date: Mon, 26 Aug 2024 18:43:25 +0200 Subject: [PATCH 1/3] gh-99505: Fix docs for determining the metaclass --- Doc/reference/datamodel.rst | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst index f099d5553963e0..a9c955c44188ae 100644 --- a/Doc/reference/datamodel.rst +++ b/Doc/reference/datamodel.rst @@ -2462,19 +2462,25 @@ Determining the appropriate metaclass .. index:: single: metaclass hint -The appropriate metaclass for a class definition is determined as follows: +The appropriate metaclass for a class definition is determined in two steps: -* if no bases and no explicit metaclass are given, then :func:`type` is used; +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 bases are defined, the metaclass of the first base is used as candidate; * 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``. + :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 metaclass of the current candidate is a subtype of the metaclass of + the current base, updated the candidate to the metaclass of the base and + continue to the next base; +* if the current candidate is a subtype of the metaclass of the current base, + continue to the next base; +* else raise a :exc:`TypeError`. .. _prepare: From 4e3e4563c956993e340f12b0127f5121e5b6ef8d Mon Sep 17 00:00:00 2001 From: Robsdedude Date: Tue, 27 Aug 2024 09:10:07 +0200 Subject: [PATCH 2/3] Improve formatting --- Doc/reference/datamodel.rst | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst index a9c955c44188ae..8e83692e281d1c 100644 --- a/Doc/reference/datamodel.rst +++ b/Doc/reference/datamodel.rst @@ -2466,21 +2466,21 @@ 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 bases are defined, the metaclass of the first base is used as candidate; -* 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. + * if no bases and no explicit metaclass are given, then :func:`type` is used + as candidate; + * if bases are defined, the metaclass of the first base is used as candidate; + * 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 metaclass of the current candidate is a subtype of the metaclass of - the current base, updated the candidate to the metaclass of the base and - continue to the next base; -* if the current candidate is a subtype of the metaclass of the current base, - continue to the next base; -* else raise a :exc:`TypeError`. + * if the metaclass of the current candidate is a subtype of the metaclass of + the current base, updated the candidate to the metaclass of the base and + continue to the next base; + * if the current candidate is a subtype of the metaclass of the current base, + continue to the next base; + * else raise a :exc:`TypeError`. .. _prepare: From 8cd038aee48b12d6b10c1b8c93de955110d72ea6 Mon Sep 17 00:00:00 2001 From: Robsdedude Date: Tue, 27 Aug 2024 10:08:57 +0200 Subject: [PATCH 3/3] Amend missed case --- Doc/reference/datamodel.rst | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst index 8e83692e281d1c..c663bb15842dda 100644 --- a/Doc/reference/datamodel.rst +++ b/Doc/reference/datamodel.rst @@ -2468,7 +2468,10 @@ The appropriate metaclass for a class definition is determined in two steps: * if no bases and no explicit metaclass are given, then :func:`type` is used as candidate; - * if bases are defined, the metaclass of the first base 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 metaclass of the first + base is used as candidate; * 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.