[Python-Dev] PEP: Ordered Class Definition Namespace

Émanuel Barry vgr255 at live.ca
Tue Jun 7 14:36:20 EDT 2016


> From: Eric Snow
> Sent: Tuesday, June 07, 2016 1:52 PM
> To: Python-Dev
> Subject: [Python-Dev] PEP: Ordered Class Definition Namespace
> 
> 
> 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.

Formatting nit: ``dict``

> Specification
> =============
> 
> * the default class *definition* namespace is now ``OrderdDict``
> * 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

What does this imply? If I define some __dunder__ methods, will they simply
not be present in __definition_order__? What if I want to keep the order of
those? While keeping the order of these might be meaningless in most cases,
I don't think there's really a huge problem in doing so. Maybe I'm
overthinking it.

> * ``__definition_order__`` is a tuple
> * ``__definition_order__`` is a read-only attribute
> * ``__definition_order__`` is always set:
> 
>   * if ``__definition_order__`` is defined in the class body then it
>     is used
>   * types that do not have a class definition (e.g. builtins) have
>     their ``__definition_order__`` set to ``None``
>   * types for which `__prepare__()`` returned something other than
>     ``OrderedDict`` (or a subclass) have their ``__definition_order__``
>     set to ``None``

I would probably like a ``type.definition_order`` method, for which the
return value is bound to __definition_order__ when the class is created
(much like the link between ``type.mro`` and ``cls.__mro__``. Additionally
I'm not sure if setting the attribute to None is a good idea; I'd have it as
an empty tuple. Then again I tend to overthink a lot.

> The following code demonstrates roughly equivalent semantics::
> 
>    class Meta(type):
>        def __prepare__(cls, *args, **kwargs):
>            return OrderedDict()
> 
>    class Spam(metaclass=Meta):
>        ham = None
>        eggs = 5
>        __definition_order__ = tuple(k for k in locals()
>                                     if (!k.startswith('__') or
>                                         !k.endswith('__')))

Mixing up C and Python syntax here.

> However, using ``OrderedDict`` for ``type,__dict__`` would obscure the
> relationship with the definition namespace, making it less useful.
> Additionally, doing this would require significant changes to the
> semantics of the concrete dict C-API.

Formatting nit: ``dict``

I'm +1 on the whole idea (one of my common uses of metaclasses was to keep
the definition order *somewhere*). Thank you for doing that!
-Emanuel


More information about the Python-Dev mailing list