Focus PEP 520 on __definition_order__. (#27)

This commit is contained in:
ericsnowcurrently 2016-06-20 19:24:03 -06:00 committed by GitHub
parent 612452784a
commit 2c76730f6b
1 changed files with 35 additions and 25 deletions

View File

@ -1,5 +1,5 @@
PEP: 520
Title: Ordered Class Definition Namespace
Title: Preserving Class Attribute Definition Order
Version: $Revision$
Last-Modified: $Date$
Author: Eric Snow <ericsnowcurrently@gmail.com>
@ -8,7 +8,7 @@ Type: Standards Track
Content-Type: text/x-rst
Created: 7-Jun-2016
Python-Version: 3.6
Post-History: 7-Jun-2016, 11-Jun-2016
Post-History: 7-Jun-2016, 11-Jun-2016, 20-Jun-2016
Abstract
@ -20,44 +20,50 @@ namespace is copied into new ``dict`` and the original definition
namespace is discarded. The new copy is stored away as the class's
namespace and is exposed as ``__dict__`` through a read-only proxy.
This PEP changes the default class definition namespace to ``OrderedDict``.
The long-lived class namespace (``__dict__``) will remain a ``dict``.
Furthermore, the order in which the attributes are defined in each class
body will now be preserved in the ``__definition_order__`` attribute of
the class. This allows introspection of the original definition order,
This PEP preserves the order in which the attributes in the definition
namespace were added to it, before that namespace is discarded. This
means it reflects the definition order of the class body. That order
will now be preserved in the ``__definition_order__`` attribute of the
class. This allows introspection of the original definition order,
e.g. by class decorators.
Additionally, this PEP changes the default class definition namespace
to ``OrderedDict``. The long-lived class namespace (``__dict__``) will
remain a ``dict``.
Motivation
==========
Currently the namespace used during execution of a class body defaults
to ``dict``. If the metaclass defines ``__prepare__()`` then the result
of calling it is used. Thus, before this PEP, if you needed your class
definition namespace to be ``OrderedDict`` you had to use a metaclass.
Currently Python does not preserve the order in which attributes are
added to the class definition namespace. The namespace used during
execution of a class body defaults to ``dict``. If the metaclass
defines ``__prepare__()`` then the result of calling it is used. Thus,
before this PEP, to access your class definition namespace you must
use ``OrderedDict`` along with a metaclass. Then you must preserve the
definition order (from the ``OrderedDict``) yourself. This has a
couple of problems.
Metaclasses introduce an extra level of complexity to code and in some
cases (e.g. conflicts) are a problem. So reducing the need for them is
worth doing when the opportunity presents itself. Given that we now have
a C implementation of ``OrderedDict`` and that ``OrderedDict`` is the
common use case for ``__prepare__()``, we have such an opportunity by
defaulting to ``OrderedDict``.
First, it requires the use of a metaclass. Metaclasses introduce an
extra level of complexity to code and in some cases (e.g. conflicts)
are a problem. So reducing the need for them is worth doing when the
opportunity presents itself. PEP 422 and PEP 487 discuss this at
length. Given that we now have a C implementation of ``OrderedDict``
and that ``OrderedDict`` is the common use case for ``__prepare__()``,
we have such an opportunity by defaulting to ``OrderedDict``.
The usefulness of ``OrderedDict``-by-default is greatly increased if the
definition order is directly introspectable on classes afterward,
particularly by code that is independent of the original class definition.
Second, only classes that opt in to using the ``OrderedDict``-based
metaclass will have access to the definition order. This is problematic
for cases where universal access to the definition order is important.
One of the original motivating use cases for this PEP is generic class
decorators that make use of the definition order.
Changing the default class definition namespace has been discussed a
number of times, including on the mailing lists and in PEP 422 and
PEP 487 (see the References section below).
Specification
=============
* the default class *definition* namespace is now ``OrderdDict``
Part 1:
* 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
@ -74,6 +80,10 @@ Specification
``OrderedDict`` (or a subclass) have their ``__definition_order__``
set to ``None`` (except where #1 applies)
Part 2:
* the default class *definition* namespace is now ``OrderdDict``
The following code demonstrates roughly equivalent semantics for the
default behavior::