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