Add stricter constraints to manually set __definition_order__.
This commit is contained in:
parent
4f37f47475
commit
3fbf62a658
39
pep-0520.txt
39
pep-0520.txt
|
@ -61,19 +61,21 @@ Specification
|
||||||
* the order in which class attributes are defined is preserved in the
|
* the order in which class attributes are defined is preserved in the
|
||||||
new ``__definition_order__`` attribute on each class
|
new ``__definition_order__`` attribute on each class
|
||||||
* "dunder" attributes (e.g. ``__init__``, ``__module__``) are ignored
|
* "dunder" attributes (e.g. ``__init__``, ``__module__``) are ignored
|
||||||
* ``__definition_order__`` is a tuple
|
* ``__definition_order__`` is a ``tuple`` (or ``None``)
|
||||||
* ``__definition_order__`` is a read-only attribute
|
* ``__definition_order__`` is a read-only attribute
|
||||||
* ``__definition_order__`` is always set:
|
* ``__definition_order__`` is always set:
|
||||||
|
|
||||||
1. if ``__definition_order__`` is defined in the class body then the
|
1. if ``__definition_order__`` is defined in the class body then it
|
||||||
value is used as-is, though the attribute will still be read-only
|
must be a ``tuple`` of identifiers or ``None``; any other value
|
||||||
|
will result in ``TypeError``
|
||||||
2. classes that do not have a class definition (e.g. builtins) have
|
2. classes that do not have a class definition (e.g. builtins) have
|
||||||
their ``__definition_order__`` set to ``None``
|
their ``__definition_order__`` set to ``None``
|
||||||
3. classes for which `__prepare__()`` returned something other than
|
3. classes for which `__prepare__()`` returned something other than
|
||||||
``OrderedDict`` (or a subclass) have their ``__definition_order__``
|
``OrderedDict`` (or a subclass) have their ``__definition_order__``
|
||||||
set to ``None`` (except where #1 applies)
|
set to ``None`` (except where #1 applies)
|
||||||
|
|
||||||
The following code demonstrates roughly equivalent semantics::
|
The following code demonstrates roughly equivalent semantics for the
|
||||||
|
default behavior::
|
||||||
|
|
||||||
class Meta(type):
|
class Meta(type):
|
||||||
def __prepare__(cls, *args, **kwargs):
|
def __prepare__(cls, *args, **kwargs):
|
||||||
|
@ -115,7 +117,8 @@ unlikely and furthermore it is usually best to go immutable-by-default.
|
||||||
Note that ``__definition_order__`` is centered on the class definition
|
Note that ``__definition_order__`` is centered on the class definition
|
||||||
body. The use cases for dealing with the class namespace (``__dict__``)
|
body. The use cases for dealing with the class namespace (``__dict__``)
|
||||||
post-definition are a separate matter. ``__definition_order__`` would
|
post-definition are a separate matter. ``__definition_order__`` would
|
||||||
be a significantly misleading name for a supporting feature.
|
be a significantly misleading name for a feature focused on more than
|
||||||
|
class definition.
|
||||||
|
|
||||||
See [nick_concern_] for more discussion.
|
See [nick_concern_] for more discussion.
|
||||||
|
|
||||||
|
@ -127,6 +130,32 @@ interpreter. In practice they should not be relevant to the users of
|
||||||
``__definition_order__``. Instead, for nearly everyone they would only
|
``__definition_order__``. Instead, for nearly everyone they would only
|
||||||
be clutter, causing the same extra work for everyone.
|
be clutter, causing the same extra work for everyone.
|
||||||
|
|
||||||
|
Why None instead of an empty tuple?
|
||||||
|
-----------------------------------
|
||||||
|
|
||||||
|
A key objective of adding ``__definition_order__`` is to preserve
|
||||||
|
information in class definitions which was lost prior to this PEP.
|
||||||
|
One consequence is that ``__definition_order__`` implies an original
|
||||||
|
class definition. Using ``None`` allows us to clearly distinquish
|
||||||
|
classes that do not have a definition order. An empty tuple clearly
|
||||||
|
indicates a class that came from a definition statement but did not
|
||||||
|
define any attributes there.
|
||||||
|
|
||||||
|
Why None instead of not setting the attribute?
|
||||||
|
----------------------------------------------
|
||||||
|
|
||||||
|
The absence of an attribute requires more complex handling than ``None``
|
||||||
|
does for consumers of ``__definition_order__``.
|
||||||
|
|
||||||
|
Why constrain manually set values?
|
||||||
|
----------------------------------
|
||||||
|
|
||||||
|
If ``__definition_order__`` is manually set in the class body then it
|
||||||
|
will be used. We require it to be a tuple of identifiers (or ``None``)
|
||||||
|
so that consumers of ``__definition_order__`` may have a consistent
|
||||||
|
expectation for the value. That helps maximize the feature's
|
||||||
|
usefulness.
|
||||||
|
|
||||||
Why is __definition_order__ even necessary?
|
Why is __definition_order__ even necessary?
|
||||||
-------------------------------------------
|
-------------------------------------------
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue