[Python-Dev] PEP520 and absence of __definition_order__

Nick Coghlan ncoghlan at gmail.com
Sat Sep 10 23:05:59 EDT 2016


On 11 September 2016 at 07:26, Guido van Rossum <guido at python.org> wrote:
> On Sat, Sep 10, 2016 at 10:57 AM, Nick Coghlan <ncoghlan at gmail.com> wrote:
>> On 11 September 2016 at 03:08, Guido van Rossum <guido at python.org> wrote:
>>> So I'm happy to continue thinking about this, but I expect this is not
>>> such a big deal as you fear. Anyway, let's see if someone comes up
>>> with a more convincing argument by beta 2!
>>
>> For CPython specifically, I don't have anything more convincing than
>> Ethan's Enum example (where the way the metaclass works means most of
>> the interesting attributes don't live directly in the class dict, they
>> live in private data structures stored in the class dict, making
>> "list(MyEnum.__dict__)" inherently uninteresting, regardless of
>> whether it's ordered or not).
>
> But that would only matter if we also defined a helper utility that
> used __definition_order__. I expect that the implementation of Enum
> could be simplified somewhat in Python 3.6 since it can trust that the
> namespace passed into __new__ is ordered (so it doesn't have to switch
> it to an OrderedDict in __prepare__, perhaps).
>
> In any case the most likely way to use __definition_order__ in general
> was always to filter its contents through some other condition (e.g.
> "isn't a method and doesn't start with underscore") -- you can do the
> same with keys(). Classes that want to provide a custom list of
> "interesting" attributes can provide that using whatever class method
> or attribute they want -- it's just easier to keep those attributes
> ordered because the namespace is always ordered.

For example,it's already possible to expose order information via
__dir__, consumers of the information just have to bypass the implicit
sorting applied by the dir() builtin:

  >>> class Example:
  ...     def __dir__(self):
  ...         return "first second third fourth".split()
  ...
  >>> dir(Example())
  ['first', 'fourth', 'second', 'third']
  >>> Example().__dir__()
  ['first', 'second', 'third', 'fourth']

You've persuaded me that omitting __definition_order__ is the right
thing to do for now, so the last thing I'm going to do is to
explicitly double check with the creators of a few interesting
alternate implementations (MicroPython, VOC for JVM environments,
Batavia for JavaScript environments) to see if this may cause them
problems in officially implementing 3.6 (we know PyPy will be OK,
since they did it first).

VOC & Batavia *should* be OK (worst case, they return
collections.OrderedDict from __prepare__ and also use it for __dict__
attributes), but I'm less certain about MicroPython (since I don't
know enough about how its current dict implementation works to know
whether or not they'll be able to make the same change PyPy and
CPython did)

Cheers,
Nick.

-- 
Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia


More information about the Python-Dev mailing list