[Python-ideas] PEP for executing a module in a package containing relative imports

Christian Heimes lists at cheimes.de
Sun Apr 22 20:15:43 CEST 2007


Steven Bethard wrote:
> I think this PEP now needs to explicitly state that keeping the "am I
> the main module?" idiom as simple as possible is *not* a goal. Because
> everything I've seen (except for the original proposals in the PEP)
> are substantially more complicated than the current::
> 
>     if __name__ == '__main__':
> 

I'm proposing the following changes:

* sys.main is added which contains the dotted name of the main script.
   This allows code like:

     if __name__ == sys.main:
         ...

     main_module = sys.modules[sys.main]

* __name__ is never mangled and contains always the dotted name of
   the current module. It's not set to '__main__' any more. You can
   get the current module object with

     this_module = sys.modules[__name__]

* I'm against sys.modules['__main__] = main_module because it may
   cause ugly side effects with reload. The same functionality is
   available with sys.modules[sys.main]. The Zen Of Python says that
   there should be one and only one obvious way.

 > I guess I don't understand why we wouldn't be willing to put up with a
 > new module attribute or builtin to minimize the boilerplate in pretty
 > much every Python application out there.

Why bother with the second price when you can win the first prize? In my 
opinion a __main__() function makes live easier than a __main__ module 
level variable. It's also my opinion that the main code should be in a 
function and not in the body of the module. I consider it good style 
because the code is unit testable (is this a word? *g*) and callable 
from another module while code in the body is not accessable from unit 
tests and other scripts.

I know that some people are against __main__(argv) but I've good reasons 
to propose the argv syntax. Although argv is available via sys.argv I 
like the see it as an argument for __main__() for the same reasons I 
like to see __main__. It makes unit testing and calls from another 
module possible. W/o the argv argument is harder to change the argument 
in unit tests.

Now for some syntactic sugar and a dream of mine:

@argumentdecorator(MyOptionParserClass)
def __main__(egg, spam=5):
    pass

The argumentdecorator function takes some kind of option parser class 
that is used to parse argv. This would allow nice code like

__main__(('mainscript.py', '--eggs 5', '--no-spam'))

Christian




More information about the Python-ideas mailing list