Search code examples
pythonpython-modulepython-3.6python-datamodel

Is definition order available in a module namespace?


It's documented that the definition order in classes is preserved (see also PEP 520):

If the metaclass has no __prepare__ attribute, then the class namespace is initialised as an empty ordered mapping.

Is the definition order also preserved in module objects?

# foo_bar.py

def foo():
    pass

def bar():
    pass

I've experimented with the module above (also swapping the ordering), and it did seem to be reliable:

>>> import foo_bar
>>> for name in foo_bar.__dict__:
...     if not name.startswith('_'):
...         print(name)
... 
foo
bar

Presumably, the module namespace also uses a compact dict underneath, or perhaps it follows from the fact that the type(foo_bar) is a <class 'module'> that it must also respect definition order, like any other class. However, I'm not sure if this is a feature guaranteed by Python, or just a CPython implementation detail. Are the names in modules required to respect definition ordering?


Solution

  • Built-in classes, like the module class, don't go through the normal mechanism user-defined classes do* and, as such, don't make use of metaclass.__prepare__. PEP 520 does not apply for them so the guarantees it extends cannot be applied here.

    The ordering of the module namespace is currently preserved due to the dictionary being insertion ordered so, like the dictionary itself, is considered an implementation detail.


    * User defined classes first go through build_class (the function the LOAD_BUILD_CLASS bytecode loads when you dis a class statement) in bltinmodule.c. This is the only place where __prepare__ is invoked (which returns a PyDict_New from type_prepare if a custom meta with a __prepare__ isn't defined).