Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #94885
| Date | 2015-08-02 13:53 +1000 |
|---|---|
| From | Cameron Simpson <cs@zip.com.au> |
| Subject | __main__ vs official module name: distinct module instances |
| Newsgroups | comp.lang.python |
| Message-ID | <mailman.1151.1438488073.3674.python-list@python.org> (permalink) |
Hi All,
Maybe this should be over in python-ideas, since there is a proposal down the
bottom of this message. But first the background...
I've just wasted a silly amount of time debugging an issue that really I know
about, but had forgotten.
I have a number of modules which include a main() function, and down the bottom
this code:
if __name__ == '__main__':
sys.exit(main(sys.argv))
so that I have a convenient command line tool if I invoke the module directly.
I typically have tiny shell wrappers like this:
#!/bin/sh
exec python -m cs.app.maildb -- ${1+"$@"}
In short, invoke this module as a main program, passing in the command line
arguments. Very useful.
My problem?
When invoked this way, the module cs.app.maildb that is being executed is
actually the module named "__main__". If some other piece of code imports
"cs.app.maildb" they get a _different_ instance of the module. In the same
program! And how did it cause me trouble? I am monkey patching my module for
debug purposes, and that monkey patcher imports the module by name. So I was
monkey patching cs.app.maildb, and _not_ patching __main__. And thus not seeing
any effect from the patch.
I realise that having __name__ == '__main__' at all almost implies this effect.
I am not sure it needs to.
The Proposal:
What are the implications of modifying the python invocation:
python -m cs.app.maildb
to effectively do this (Python pseudo code):
M = importlib.import("cs.app.maildb")
M.__name__ = '__main__'
sys.modules['__main__'] = M
i.e. import the module by name, but bind it to _both_ "cs.app.maildb" and
"__main__" in sys.modules. And of course hack .__name__ to support the standard
boilerplate.
This would save some confusion when the module is invoked from the python
command line and also imported by the code; it is not intuitive that those two
things give you distinct module instances.
Aside from the module's .__name__ being '__main__' even when accessed by the
code as cs.app.maildb, are there other implications to such a change that would
break real world code?
Cheers,
Cameron Simpson <cs@zip.com.au>
The reasonable man adapts himself to the world; the unreasonable one persists
in trying to adapt the world to himself. Therefore all progress depends
on the unreasonable man. - George Bernard Shaw
Back to comp.lang.python | Previous | Next — Next in thread | Find similar | Unroll thread
__main__ vs official module name: distinct module instances Cameron Simpson <cs@zip.com.au> - 2015-08-02 13:53 +1000
Re: __main__ vs official module name: distinct module instances Steven D'Aprano <steve@pearwood.info> - 2015-08-02 17:41 +1000
Re: __main__ vs official module name: distinct module instances Chris Angelico <rosuav@gmail.com> - 2015-08-02 18:16 +1000
Re: __main__ vs official module name: distinct module instances Chris Angelico <rosuav@gmail.com> - 2015-08-02 18:18 +1000
Re: __main__ vs official module name: distinct module instances Cameron Simpson <cs@zip.com.au> - 2015-08-03 10:57 +1000
csiph-web