Add stricter constraints to manually set __definition_order__.

This commit is contained in:
Eric Snow 2016-06-11 20:22:50 -06:00
parent 4f37f47475
commit 3fbf62a658
1 changed files with 34 additions and 5 deletions

View File

@ -61,19 +61,21 @@ Specification
* the order in which class attributes are defined is preserved in the
new ``__definition_order__`` attribute on each class
* "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 always set:
1. if ``__definition_order__`` is defined in the class body then the
value is used as-is, though the attribute will still be read-only
1. if ``__definition_order__`` is defined in the class body then it
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
their ``__definition_order__`` set to ``None``
3. classes for which `__prepare__()`` returned something other than
``OrderedDict`` (or a subclass) have their ``__definition_order__``
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):
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
body. The use cases for dealing with the class namespace (``__dict__``)
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.
@ -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
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?
-------------------------------------------