[Python-ideas] Replacing the if __name__ == "__main__" idiom (was Re: making a module callable)

Nick Coghlan ncoghlan at gmail.com
Sun Nov 24 23:21:26 CET 2013


On 25 Nov 2013 07:26, "Antoine Pitrou" <solipsis at pitrou.net> wrote:
>
> On Sun, 24 Nov 2013 11:10:43 -0800
> Guido van Rossum <guido at python.org> wrote:
> > Haven't followed all of this, but perhaps the simplest thing would be to
> > define a new builtin function that returns True in the namespace of the
> > main module and false everywhere else. It could be implemented by
pulling
> > '__name__' out of the caller's local namespace and comparing it to
> > '__main__'. We could name this function __main__(), or perhaps less
> > dramatic, is_main(). Then you could write
> >
> > if is_main():
> >     <do your main code>
>
> Why not make it so that a module function named __main__, if it exists,
> gets executed when the module is run as a script?

I consider the fact that the semantics of __main__ execution are largely
the same as those of any other module import to be a feature rather than a
bug.

Keep in mind that we *can't* stop the current idiom from working (since we
have to run the top level code to build the module in the first place), and
that "run this script from disk" is just one way of executing __main__. For
example, the REPL loop is a statement-by-statement interactive rendition of
__main__, while __main__.py files in zipfiles, directories and packages
don't bother with the "if __name__ == '__main__'" guard at all.

Any "define a function with this special name" idiom would require making a
decision on what it means in the REPL (implicit atexit() function?
Automatically called when declared?), and changes not only to pythonrun.c,
but also to runpy, IDLE, and various other IDE's. pdb, profile, coverage
tools, etc would also all need to  change (unless this was made an implicit
feature of exec() and execfile(), which really doesn't sound like a good
idea).

Whether or not runpy's module API should trigger __main__ function
execution becomes a tricky question, as does the fact that many of the
PyRun_* helpers execute code in the __main__ namespace. Should they trigger
execution of special __main__ functions as well?

I don't have good answers to many of those questions, which is why I think
the whole idea of introducing "main functions" to Python as anything more
than a conventional idiom isn't worth the hassle. I consider the desire for
such a feature just a relic of people's experience with languages like C
and Java where the top level module code is just a declaration of program
structure to the compiler rather than a full fledged execution environment.

(Another point of confusion: C etc will complain if multiple main function
declarations are linked into the same program, while Python would silently
ignore any that weren't in the main module).

> (this would also mimick the __main__.py convention for packages)

Not really - that's still just normal script execution, and it has a couple
of very clear triggers analogous to the "if __name__ == '__main__'" idiom
for ordinary scripts (the import system indicating the specified name
refers to a package rather than a simple module for module execution, or to
a valid sys.path entry for direct execution).

Since those modules don't include the idiomatic guard, running them
directly in IDLE (or elsewhere) will still typically do the right thing.

I don't mind Guido's idea of an "is_main()" builtin for 3.5, though. It
should be less confusing for beginners, and for those that subsequently
want to understand the details, it can be explained in terms of the
existing, more explicit idiom. But trying to level shift from "the main
module is special" to "the already special main module may optionally
declare a special main function"? That's *way* more complicated than many
folks seem to realise.

Cheers,
Nick.

>
> Regards
>
> Antoine.
>
>
> _______________________________________________
> Python-ideas mailing list
> Python-ideas at python.org
> https://mail.python.org/mailman/listinfo/python-ideas
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20131125/2bf8aebd/attachment-0001.html>


More information about the Python-ideas mailing list