tl;dr Are there any objections to making making the default cls.__prepare__ return OrderedDict instead of dict (and preserve that order in a list on the class)?
A couple years ago [1][2] I proposed making class definition namespaces use OrderedDict by default. Said Guido [3]: I'm fine with doing this by default for a class namespace; the type of cls.__dict__ is already a non-dict (it's a proxy) and it's unlikely to have 100,000 entries. It turns out making cls.__dict__ an OrderedDict isn't reasonably tractable (due to the concrete API v. subclasses), but really that isn't what I was looking for anyway. Regardless, since it's been a while I just want to run the proposal by the group again. I'm hopeful about landing my C implementation of OrderedDict [4] in the next few days. Also, I have a patch up [5] that implements using OrderedDict for class definitions. So mostly I just want to double check that I'm still good to go. Just to be clear on what I'm proposing specifically, I've summed it up below. -eric --------------------- Currently if you want to preserve the order of a class definition you have to use a metaclass with a __prepare__ method (see PEP 3115). However, as that PEP points out [6], the common case for __prepare__ is to use OrderedDict. I'm proposing that we return OrderedDict() by default from __prepare__. Considering the common case, we should also expose that definition order on the class afterward since otherwise the extra information from the class definition namespace is discarded (type.__new__ copies it into a dict which is then used for cls.__dict__). So the key changes are: * use OrderedDict by default for class definition namespace (e.g. from type.__prepare__) * expose that definition order as cls.__definition_order__ (a list) (Note that I will not be changing the actual type of cls.__dict__ (i.e. tp_dict) which will remain a dict.) The effect of the change would be that the following are basically equivalent (relative to the the definition namespace): class Meta(type): @classmethod. def __prepare__(meta, *args, **kwargs): return OrderedDict() class SpamOld(metaclass=Meta): a = 1 b = 2 c = 3 __definition_order__ = list(locals()) class SpamNew: a = 1 b = 2 c = 3 assert SpamOld.__definition__order == SpamNew.__definition_order__ The key differences are: * for SpamNew you don't need to use a metaclass [7][8] * for SpamNew you don't need to rely on the behavior of locals() * for SpamNew the class definition isn't cluttered with extra boilerplate for __definition_order__ * class decorators that care about definition order [9] don't have to require that classes like SpamNew manually preserve that order somehow The patch for the change is pretty minimal. [5] Also, Nick Coghlan recently expressed that he favored using OrderedDict by default over the alternative presented by PEP 422/487. [10] [1] https://mail.python.org/pipermail/python-ideas/2013-February/019690.html [2] https://mail.python.org/pipermail/python-dev/2013-June/127103.html [3] Guido: https://mail.python.org/pipermail/python-ideas/2013-February/019704.html [4] http://bugs.python.org/issue16991 [5] http://bugs.python.org/issue24254 [6] see the "Alternate Proposals" section of https://www.python.org/dev/peps/pep-3115/ [7] PEPs 422 and 487 relatedly focus on the benefits of reducing the need to use metaclasses [8] https://mail.python.org/pipermail/python-ideas/2013-February/019706.html [9] see "Key points" on https://mail.python.org/pipermail/python-dev/2013-February/124439.html [10] Nick: https://mail.python.org/pipermail/python-ideas/2015-March/032254.html _______________________________________________ Python-Dev mailing list Python-Dev@python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com