[Python-Dev] Magic main functions

Adam Souzis adamsz at gmail.com
Fri Oct 15 10:00:34 CEST 2004


Here's another good reason to change the way "main()" works today:

A consequence of having the invoked python script's module always be
named "__main__" is that when another module imports it by its real
name the module will be loaded twice with 2 separate class and
function definitions, etc. This can lead to unobvious bugs; for
example, an except clause will think your trying to catch another type
of exception.

to illustrate:

anothermodule.py:
import mymodule
def raiseFoo():
    raise mymodule.foo()

mymodule.py:
import anothermodule

class foo(exception):
    pass

if __name__ == '__main__':
    try:    
        anothermodule.raiseFoo()
    except foo:
        #nope, this isn't going to work 'cuz
        #its trying to catch __main__.foo not mymodule.foo
        print 'caught foo!'

One way to prevent bugs like this (which can be tricky to track down)
is to use an idiom like this for modules that can be invoked from the
command line:
if __name__ == '__main__':
    import mymodule
    mymodule.main()
else:
    #define the module contents in this conditional block, including a main()

BTW, the way this problem also exists when doing a relative import of
module inside a package. e.g.:

package1/example.py:
import package1.module1
import module1
#module1 is loaded twice, treated as different modules

-- adam

On Thu, 14 Oct 2004 17:16:39 -0400, Phillip J. Eby
<pje at telecommunity.com> wrote:
> At 07:06 AM 10/15/04 +1000, Nick Coghlan wrote:
> >Barry Warsaw wrote:
> >>On Thu, 2004-10-14 at 10:04, Bob Ippolito wrote:
> >>
> >>>>+1.  Also, if a non-dotted module name can't be found, pyrun should be
> >>>>called to see if the module is actually a package (with an __main__ that
> >>>>lives in the package's __init__.py).
> >
> >Actually, if we were going to do something for packages, I'd be more
> >inclined to look for a script called __main__.py in the package directory,
> >rather than looking for a __main__ function inside __init__.py. Or else
> >simply run __init__.py itself as __main__ (i.e. allow the use of the
> >existing 'Python main' idiom inside a package's __init__.py)
> >
> >(Interestingly, that's at least the second time it has been suggested to
> >turn this idea into 'C-like main functions for Python'. '-m' is about
> >another way to invoke the current 'if __name__ == "__main__":' idiom. It
> >is most definitely *not* about creating a new idiom for main functions -
> >an activity which would seem to be PEP-worthy)
> 
> Perhaps this means that -m is premature?  I personally would rather wait
> for 2.5 if it means we get a nice, future-proof "main" convention out of
> the deal.  While -m would not then be "backward compatible" with existing
> scripts, people could start changing scripts to match the convention as
> soon as there was an accepted PEP.
> 
> 
> 
> _______________________________________________
> Python-Dev mailing list
> Python-Dev at python.org
> http://mail.python.org/mailman/listinfo/python-dev
> Unsubscribe: http://mail.python.org/mailman/options/python-dev/adamsz%40gmail.com
>


More information about the Python-Dev mailing list