[Python-ideas] proposal: "python -m foo" should bind sys.modules['foo']

Nick Coghlan ncoghlan at gmail.com
Thu Aug 6 05:26:34 CEST 2015


On 6 August 2015 at 10:07, Cameron Simpson <cs at zip.com.au> wrote:
> I suspect "How Reloading Will Work" would need to track both module.__name__
> and module.__spec__.name to reattach the module to both entires in
> sys.modules.

Conveniently, the fact that reloading rewrites the global namespace of
the existing module, rather than creating the new module, means that
the dual references won't create any new problems relating to multiple
references - we already hit those issues due to the fact that modules
refer directly to each from their module namespaces.

> I'd like to have a go at addressing just the change I outline above, in the
> interests of just getting it done. Is that too narrow a change or PEP topic?

PEPs can be used for quite small things if we want to check for edge
cases, and the interaction between __main__ and the rest of the import
system is a truly fine source of those :)

> Are there specific other things I should be considering/addressing that
> might be affected by my suggestion?

Using __spec__.name for pickling: http://bugs.python.org/issue19702
Proposed runpy refactoring to reduce the special casing for __main__:
http://bugs.python.org/issue19982

> Also, where do I find to source for runpy to preruse?

It's a standard library module:
https://hg.python.org/cpython/file/default/Lib/runpy.py

"_run_module_as_main" is the module level function that powers the "-m" switch.

Actually *implementing* this change should be as simple as changing the line:

    main_globals = sys.modules["__main__"].__dict__

to instead be:

    main_module = sys.modules["__main__"]
    sys.modules[mod_spec.name] = main_module
    main_globals = main_module.__dict__

The PEP is mainly useful to more widely *advertise* the semantic
change, since having the module start being accessible under both
names has the potential to cause problems. In particular, I'll upgrade
the pickle issue to something that *needs* to be addressed before this
change can be made, as there will be programs that are working today
because they'll be dual importing the main module, and then pickling
objects from the properly imported one, which then unpickle correctly
in other processes (even if __main__ is different).

Preventing the dual import without also fixing the pickle
compatibility issue when pickling __main__ objects would thus have the
potential to break currently working code.

Cheers,
Nick.

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


More information about the Python-ideas mailing list