Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #94885

__main__ vs official module name: distinct module instances

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)

Show all headers | View raw


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 | NextNext in thread | Find similar | Unroll thread


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