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 * 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?
------------------------------------------- -------------------------------------------