Replacing the if __name__ == "__main__" idiom (was Re: making a module callable)

On Fri, Nov 22, 2013 at 1:44 PM, Gregory P. Smith <greg@krypto.org> wrote:
It'd be nice to formalize a way to get rid of the __name__ == '__main__' idiom as well in the long long run. Sure everyone's editor types that for them now but it's still a wart. Anyways, digressing... ;)
This has come up before and is the subject of several PEPS. [1][2] The current idiom doesn't bother me too much as I try not to have files that are both scripts and modules. However, Python doesn't make the distinction all that clear nor does it do much to encourage people to keep the two separate. I'd prefer improvements in both those instead, but haven't had the time for any concrete proposal. FWIW, aside from the idiom there are other complications that arise from a module that also gets loaded in __main__ (run as a script). See PEP 395 [3]. -erc [1] http://www.python.org/dev/peps/pep-0299/ [2] http://www.python.org/dev/peps/pep-3122/ [3] http://www.python.org/dev/peps/pep-0395/ (sort of related)

I'm not in love with the *spelling* of " if __name__=='__main__': ", but I very frequently use the overall pattern. Much--or even most--of the time when I write a module, I like to allow it to either do a minimal case of its basic functionality and/or have the module run some basic unit tests as a quick check against breakage. So in contrast to Eric Snow, I try *to* make my files both scripts and modules. I know this isn't the only possible approach, but I don't think it's bad or uncommon. On Fri, Nov 22, 2013 at 1:40 PM, Eric Snow <ericsnowcurrently@gmail.com>wrote:
On Fri, Nov 22, 2013 at 1:44 PM, Gregory P. Smith <greg@krypto.org> wrote:
It'd be nice to formalize a way to get rid of the __name__ == '__main__' idiom as well in the long long run. Sure everyone's editor types that for them now but it's still a wart. Anyways, digressing... ;)
This has come up before and is the subject of several PEPS. [1][2] The current idiom doesn't bother me too much as I try not to have files that are both scripts and modules. However, Python doesn't make the distinction all that clear nor does it do much to encourage people to keep the two separate. I'd prefer improvements in both those instead, but haven't had the time for any concrete proposal.
FWIW, aside from the idiom there are other complications that arise from a module that also gets loaded in __main__ (run as a script). See PEP 395 [3].
-erc
[1] http://www.python.org/dev/peps/pep-0299/ [2] http://www.python.org/dev/peps/pep-3122/ [3] http://www.python.org/dev/peps/pep-0395/ (sort of related) _______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas
-- Keeping medicines from the bloodstreams of the sick; food from the bellies of the hungry; books from the hands of the uneducated; technology from the underdeveloped; and putting advocates of freedom in prisons. Intellectual property is to the 21st century what the slave trade was to the 16th.

On Fri, 22 Nov 2013 14:02:27 -0800 David Mertz <mertz@gnosis.cx> wrote:
I'm not in love with the *spelling* of " if __name__=='__main__': ", but I very frequently use the overall pattern.
Much--or even most--of the time when I write a module, I like to allow it to either do a minimal case of its basic functionality and/or have the module run some basic unit tests as a quick check against breakage. So in contrast to Eric Snow, I try *to* make my files both scripts and modules. I know this isn't the only possible approach, but I don't think it's bad or uncommon.
I agree with this, and we actually use it quite a bit in the stdlib (try e.g. "python -m zipfile -h"). Regards Antoine.

On Fri, Nov 22, 2013 at 3:02 PM, David Mertz <mertz@gnosis.cx> wrote:
I'm not in love with the *spelling* of " if __name__=='__main__': ", but I very frequently use the overall pattern.
Much--or even most--of the time when I write a module, I like to allow it to either do a minimal case of its basic functionality and/or have the module run some basic unit tests as a quick check against breakage. So in contrast to Eric Snow, I try *to* make my files both scripts and modules. I know this isn't the only possible approach, but I don't think it's bad or uncommon.
You're right and I think it's a good pattern too. That is something we do in the stdlib (and increasingly so). It slipped my mind. I've also seen the idiom used for initiating tests (not that I necessarily condone that practice), though less so in large projects. It would be nice if we could address the issues outlined in PEP 395. One nice approach would be to first import the module separately, copy the namespace into __main__, and then look for some special function (in the module) like __main__() and run it. That function would also be available to use programmatically. That's pretty similar to the PEPs I mentioned before. Who knows. Maybe the time has come for the idea. -eric

On 22/11/2013 22:27, Eric Snow wrote:
On Fri, Nov 22, 2013 at 3:02 PM, David Mertz <mertz@gnosis.cx> wrote:
I'm not in love with the *spelling* of " if __name__=='__main__': ", but I very frequently use the overall pattern.
Much--or even most--of the time when I write a module, I like to allow it to either do a minimal case of its basic functionality and/or have the module run some basic unit tests as a quick check against breakage. So in contrast to Eric Snow, I try *to* make my files both scripts and modules. I know this isn't the only possible approach, but I don't think it's bad or uncommon. You're right and I think it's a good pattern too. That is something we do in the stdlib (and increasingly so). It slipped my mind. I've also seen the idiom used for initiating tests (not that I necessarily condone that practice), though less so in large projects. It would be nice if we could address the issues outlined in PEP 395. Yes. Having functionality and some test of that functionality in the same module simplifies file organisation/maintenance. The test typically also provides extra documentation of the functionality ("this is how you use it").
Rob Cliffe

Adding a mainfunction decorator was mentioned in the other thread, seemed interesting so I coded up a simple example to see how it works. https://github.com/objcode/mainfunction/blob/master/mainfunction/mainfunctio...
From the README:
@mainfunction def main(): print "Hello, World." vs: if __name__ == '__main__': print "Hello, World." After playing with it briefly, I'm not sure it's a clear spelling win as decorators are a fairly advanced topic to a new programmer. If statements are one of the first programming constructs a new programmer learns - and they don't leave a "magic taste". Thoughts? On Fri, Nov 22, 2013 at 3:47 PM, Rob Cliffe <rob.cliffe@btinternet.com>wrote:
On 22/11/2013 22:27, Eric Snow wrote:
On Fri, Nov 22, 2013 at 3:02 PM, David Mertz <mertz@gnosis.cx> wrote:
I'm not in love with the *spelling* of " if __name__=='__main__': ", but I very frequently use the overall pattern.
Much--or even most--of the time when I write a module, I like to allow it to either do a minimal case of its basic functionality and/or have the module run some basic unit tests as a quick check against breakage. So in contrast to Eric Snow, I try *to* make my files both scripts and modules. I know this isn't the only possible approach, but I don't think it's bad or uncommon.
You're right and I think it's a good pattern too. That is something we do in the stdlib (and increasingly so). It slipped my mind. I've also seen the idiom used for initiating tests (not that I necessarily condone that practice), though less so in large projects. It would be nice if we could address the issues outlined in PEP 395.
Yes. Having functionality and some test of that functionality in the same module simplifies file organisation/maintenance. The test typically also provides extra documentation of the functionality ("this is how you use it").
Rob Cliffe
_______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas
-- Sean McQuillan 415.990.0854

On Fri, 22 Nov 2013 17:45:22 -0800 Sean McQuillan <mcquillan.sean@gmail.com> wrote:
Adding a mainfunction decorator was mentioned in the other thread, seemed interesting so I coded up a simple example to see how it works.
https://github.com/objcode/mainfunction/blob/master/mainfunction/mainfunctio...
From the README:
@mainfunction def main(): print "Hello, World."
vs:
if __name__ == '__main__': print "Hello, World."
After playing with it briefly, I'm not sure it's a clear spelling win as decorators are a fairly advanced topic to a new programmer. If statements are one of the first programming constructs a new programmer learns - and they don't leave a "magic taste".
Indeed, I think the current idiom is much better. Regards Antoine.

On Fri, Nov 22, 2013 at 05:45:22PM -0800, Sean McQuillan wrote:
Adding a mainfunction decorator was mentioned in the other thread, seemed interesting so I coded up a simple example to see how it works.
https://github.com/objcode/mainfunction/blob/master/mainfunction/mainfunctio...
I haven't actually tried it, but by reading the code I don't think that works the way I expect a main function to work. Your decorator simply does a bit of book-keeping, then immediately calls the main function. So it doesn't so much define a main function as just execute it straight away, which means it works with simple cases like this: @mainfunction def main(): print "Hello, World." but not for cases like this: @mainfunction def main(): do_stuff("Hello, World!") def do_stuff(msg): print msg since do_stuff doesn't exist at the time main() is executed. In contrast, the standard idiom is typically the very last thing at the bottom of the file, and so by the time it is called all the support functions are in place. My aesthetic sense tells me that there are two reasonable approaches here: 1) The current idiom, with an explicit "if __name__" test. This is the most flexible. 2) An implicit main function, which I think should be spelled __main__ to emphasise that it is special. This, I think, would require support from the compiler. (At least, I can't see any easy way to bootstrap it without using the "if __name__" test above.) python some_file.py python -m some_file would both execute the file as normal. The only addition would be, after the file has been run the compiler checks whether there is a name "__main__" in the global namespace, and if so, calls that __main__ object with sys.argv as argument. This second is analogous to the situation with packages. If a package has a __main__.py file, it is run when you call python -m package This second approach is purely a convenience for writing scripts, it doesn't given you anything you can't already do with the current idiom, but I think that defining a special main function def __main__(argv): ... is a cleaner (but less flexible) idiom that the current if __name__ business, and simpler for people to learn. -- Steven

+1 for the second approach, because 1.) It'd be more familiar to programmers coming from C, Java, etc. But I don't see how it would be easier to learn to completely new programmers. 2.) Forces people not to pollute the global namespace by making them write their code inside a function. That's usually a good idea anyways, which is why people already do if __name__ == "__main__": main() -- Markus Steven D'Aprano <steve@pearwood.info> wrote:
On Fri, Nov 22, 2013 at 05:45:22PM -0800, Sean McQuillan wrote:
Adding a mainfunction decorator was mentioned in the other thread, seemed interesting so I coded up a simple example to see how it works.
https://github.com/objcode/mainfunction/blob/master/mainfunction/mainfunctio...
I haven't actually tried it, but by reading the code I don't think that
works the way I expect a main function to work. Your decorator simply does a bit of book-keeping, then immediately calls the main function. So it doesn't so much define a main function as just execute it straight away, which means it works with simple cases like this:
@mainfunction def main(): print "Hello, World."
but not for cases like this:
@mainfunction def main(): do_stuff("Hello, World!")
def do_stuff(msg): print msg
since do_stuff doesn't exist at the time main() is executed. In contrast, the standard idiom is typically the very last thing at the bottom of the file, and so by the time it is called all the support functions are in place.
My aesthetic sense tells me that there are two reasonable approaches here:
1) The current idiom, with an explicit "if __name__" test. This is the most flexible.
2) An implicit main function, which I think should be spelled __main__ to emphasise that it is special. This, I think, would require support from the compiler. (At least, I can't see any easy way to bootstrap it without using the "if __name__" test above.)
python some_file.py
python -m some_file
would both execute the file as normal. The only addition would be, after the file has been run the compiler checks whether there is a name "__main__" in the global namespace, and if so, calls that __main__ object with sys.argv as argument.
This second is analogous to the situation with packages. If a package has a __main__.py file, it is run when you call
python -m package
This second approach is purely a convenience for writing scripts, it doesn't given you anything you can't already do with the current idiom,
but I think that defining a special main function
def __main__(argv): ...
is a cleaner (but less flexible) idiom that the current if __name__ business, and simpler for people to learn.
-- Steven _______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas

On Nov 22, 2013 8:06 PM, "Steven D'Aprano" <steve@pearwood.info> wrote:
def __main__(argv): ...
is a cleaner (but less flexible) idiom that the current if __name__ business, and simpler for people to learn.
If I had a time machine I would either do the __main__ function or alternatively: if __main__: .... but alas I can't time travel and changing it will *not* be simpler to learn because people will be seeing both the old idiom and the new idiom for a long time. While it's interesting to discuss from the standpoint of what's the best design, it's just not worth changing, IMHO. --- Bruce

On Sat, Nov 23, 2013 at 10:00 AM, Bruce Leban <bruce@leapyear.org> wrote:
On Nov 22, 2013 8:06 PM, "Steven D'Aprano" <steve@pearwood.info> wrote:
def __main__(argv): ...
is a cleaner (but less flexible) idiom that the current if __name__ business, and simpler for people to learn.
If I had a time machine I would either do the __main__ function or alternatively:
if __main__: ....
but alas I can't time travel and changing it will *not* be simpler to learn because people will be seeing both the old idiom and the new idiom for a long time. While it's interesting to discuss from the standpoint of what's the best design, it's just not worth changing, IMHO.
That was why I said it'd be for the long long term... If we ever do anything, I like this simple __main__ bool idea best. Decorators are too much unnecessary complexity for the task.

On Sun, Nov 24, 2013 at 5:00 AM, Bruce Leban <bruce@leapyear.org> wrote:
If I had a time machine I would either do the __main__ function or alternatively:
if __main__: ....
but alas I can't time travel and changing it will *not* be simpler to learn because people will be seeing both the old idiom and the new idiom for a long time. While it's interesting to discuss from the standpoint of what's the best design, it's just not worth changing, IMHO.
+1. I quite like the simplicity of that, and it wouldn't even be backward incompatible, but it wouldn't be backported. Just a really crazy idea... Does Python let you go "one level outside" and tinker with the code that imports __main__? I haven't looked into all that mechanism, but I know quite a bit of it is now implemented in Python, so it's theoretically possible... could you, in effect, add a line of code *after* that import that effectively calls __main__.__main__(sys.argv) ? That would do most of what you want. ChrisA

On Sun, Nov 24, 2013 at 09:04:59AM +1100, Chris Angelico wrote:
Just a really crazy idea... Does Python let you go "one level outside" and tinker with the code that imports __main__? I haven't looked into all that mechanism, but I know quite a bit of it is now implemented in Python, so it's theoretically possible... could you, in effect, add a line of code *after* that import that effectively calls __main__.__main__(sys.argv) ? That would do most of what you want.
It sounds like you're describing an import hook, although such things are completely opaque to me. I know they exist, but I've got no idea how they work or what they can do. -- Steven

Import hooks don't work with __main__ =( I spent a while trying to get it to work when working on MacroPy, to no avail. On Sat, Nov 23, 2013 at 4:37 PM, Steven D'Aprano <steve@pearwood.info>wrote:
On Sun, Nov 24, 2013 at 09:04:59AM +1100, Chris Angelico wrote:
Just a really crazy idea... Does Python let you go "one level outside" and tinker with the code that imports __main__? I haven't looked into all that mechanism, but I know quite a bit of it is now implemented in Python, so it's theoretically possible... could you, in effect, add a line of code *after* that import that effectively calls __main__.__main__(sys.argv) ? That would do most of what you want.
It sounds like you're describing an import hook, although such things are completely opaque to me. I know they exist, but I've got no idea how they work or what they can do.
-- Steven
_______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas

It's hard to see how they could. How would you *install* an import hook before __main__ got imported?
By doing crazy things like trying to reload __main__, or by deleting __main__ from the system modules and trying to re-import it, or by using introspection to load the file containing __main__ and stuffing it into sys.modules, or doing other nasty things. It's hard to see how any of these would work. I just wanted to confirm "they don't". On Sat, Nov 23, 2013 at 7:35 PM, Greg Ewing <greg.ewing@canterbury.ac.nz>wrote:
Haoyi Li wrote:
Import hooks don't work with __main__ =( I spent a while trying to get it to work when working on MacroPy, to no avail.
It's hard to see how they could. How would you *install* an import hook before __main__ got imported?
-- Greg
_______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas

On Sat, Nov 23, 2013 at 7:35 PM, Greg Ewing <greg.ewing@canterbury.ac.nz>wrote:
Haoyi Li wrote:
Import hooks don't work with __main__ =( I spent a while trying to get it to work when working on MacroPy, to no avail.
It's hard to see how they could. How would you *install* an import hook before __main__ got imported?
*Don't do this*... but you can abuse sitecustomize: http://docs.python.org/3.4/library/site.html -gps

i’m all for a special method name or decorator, because of the namespace issue. once you do more on your main function than print(‘Hello World’), say define variables, you tend to do: def main(): ... if __name__ == '__main__': main() in order not to pollute the namespace of the module. if __main__: ... looks nice, but will result in the same definition as the old behavior for that reason. so i’d propose one of the following API-wise: def __main__(): ... @mainfunctiondef main(): ... and implementation-wise, both should result in the function being called once the module is loaded, no matter where it is in the code. and both would AFAIK need a change to the module loader as AFAIK you can’t create a after-load hook for a module (if you can, the decorator would work without a change to the loader) 2013/11/24 Gregory P. Smith <greg@krypto.org>
On Sat, Nov 23, 2013 at 7:35 PM, Greg Ewing <greg.ewing@canterbury.ac.nz>wrote:
Haoyi Li wrote:
Import hooks don't work with __main__ =( I spent a while trying to get it to work when working on MacroPy, to no avail.
It's hard to see how they could. How would you *install* an import hook before __main__ got imported?
*Don't do this*... but you can abuse sitecustomize: http://docs.python.org/3.4/library/site.html
-gps
_______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas

On Mon, Nov 25, 2013 at 3:26 AM, Philipp A. <flying-sheep@web.de> wrote:
so i’d propose one of the following API-wise:
def __main__(): ...
@mainfunction def main(): ...
The decorator minorly worries me; what happens if you use it on two functions? Presumably both would have to be called, in the order they're in the file (or rather, the order the decorators are called), but it'd be extremely confusing to try to read that code. ChrisA

2013/11/24 Chris Angelico <rosuav@gmail.com> The decorator minorly worries me; what happens if you use it on two
functions? Presumably both would have to be called, in the order they're in the file (or rather, the order the decorators are called), but it'd be extremely confusing to try to read that code.
ChrisA
people can also do more than one if __name__ == '__main__' blocks ATM…

On Mon, Nov 25, 2013 at 3:46 AM, Philipp A. <flying-sheep@web.de> wrote:
2013/11/24 Chris Angelico <rosuav@gmail.com>
The decorator minorly worries me; what happens if you use it on two functions? Presumably both would have to be called, in the order they're in the file (or rather, the order the decorators are called), but it'd be extremely confusing to try to read that code.
ChrisA
people can also do more than one if __name__ == '__main__' blocks ATM…
True, but the concept of a "main function" is going to look far more like there should be only one. And it'd be extremely weird if: @mainfunction def main(): print("First function!") @mainfunction def main(): print("Second function!") called both, even though the second one shadows the first; and it'd be just as weird if: @mainfunction def main(): print("First function!") def main(): print("Second function!") called the second, even though it wasn't decorated as a main function. ChrisA

On 11/24/2013 05:26 PM, Philipp A. wrote:
i’m all for a special method name or decorator, because of the namespace issue.
once you do more on your main function than print(‘Hello World’), say define variables, you tend to do:
| def main(): ...
if __name__ == '__main__': main()|
in order not to pollute the namespace of the module.
I don't get that argument: when the module is executed as the main script, you shouldn't need to care about the "module namespace" since it isn't really one. Georg

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> For people who want to use this idiom on older platforms too they can easily implement it themselves using sys._getframe(). This is less magical than introducing a @mainfunction decorator, not really more typing, and easily understood by people who already know the old "if __name__ == '__main__'" idiom. -- --Guido van Rossum (python.org/~guido)

On 11/24/2013 2:10 PM, Guido van Rossum 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>
Writing 'is_main' (or anything else) instead of '__name__=='__main__' seems silly if it would be the only thing breaking back compatibility.
For people who want to use this idiom on older platforms too they can easily implement it themselves using sys._getframe.
...if one know about sys._getframe and how to use it. The leading underscore implies that it is subject to change in each version. Writing an import (from somewhere dependable) for such a function will be as many keystrokes as writing the idiom. For my main project, I have a template file that includes 'if __name__.. <run test>' along with other project boilerplate. -- Terry Jan Reedy

On Sun, 24 Nov 2013 11:10:43 -0800 Guido van Rossum <guido@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? (this would also mimick the __main__.py convention for packages) Regards Antoine.

On 25 Nov 2013 07:26, "Antoine Pitrou" <solipsis@pitrou.net> wrote:
On Sun, 24 Nov 2013 11:10:43 -0800 Guido van Rossum <guido@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@python.org https://mail.python.org/mailman/listinfo/python-ideas

On Mon, 25 Nov 2013 08:21:26 +1000 Nick Coghlan <ncoghlan@gmail.com> wrote:
On 25 Nov 2013 07:26, "Antoine Pitrou" <solipsis@pitrou.net> wrote:
On Sun, 24 Nov 2013 11:10:43 -0800 Guido van Rossum <guido@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.
Yes, I'm quite happy with the current idiom myself. I was merely suggesting this in case many people start opposing the statu quo and start demanding another idiom :-) Regards Antoine.

On Sun, Nov 24, 2013 at 2:21 PM, Nick Coghlan <ncoghlan@gmail.com> wrote:
On 25 Nov 2013 07:26, "Antoine Pitrou" <solipsis@pitrou.net> wrote:
On Sun, 24 Nov 2013 11:10:43 -0800 Guido van Rossum <guido@python.org> wrote:
Haven't followed all of this, but perhaps the simplest thing would be
define a new builtin function that returns True in the namespace of the main module and false everywhere else. It could be implemented by
to 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.
Right!
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'm not sure that the REPL behavior w.r.t. such a special function should be the deciding factor.
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).
I think that explicit is better than implicit, and that's where a special function name loses. Also, there's no reasonable way to backport a special function. (Whereas backporting is_main() is trivial, since the behavior of sys._getframe() is past releases is stable.) A decorator is perhaps a little better, but it immediately brings up the question of when the decorated function should be called, if this *is* the main module. There are two options: after the import is complete (matching how a special function name would work) or at the point where the decorated function occurs. If we want people to be able to backport the decorator it would have to be the latter. But the decorator is more verbose than even the current idiom: @mainfunction def main(): <blah> vs. if __name__ == '__main__': <blah> whereas my proposal is shorter *and* more readable: if is_main(): <blah>
(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.
Yup. -- --Guido van Rossum (python.org/~guido)

I want to have callable main function to allow script can be executed directly or from other function. def main(): <blah> if is_main(): main() is not shorter than @mainfunction def main(): <blah> But I like: def __main__(): <blah> On Mon, Nov 25, 2013 at 8:11 AM, Guido van Rossum <guido@python.org> wrote:
On Sun, Nov 24, 2013 at 2:21 PM, Nick Coghlan <ncoghlan@gmail.com> wrote:
On 25 Nov 2013 07:26, "Antoine Pitrou" <solipsis@pitrou.net> wrote:
On Sun, 24 Nov 2013 11:10:43 -0800 Guido van Rossum <guido@python.org> wrote:
Haven't followed all of this, but perhaps the simplest thing would be
define a new builtin function that returns True in the namespace of
main module and false everywhere else. It could be implemented by
to the 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.
Right!
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'm not sure that the REPL behavior w.r.t. such a special function should be the deciding factor.
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).
I think that explicit is better than implicit, and that's where a special function name loses. Also, there's no reasonable way to backport a special function. (Whereas backporting is_main() is trivial, since the behavior of sys._getframe() is past releases is stable.)
A decorator is perhaps a little better, but it immediately brings up the question of when the decorated function should be called, if this *is* the main module. There are two options: after the import is complete (matching how a special function name would work) or at the point where the decorated function occurs. If we want people to be able to backport the decorator it would have to be the latter.
But the decorator is more verbose than even the current idiom:
@mainfunction def main(): <blah>
vs.
if __name__ == '__main__': <blah>
whereas my proposal is shorter *and* more readable:
if is_main(): <blah>
(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.
Yup.
-- --Guido van Rossum (python.org/~guido)
_______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas
-- INADA Naoki <songofacandy@gmail.com>

On Sun, Nov 24, 2013 at 7:08 PM, INADA Naoki <songofacandy@gmail.com> wrote:
I want to have callable main function to allow script can be executed directly or from other function.
def main(): <blah>
if is_main(): main()
is not shorter than
@mainfunction def main(): <blah>
But I like:
def __main__(): <blah>
I had a few other arguments also against the decorator. (Like less magic. :-) -- --Guido van Rossum (python.org/~guido)

On 11/24/2013 05:11 PM, Guido van Rossum wrote:
> 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.
Right!
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.
Right, it prevents that section from running in the case where it's not the main module. But spelling that explicitly isn't as nice. if not __name__ != "__main__": # Don't do this if this module isn't named "__main__". Regarding the is_main()... seems like it should take an argument. Most is_something() functions do. Is there a way to make something like the following work? def is_main(name=None): if name == None: name = get_attr_from_caller() # dynamic lookup return (name == "__main__") And how about just a global name __main__ that is always set to "__main__"? if __name__ is __main__: ... Not a big change, but it reads nice and maybe users will like it well enough not to keep suggesting changing it. ;-) Down the road (python6) you could change both of those to the real main modules name and they would still work. Just a few thoughts, Ron

On Mon, Nov 25, 2013 at 3:14 PM, Ron Adam <ron3200@gmail.com> wrote:
And how about just a global name __main__ that is always set to "__main__"?
if __name__ is __main__: ...
Not a big change, but it reads nice and maybe users will like it well enough not to keep suggesting changing it. ;-)
But then you have to explain why you're using 'is' to compare strings, which shouldn't normally be done. Why not just use == as per current? ChrisA

On 11/24/2013 10:21 PM, Chris Angelico wrote:
But then you have to explain why you're using 'is' to compare strings, which shouldn't normally be done. Why not just use == as per current?
In the case of generally parsing strings, that is correct as there may be more than one of something that can match. But when there is only *one* of something, and you aren't manipulating the parts, then "is" should be ok. __name__ would be bound directly to __main__'s string object, so "is" or "==" should always work for that case. Cheers, Ron

On Tue, Nov 26, 2013 at 1:55 AM, Ron Adam <ron3200@gmail.com> wrote:
But when there is only *one* of something, and you aren't manipulating the parts, then "is" should be ok. __name__ would be bound directly to __main__'s string object, so "is" or "==" should always work for that case.
Really? Is this something that's guaranteed? I know the CPython compiler will optimize a lot of constants, but can you really be sure that this is safe? ChrisA

On 11/25/2013 09:15 AM, Chris Angelico wrote:
On Tue, Nov 26, 2013 at 1:55 AM, Ron Adam <ron3200@gmail.com> wrote:
But when there is only *one* of something, and you aren't manipulating the parts, then "is" should be ok. __name__ would be bound directly to __main__'s string object, so "is" or "==" should always work for that case.
Really? Is this something that's guaranteed? I know the CPython compiler will optimize a lot of constants, but can you really be sure that this is safe?
It seems to me, that you can't do this ... if __main__ is "__main__": That depends on the compiler to optimise that case so they are the same object. But in this case... __main__ = "__main__" __name__ = __main__ assert __main__ is __name__ That should always work. I would think it was a bug if it didn't. Cheers, Ron

On Tue, Nov 26, 2013 at 2:35 AM, Ron Adam <ron3200@gmail.com> wrote:
But in this case...
__main__ = "__main__" __name__ = __main__ assert __main__ is __name__
That should always work. I would think it was a bug if it didn't.
Of course, that will work. But this isn't guaranteed to: __main__ = "__main__" __name__ = "__main__" assert __main__ is __name__ It quite possibly will, but it's not guaranteed by the language. And this is more what's being done here - a separate literal. ChrisA

On 11/25/2013 09:56 AM, Chris Angelico wrote:
On Tue, Nov 26, 2013 at 2:35 AM, Ron Adam<ron3200@gmail.com> wrote:
But in this case...
__main__ = "__main__" __name__ = __main__ assert __main__ is __name__
That should always work. I would think it was a bug if it didn't. Of course, that will work. But this isn't guaranteed to:
__main__ = "__main__" __name__ = "__main__" assert __main__ is __name__
It quite possibly will, but it's not guaranteed by the language. And this is more what's being done here - a separate literal.
Are thinking that the __main__ global would be defined after the main module is loaded? I was thinking that __main__ would be set to "__main__" first, then when the main module is loaded, it's __name__ attribute set to __main__ rather than "__main__". Exactly as the first example above. Or are you thinking there may be more than one main module? If you just feel strongly that using 'is' is a bad practice in this case, I'm fine with that. Cheers, Ron

On 11/25/2013 02:12 PM, Ron Adam wrote:
On 11/25/2013 09:56 AM, Chris Angelico wrote:
On Tue, Nov 26, 2013 at 2:35 AM, Ron Adam wrote:
But in this case...
__main__ = "__main__" __name__ = __main__ assert __main__ is __name__
That should always work. I would think it was a bug if it didn't.
Of course, that will work. But this isn't guaranteed to:
__main__ = "__main__" __name__ = "__main__" assert __main__ is __name__
It quite possibly will, but it's not guaranteed by the language. And this is more what's being done here - a separate literal.
Are thinking that the __main__ global would be defined after the main module is loaded?
I was thinking that __main__ would be set to "__main__" first, then when the main module is loaded, it's __name__ attribute set to __main__ rather than "__main__". Exactly as the first example above.
Or are you thinking there may be more than one main module?
If you just feel strongly that using 'is' is a bad practice in this case, I'm fine with that.
Yes, it is bad practice to use `is` this way. The only time `is` should be used is when you need to know that two names/references are referring to the exact same object, which is definitely not the case here. -- ~Ethan~

On Tue, Nov 26, 2013 at 9:12 AM, Ron Adam <ron3200@gmail.com> wrote:
I was thinking that __main__ would be set to "__main__" first, then when the main module is loaded, it's __name__ attribute set to __main__ rather than "__main__". Exactly as the first example above.
I thought you were describing assigning a particular string to __name__, which is where the problem would come from. If it's being set to "whatever's in __main__", then yes, your description is correct and it's safe. OTOH, what you now have is: # standard idiom, everyone knows this works if __name__ is __main__: # use of actual thing: it's a string print(__name__) # everywhere else, this is the wrong thing to do: if input() is "yes": do_dangerous_stuff() So now you have to explain why it's right to use 'is', but only with these things, which are magical. Possibly the easiest would be to guarantee that __main__ and __name__ are sys.intern()'d, which could then lead into an explanation of interning rather than an explanation of magic. ChrisA

On 11/24/2013 10:14 PM, Ron Adam wrote:
Regarding the is_main()... seems like it should take an argument. Most is_something() functions do. Is there a way to make something like the following work?
def is_main(name=None): if name == None: name = get_attr_from_caller() # dynamic lookup return (name == "__main__")
This should have been... def is_main(name=None): if name == None: name = get_attr_from_caller("__name__") # dynamic lookup return (name == "__main__") -Ron

Guido van Rossum 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.
Can someone remind me why there's so much resistance to simply blessing a __main__() function? It would be straightforward and intuitive and in line with what just about every other language does. -- Greg

On 25 Nov 2013 08:28, "Greg Ewing" <greg.ewing@canterbury.ac.nz> wrote:
Guido van Rossum 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.
Can someone remind me why there's so much resistance to simply blessing a __main__() function? It would be straightforward and intuitive and in line with what just about every other language does.
See my other email. Implementing it is not straightforward at all, and it's only intuitive to people that have been trained to think that way by C, Java, et al. Cheers, Nick.
-- Greg
_______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas

From: Greg Ewing <greg.ewing@canterbury.ac.nz>
G uido van Rossum 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.
Can someone remind me why there's so much resistance to simply blessing a __main__() function? It would be straightforward and intuitive and in line with what just about every other language does.
Which languages, other than C and its direct descendants? The other major scripting languages—Ruby, Perl, JavaScript, PHP, Tcl, etc.—have no such thing; they all just execute all the top-level code, and provide some variable you can check to see if you're the "main module", just like Python. The conventional idioms in those languages are mostly borrowed from Python's. For example: # Ruby if __FILE__ == $0 exit(main(ARGV)) # or exit(MainClass.new(ARGV).run) end # Node.js if (require.main === module) { main(process.argv) } Most functional languages don't have any special main function or main environment. Other procedural languages like Pascal, Fortran, etc. that have a special main environment do it with different syntax—e.g., the code goes in BEGIN PROGRAM instead of in a function/procedure. The only one I can think of that uses a special main function like C is Visual BASIC (which borrowed it from C).

On Sun, Nov 24, 2013 at 2:27 PM, Greg Ewing <greg.ewing@canterbury.ac.nz>wrote:
Can someone remind me why there's so much resistance to simply blessing a __main__() function? It would be straightforward and intuitive and in line with what just about every other language does.
What's not intuitive is that __main__ would be called sometimes and not other times. Not knowing the idiom, seeing def __main__, why would I assume it's going to get executed automatically and that this is only true of one of the files being executed? The first time I saw __name__ == '__main__', I thought "Huh?" and went and looked it up and learned how it worked. If I had seen def __main__, I probably would have thought it worked just like C's main function which can be in any file. --- Bruce I'm hiring: http://www.cadencemd.com/info/jobs Latest blog post: Alice's Puzzle Page http://www.vroospeak.com Learn how hackers think: http://j.mp/gruyere-security

2013/11/24 Guido van Rossum <guido@python.org>
if is_main(): <do your main code>
How about going the other way around? if imported(): break <do your main code> Most of the time, people put the main stuff at the end of the script, so this check can serve as a seperator, equivalent to what is sometimes marked with '***********************' - snip the script here. Of course, it is still possible to do if not imported(): main() I think it is at least as obvious as is_main(), and even more so for those without a C-like background. (Personally I'd prefer an `imported` magic variable but I guess that's out of question). Elazar

On 25/11/2013 22:25, אלעזר wrote:
2013/11/24 Guido van Rossum <guido@python.org <mailto:guido@python.org>>
if is_main(): <do your main code>
How about going the other way around?
if imported(): break
<do your main code>
Most of the time, people put the main stuff at the end of the script, so this check can serve as a seperator, equivalent to what is sometimes marked with '***********************' - snip the script here.
Of course, it is still possible to do
if not imported(): main()
I think it is at least as obvious as is_main(), and even more so for those without a C-like background.
(Personally I'd prefer an `imported` magic variable but I guess that's out of question).
Instead of "imported", how about "import"? That already exists as a reserved word and its use outside an import statement is currently illegal: if not import: main()

On 24Nov2013 17:26, Philipp A. <flying-sheep@web.de> wrote:
i’m all for a special method name or decorator, because of the namespace issue.
once you do more on your main function than print(‘Hello World’), say define variables, you tend to do:
def main(): ... if __name__ == '__main__': main()
in order not to pollute the namespace of the module. [...]
This is what I do, almost word for word. When I do this, the main() function is the first function in the module and the code at the bottom goes: if __name__ == '__main__': import sys sys.exit(main(sys.argv)) This make the main() function obvious when looking at the code, and makes things work intuitively on the command line, with a meaningful exit status. Modules without a main() run unit tests and I have an aspirational goal to fold a selftest mode into the module with a main(). A magic name? It seems a little overkill if the code is written in a fashion like the above: the main() is obvious. Cheers, -- Cameron Simpson <cs@zip.com.au> SCCS, the source motel! Programs check in and never check out! - Ken Thompson

On 25 November 2013 17:19, Cameron Simpson <cs@zip.com.au> wrote:
On 24Nov2013 17:26, Philipp A. <flying-sheep@web.de> wrote:
i’m all for a special method name or decorator, because of the namespace issue.
once you do more on your main function than print(‘Hello World’), say define variables, you tend to do:
def main(): ... if __name__ == '__main__': main()
in order not to pollute the namespace of the module. [...]
This is what I do, almost word for word. When I do this, the main() function is the first function in the module and the code at the bottom goes:
if __name__ == '__main__': import sys sys.exit(main(sys.argv))
This make the main() function obvious when looking at the code, and makes things work intuitively on the command line, with a meaningful exit status.
Modules without a main() run unit tests and I have an aspirational goal to fold a selftest mode into the module with a main().
A magic name? It seems a little overkill if the code is written in a fashion like the above: the main() is obvious.
So, rather than the low level "is_main", perhaps a higher level builtin would be appropriate?
def run_if_main(f): ... import sys ... if sys._getframe(-1).f_globals.get("__name__") == "__main__": ... sys.exit(f(sys.argv)) ...
Starting to get a little too magical for my taste at that point, although with a small tweak (to return "f" in the "not main" case) it *does* allow the idiom: @run_if_main def main(argv): ... Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia

On Mon, Nov 25, 2013 at 08:20:23PM +1000, Nick Coghlan wrote:
So, rather than the low level "is_main", perhaps a higher level builtin would be appropriate?
def run_if_main(f): ... import sys ... if sys._getframe(-1).f_globals.get("__name__") == "__main__": ... sys.exit(f(sys.argv)) ...
Starting to get a little too magical for my taste at that point, although with a small tweak (to return "f" in the "not main" case) it *does* allow the idiom:
@run_if_main def main(argv): ...
I love decorators, I really do, but I strongly feel that a decorator is completely the wrong API for this functionality. I can't quite put it into words, it's an aesthetic thing, but there is one concrete objection I can give. To understand the current "if __name__" idiom, the user only needs to understand the if statement and the rule that Python defines a special global variable __name__. To understand this run_if_main idiom, the user has to understand decorators. It's hard to believe, but I've come across people -- even quite experienced Python developers -- who avoid decorators because they don't quite get how they work. And of course beginners have no idea what a decorator is. These means explaining about higher-order functions. For something as basic as running a main function when called as a script, one shouldn't have to understand functional programming, higher order functions and decorators. Here are the alternatives, as I see them: (1) Keep the status quo. I don't actually dislike the status quo, even though after 15 years I still write "if __name__ is '__main__'" and have to go back and correct it :-) This is a bit magical, so although it's a perfectly acceptable solution, perhaps we can make something a bit less magical? (Or at least, stick the magic in the implementation, rather than in the user's code.) This has suited Python well for 20-odd years, and there's nothing really wrong with it. +0.5 on this. (2) Have a special function, called "main" or more likely "__main__", which is automagically called by Python if and only if the module is being run as the main module. I still have a soft-spot for this, but I'm now satisfied that it is the wrong solution. Arguments against: - Explicit is better than implicit. - Because it needs support from the compiler, you can't back-port this to older versions of Python. - People will be confused by the fact that __main__ is sometimes automatically called and sometimes not. -1 on this one. (3) Add an is_main() function to simplify the idiom to: if is_main(): ... Pros: - the magic of deciding whether we're running in the main module is hidden behind an abstraction layer; - even more easily understood than the current "if __name__" idiom; - easily backported. Cons: - one more built-in. I give this one a +1. (4) Like #3 above, but make it a (read-only?) global variable, like __debug__. Possibly spelled "__main__". The idiom becomes: if is_main: ... if __main__: ... Pros: - Some people might feel that "this is the main module" feels more like a global variable than a function call. Cons: - If read-only, that requires some magic behind the scenes. - If not read-only, then people will mess about with it and get confused. +0.5 if read-only, -0.5 if not. (5) A decorator-based solution. Pros: - More explicit than automagically calling a function based on its name. Cons: - Feels wrong to me. I realise that's entirely subjective. - To me, "run the main function" seems far too basic an operation to justify requiring the user learn about decorators first. - Have to import the decorator first. - Unless it's a built-in, in which case, yet another built-in. - If we go with this solution, the bike-shedding. Oh the bike- shedding! * what should it pass to the decorated function? ~ sys.argv ~ a copy of sys.argv ~ sys.argv[1:] ~ nothing at all * should you be allowed to decorate more than one function? * should the function(s) be called immediately, or queued up and then run after the module is fully loaded? * call sys.exit? I'm -1 on this. There are too many slightly different flavours of this solution, and none of them are really hard to solve once you know whether or not your in the main module. -- Steven

On 26 November 2013 00:12, Steven D'Aprano <steve@pearwood.info> wrote: <A wonderful summary> I'm wondering if we should add a link to Steven's post from http://www.python.org/dev/peps/pep-0299/ (and perhaps even update the PEP text itself) As the status of PEP 299 shows, Guido has rejected the idea of a special main function before, but I think Steven's post does a better job of spelling out "Why not?" than any of the previous discussions. Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia

On Mon, Nov 25, 2013 at 6:22 AM, Nick Coghlan <ncoghlan@gmail.com> wrote:
On 26 November 2013 00:12, Steven D'Aprano <steve@pearwood.info> wrote:
<A wonderful summary>
I'm wondering if we should add a link to Steven's post from http://www.python.org/dev/peps/pep-0299/ (and perhaps even update the PEP text itself)
As the status of PEP 299 shows, Guido has rejected the idea of a special main function before, but I think Steven's post does a better job of spelling out "Why not?" than any of the previous discussions.
+1 (if you haven't already done it) -gps

On 25/11/2013 14:12, Steven D'Aprano wrote:
(4) Like #3 above, but make it a (read-only?) global variable, like __debug__. Possibly spelled "__main__". The idiom becomes:
if is_main: ...
if __main__: ...
Pros:
- Some people might feel that "this is the main module" feels more like a global variable than a function call.
Cons:
- If read-only, that requires some magic behind the scenes.
- If not read-only, then people will mess about with it and get confused.
+0.5 if read-only, -0.5 if not.
I like this idea (a global variable called __main__), provided that it can be implemented without slowing down access to other variables. Say __main__ did not exist as a real variable, so attempting to read it triggered a NameError behind the scenes. The error handling code could then check for a name of '__main__' as a special case. Does this make sense? Con: A variable which changes its value without being assigned to is more magical/unexpected than a function (is_main()) which returns different values at different times. But I think people would soon get used to it, and find it convenient. The behaviour could be overridden (if the run-time allowed it) by defining a "real" variable called __main__. Well, among consenting adults, why not? It might even be useful. Rob Cliffe

On Tue, 26 Nov 2013 01:12:21 +1100 Steven D'Aprano <steve@pearwood.info> wrote:
(1) Keep the status quo.
+1. The status quo has another benefit: it teaches beginners about __name__ and, with it, the fact that many Python objects have useful introspection data.
(3) Add an is_main() function to simplify the idiom to:
if is_main(): ...
Pros:
- the magic of deciding whether we're running in the main module is hidden behind an abstraction layer;
- even more easily understood than the current "if __name__" idiom;
- easily backported.
Cons:
- one more built-in.
Other con: the is_main() implementation would have to be hackish (use of sys._getframe() or a similar trick). I'm personally -0.5.
(5) A decorator-based solution.
-1. Much too complicated for a simple need. Regards Antoine.

On Nov 25, 2013, at 8:05, Antoine Pitrou <solipsis@pitrou.net> wrote:
On Tue, 26 Nov 2013 01:12:21 +1100 Steven D'Aprano <steve@pearwood.info> wrote:
(1) Keep the status quo.
+1.
The status quo has another benefit: it teaches beginners about __name__ and, with it, the fact that many Python objects have useful introspection data.
This is a great point. In fact, I even took advantage of this fact a few days ago, explaining the __self__ attribute on (bound) methods by saying "Almost everything in Python has useful attributes, like the __name__ attribute on modules that you use every day", so I'm not sure why I didn't notice this benefit until you pointed it out... But I'm glad you did.
(3) Add an is_main() function to simplify the idiom to:
if is_main(): ...
Pros:
- the magic of deciding whether we're running in the main module is hidden behind an abstraction layer;
- even more easily understood than the current "if __name__" idiom;
- easily backported.
Cons:
- one more built-in.
Other con: the is_main() implementation would have to be hackish (use of sys._getframe() or a similar trick).
Agreed. If Python had a (non-hacky) way to declare a variable as coming from the caller's namespace instead of the defining namespace this would be a great answer. But Python doesn't (and probably shouldn't) have any such feature, and a function that everyone learns as a novice that implies such a feature exists is probably a bad idea.
I'm personally -0.5.
(5) A decorator-based solution.
-1. Much too complicated for a simple need.
Regards
Antoine.
_______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas

On Nov 25, 2013, at 6:12, Steven D'Aprano <steve@pearwood.info> wrote:
To understand the current "if __name__" idiom, the user only needs to understand the if statement and the rule that Python defines a special global variable __name__. To understand this run_if_main idiom, the user has to understand decorators. It's hard to believe, but I've come across people -- even quite experienced Python developers -- who avoid decorators because they don't quite get how they work. And of course beginners have no idea what a decorator is. These means explaining about higher-order functions.
No, it really doesn't. In order to write a decorator, or read it's code, you have to understand HOFs. But to use a decorator? I've seen many people successfully using @property, @classmethod, etc. without even knowing that they're functions. (Never mind that most of them have no need for those decorators, the point is that they have no problem figuring out how to use them.) I don't like the decorator idea either, but I think this is the wrong argument. Guido's points that it's too magical, and ends up providing less power with that magic than you already have without, seem better. But Steven's bikesheddability argument (right next to the "have to understand decorators" argument) is what really sells me that this is the wrong answer. All those options means that people will have to learn or look up which option Python chose--and, as usual, many novices won't even realize there was an option to choose from, assume wrong, and have to ask someone "Why does my code after the @is_main function never get run, while the same code after an old-style if __name__ block does?" because they don't realize that the main function's result is passed to exit because they never even realized such a thing was possible.

On Nov 26, 2013, at 01:12 AM, Steven D'Aprano wrote:
(1) Keep the status quo.
I'd have no problem with this. The current idiom doesn't seem broken to me, nor is it that hard to type. I also don't think it's very hard to discover given how common it is.
if __main__:
If we *had* to make this easier to type, this would be my choice. It doesn't even have to be read-only, given that __name__ can be messed with, but usually isn't. Why then worry about __main__ getting messed with? -Barry

On Mon, Nov 25, 2013 at 11:42 AM, Barry Warsaw <barry@python.org> wrote:
On Nov 26, 2013, at 01:12 AM, Steven D'Aprano wrote:
(1) Keep the status quo.
I'd have no problem with this. The current idiom doesn't seem broken to me, nor is it that hard to type. I also don't think it's very hard to discover given how common it is.
All agreed, yet it is not that easy to type either (underscores and quotes require the shift key). Perhaps more important, it causes everyone who sees it first to wonder why the idiom isn't simpler.
if __main__:
If we *had* to make this easier to type, this would be my choice. It doesn't even have to be read-only, given that __name__ can be messed with, but usually isn't. Why then worry about __main__ getting messed with?
The problem with this is, how would you implement this? You can either make __main__ a builtin object with a magic __bool__() method, or you can plunk a bool named __main__ in every module namespace. I don't much like either. -- --Guido van Rossum (python.org/~guido)

On 26 Nov 2013 05:51, "Guido van Rossum" <guido@python.org> wrote:
On Mon, Nov 25, 2013 at 11:42 AM, Barry Warsaw <barry@python.org> wrote:
On Nov 26, 2013, at 01:12 AM, Steven D'Aprano wrote:
(1) Keep the status quo.
I'd have no problem with this. The current idiom doesn't seem broken to
nor is it that hard to type. I also don't think it's very hard to discover given how common it is.
All agreed, yet it is not that easy to type either (underscores and quotes require the shift key). Perhaps more important, it causes everyone who sees it first to wonder why the idiom isn't simpler.
if __main__:
If we *had* to make this easier to type, this would be my choice. It
doesn't
even have to be read-only, given that __name__ can be messed with, but usually isn't. Why then worry about __main__ getting messed with?
The problem with this is, how would you implement this? You can either make __main__ a builtin object with a magic __bool__() method, or you can
me, plunk a bool named __main__ in every module namespace. I don't much like either. Shadowing would allow this to work without magic and with changes to only two modules: you could have a builtin __main__ that was always False and then set a __main__=True attribute in the main module. This still teaches the lesson about runtime introspection *and* could be used to teach an important lesson about name shadowing. Like Barry, this is my favourite of the suggestions so far, but I'm still not sure it's worth the hassle: - any such code would automatically be 3.5+ only (failing with NameError on earlier versions) - anything that emulates __main__ execution in a namespace other than the interpreter provided one would also need to be updated to set the new attribute - it adds "Why is __name__ wrong in __main__?" to the list of historical relics that can only be explained in terms of "the modern alternative didn't always exist" Potentially still a net win, though - call it +0 from me. Cheers, Nick.
-- --Guido van Rossum (python.org/~guido)
_______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas

On Mon, Nov 25, 2013 at 1:10 PM, Nick Coghlan <ncoghlan@gmail.com> wrote:
On 26 Nov 2013 05:51, "Guido van Rossum" <guido@python.org> wrote:
On Mon, Nov 25, 2013 at 11:42 AM, Barry Warsaw <barry@python.org> wrote:
On Nov 26, 2013, at 01:12 AM, Steven D'Aprano wrote:
(1) Keep the status quo.
I'd have no problem with this. The current idiom doesn't seem broken
nor is it that hard to type. I also don't think it's very hard to discover given how common it is.
All agreed, yet it is not that easy to type either (underscores and quotes require the shift key). Perhaps more important, it causes everyone who sees it first to wonder why the idiom isn't simpler.
if __main__:
If we *had* to make this easier to type, this would be my choice. It
doesn't
even have to be read-only, given that __name__ can be messed with, but usually isn't. Why then worry about __main__ getting messed with?
The problem with this is, how would you implement this? You can either make __main__ a builtin object with a magic __bool__() method, or you can
to me, plunk a bool named __main__ in every module namespace. I don't much like either.
Shadowing would allow this to work without magic and with changes to only two modules: you could have a builtin __main__ that was always False and then set a __main__=True attribute in the main module.
This still teaches the lesson about runtime introspection *and* could be used to teach an important lesson about name shadowing.
Like Barry, this is my favourite of the suggestions so far, but I'm still not sure it's worth the hassle:
- any such code would automatically be 3.5+ only (failing with NameError on earlier versions) - anything that emulates __main__ execution in a namespace other than the interpreter provided one would also need to be updated to set the new attribute - it adds "Why is __name__ wrong in __main__?" to the list of historical relics that can only be explained in terms of "the modern alternative didn't always exist"
Potentially still a net win, though - call it +0 from me.
Still only -0 from me, mostly because of the first two of your items, and because it just replaces one kind of magic with another. But mostly I don't see why it has to involve a __dunder__ name (other reminding the reader of the old idiom). The reason for using __dunder__ style for __name__ and '__main__' was clear: they impose on namespaces that are nominally the user's (__name__ is a global variable, the value '__main__' is a module name, we don't want to interfere with a user-defined global variable named 'name' nor with a user-defined module named 'main'). But we don't need the same kind of caution for builtins (if the use defines a variable is_builtin that variable wins). (I don't get the point against my is_main() proposal that it also uses magic. It's a builtin. *Of course* it is allowed to use magic.) -- --Guido van Rossum (python.org/~guido)

On Mon, 25 Nov 2013 13:22:53 -0800 Guido van Rossum <guido@python.org> wrote:
(I don't get the point against my is_main() proposal that it also uses magic. It's a builtin. *Of course* it is allowed to use magic.)
Just because it is allowed to use magic doesn't mean it's a good idea, though. I can imagine people struggling to understand how it works (and how they can replicate it), while the current idiom is very easy to understand. I still don't think the current idiom is problematic, so I'm -0.8 on the whole thing :-) Regards Antoine.

On Mon, Nov 25, 2013 at 1:44 PM, Antoine Pitrou <solipsis@pitrou.net> wrote:
On Mon, 25 Nov 2013 13:22:53 -0800 Guido van Rossum <guido@python.org> wrote:
(I don't get the point against my is_main() proposal that it also uses magic. It's a builtin. *Of course* it is allowed to use magic.)
Just because it is allowed to use magic doesn't mean it's a good idea, though.
Really? Many builtins do huge amounts of magic.
I can imagine people struggling to understand how it works (and how they can replicate it), while the current idiom is very easy to understand.
Hm. I think most people who wonder how it works would learn something from figuring it out (like I did as a child disassembling my mother's vacuum cleaner :-). But most everyone else wonders why this is such a strange idiom.
I still don't think the current idiom is problematic, so I'm -0.8 on the whole thing :-)
Check the length of this thread. (And the ones before it. :-) -- --Guido van Rossum (python.org/~guido)

On Mon, 25 Nov 2013 13:57:57 -0800 Guido van Rossum <guido@python.org> wrote:
I still don't think the current idiom is problematic, so I'm -0.8 on the whole thing :-)
Check the length of this thread. (And the ones before it. :-)
Well, the #1 complaint seems be that it's not terribly pretty. That doesn't sound like a huge problem to me :-) Am I missing something? (I also understand that it relies on a more-or-less implementation detail, but the implementation detail will have to stay for compatibility reasons, anyway) Regards Antoine.

On Mon, Nov 25, 2013 at 3:14 PM, Antoine Pitrou <solipsis@pitrou.net> wrote:
(I also understand that it relies on a more-or-less implementation detail, but the implementation detail will have to stay for compatibility reasons, anyway)
What implementation detail are you talking about? -eric

On 11/25/2013 5:31 PM, Eric Snow wrote:
On Mon, Nov 25, 2013 at 3:14 PM, Antoine Pitrou <solipsis@pitrou.net> wrote:
(I also understand that it relies on a more-or-less implementation detail, but the implementation detail will have to stay for compatibility reasons, anyway)
What implementation detail are you talking about?
The fact that .__name__ is set to "__main__" in the main module. -- Terry Jan Reedy

On Mon, Nov 25, 2013 at 4:37 PM, Terry Reedy <tjreedy@udel.edu> wrote:
On 11/25/2013 5:31 PM, Eric Snow wrote:
On Mon, Nov 25, 2013 at 3:14 PM, Antoine Pitrou <solipsis@pitrou.net> wrote:
(I also understand that it relies on a more-or-less implementation detail, but the implementation detail will have to stay for compatibility reasons, anyway)
What implementation detail are you talking about?
The fact that .__name__ is set to "__main__" in the main module.
I don't see why that's an implementation detail. The language reference specifies that scripts are run in the namespace of the main module and that it's named "__main__". [1][2] -eric [1] http://docs.python.org/3.4/reference/executionmodel.html#naming-and-binding [2] http://docs.python.org/3.4/reference/toplevel_components.html#complete-pytho...

On 25 November 2013 21:44, Antoine Pitrou <solipsis@pitrou.net> wrote:
On Mon, 25 Nov 2013 13:22:53 -0800 Guido van Rossum <guido@python.org> wrote:
(I don't get the point against my is_main() proposal that it also uses magic. It's a builtin. *Of course* it is allowed to use magic.)
Just because it is allowed to use magic doesn't mean it's a good idea, though. I can imagine people struggling to understand how it works (and how they can replicate it), while the current idiom is very easy to understand.
I still don't think the current idiom is problematic, so I'm -0.8 on the whole thing :-)
Also, the current idiom is in use in an immense amount of documentation and existing code. That's not going away, so people now have *two* ways of saying the same thing. And to be honest, I suspect many of the "old hands" will simply ignore the new idiom and continue using (and teaching others, by example if nothing else) the old one - so it's not even as if the old idiom is going to disappear. If we were starting from scratch, is_main() might be a reasonable proposal, but I don't see the value given that we're not. I'm definitely at least -0.5. And I can't see myself ever using the new style even if it's implemented. Paul. PS This is assuming that nobody is suggesting breaking "if __name__ == '__main__'". If they are, then that's a whole different debate.

On Mon, Nov 25, 2013 at 2:28 PM, Paul Moore <p.f.moore@gmail.com> wrote:
PS This is assuming that nobody is suggesting breaking "if __name__ == '__main__'". If they are, then that's a whole different debate.
My proposal is to define the builtin function as comparing __name__ to '__main__', so the old idiom will still work. It will just eventually start looking out of date. -- --Guido van Rossum (python.org/~guido)

Paul Moore writes:
And to be honest, I suspect many of the "old hands" will simply ignore the new idiom and continue using (and teaching others, by example if nothing else) the old one - so it's not even as if the old idiom is going to disappear.
Yup. In my XEmacs init, I have a Python-specific "script" skeleton that produces it (including a call to "main()" and other boilerplate) automatically, and if python-dev doesn't break it, I won't fix it.

On Nov 25, 2013, at 01:22 PM, Guido van Rossum wrote:
Still only -0 from me, mostly because of the first two of your items, and because it just replaces one kind of magic with another.
Just to continue playing along (since I have no problem with the current idiom), I do like Nick's shadowing idea. I guess what I don't like about is_main() is that it's a function call, and is two words separated by an underscore. I have no technical arguments against it, just that to me it doesn't look as pretty. And also, I guess, a function call seems a little more magical than checking an attribute value. What does the function *do*? OTOH, I guess a shadowed builtin variable is a little magical too, but maybe a touch more transparent magic. ;)
But mostly I don't see why it has to involve a __dunder__ name (other reminding the reader of the old idiom). The reason for using __dunder__ style for __name__ and '__main__' was clear: they impose on namespaces that are nominally the user's (__name__ is a global variable, the value '__main__' is a module name, we don't want to interfere with a user-defined global variable named 'name' nor with a user-defined module named 'main'). But we don't need the same kind of caution for builtins (if the use defines a variable is_builtin that variable wins).
I don't think we could use a builtin called "main", because you'd get some confusions like this: def main(): # blah blah if main: main() OTOH, maybe that's actually kind of cute. It means a builtin `main` could be False and no implicit shadowing would be necessary. I guess some folks don't like to call their main function main() so maybe that wouldn't work for them, but it's not like the old idiom would go away. Except: you surely could have main() functions in other modules which aren't run as scripts, so that would break. Okay, never mind. But I do think that this means any magic builtin would have to be dundered. Even is_main() could be a legitimate name for a function in an existing module. -Barry

On Mon, Nov 25, 2013 at 2:16 PM, Barry Warsaw <barry@python.org> wrote:
On Nov 25, 2013, at 01:22 PM, Guido van Rossum wrote:
Still only -0 from me, mostly because of the first two of your items, and because it just replaces one kind of magic with another.
Just to continue playing along (since I have no problem with the current idiom), I do like Nick's shadowing idea.
I guess what I don't like about is_main() is that it's a function call, and is two words separated by an underscore. I have no technical arguments against it, just that to me it doesn't look as pretty. And also, I guess, a function call seems a little more magical than checking an attribute value. What does the function *do*? OTOH, I guess a shadowed builtin variable is a little magical too, but maybe a touch more transparent magic. ;)
For all I care you can call it ismain(). But it should be a function so that it's clear that the same function can return a different value in different contexts. Variables that have different values in different contexts should be set by the user (technically they'd be different variables, even if they have the same name). For system stuff that varies by context, we use functions, since a function can dynamically look at the context. (For example, globals() and locals().)
But mostly I don't see why it has to involve a __dunder__ name (other reminding the reader of the old idiom). The reason for using __dunder__ style for __name__ and '__main__' was clear: they impose on namespaces that are nominally the user's (__name__ is a global variable, the value '__main__' is a module name, we don't want to interfere with a user-defined global variable named 'name' nor with a user-defined module named 'main'). But we don't need the same kind of caution for builtins (if the use defines a variable is_builtin that variable wins).
I don't think we could use a builtin called "main", because you'd get some confusions like this:
def main(): # blah blah
if main: main()
OTOH, maybe that's actually kind of cute. It means a builtin `main` could be False and no implicit shadowing would be necessary. I guess some folks don't like to call their main function main() so maybe that wouldn't work for them, but it's not like the old idiom would go away.
Except: you surely could have main() functions in other modules which aren't run as scripts, so that would break. Okay, never mind.
But I do think that this means any magic builtin would have to be dundered. Even is_main() could be a legitimate name for a function in an existing module.
That seems a logic mistake. By that reasoning we would have to be as careful with new builtins as we are with new keywords. But that's not the case. Adding is_main() to builtins is not going to break code that currently defines a global named 'is_main'. Sure, that code cannot also use the new builtin, but that's expected. -- --Guido van Rossum (python.org/~guido)

On Mon, Nov 25, 2013 at 3:39 PM, Barry Warsaw <barry@python.org> wrote:
On Nov 25, 2013, at 02:29 PM, Guido van Rossum wrote:
For all I care you can call it ismain().
Okay, I think I'm going to officially not care now. :) None of these suggestions seem worth the effort to indoctrinate folks to some new idiom, regardless of how it's spelled.
+1 -eric

On Mon, Nov 25, 2013 at 2:39 PM, Barry Warsaw <barry@python.org> wrote:
On Nov 25, 2013, at 02:29 PM, Guido van Rossum wrote:
For all I care you can call it ismain().
Okay, I think I'm going to officially not care now. :) None of these suggestions seem worth the effort to indoctrinate folks to some new idiom, regardless of how it's spelled.
I mostly agree -- but if people insist on a better idiom, a builtin function is the only one I can live with. I don't particularly care what that builtin function is called, as long as it is not a __dunder__ name. And it must be a function. -- --Guido van Rossum (python.org/~guido)

On Nov 25, 2013, at 02:29 PM, Guido van Rossum wrote:
For all I care you can call it ismain().
IMHO the ismain() function is (at least so far) the best option -- because: * it separates the "is it the main module" check from its implementation details (__name__ == '__main__') so in a far future (Py 4.0?) it may become be possible to change those details (e.g. if they do not fit well with the import machinery logic); * beautiful is better than ugly (and -- IMHO -- the current idiom is too ugly + inconvenient to type, especially as a common boilerplate...); * after allowing to pass in an optional stack frame explicitly, it could make possible (or at least far easier) to test script ("run-as-the-main=module") behaviour, e.g.: def test_my_module_as_script(self): _orig_ismain = builtins.ismain def _mocked_ismain(module_frame=None): if module_frame is None: module_frame = sys._getframe(1) name = module_frame.f_globals['__name__'] if name == 'my_module': return True return _orig_ismain(module_frame) with unittest.mock.patch('bultins.ismain', _mocked_ismain): sys.modules.pop('my_module') import my_module <asserts...> * the feature could be easily backported to older Python versions == as a 3rd party module or just not so complex boilerplate code: # import_me_anywhere_before_using_the_ismain_function.py: import builtins, sys def ismain(module_frame=None): if module_frame is None: module_frame = sys._getframe(1) return module_frame.f_globals['__name__'] == '__main__' builtins.ismain = ismain Cheers. *j

On 11/25/2013 04:50 PM, Guido van Rossum wrote:
On Mon, Nov 25, 2013 at 2:39 PM, Barry Warsaw <barry@python.org <mailto:barry@python.org>> wrote:
On Nov 25, 2013, at 02:29 PM, Guido van Rossum wrote:
>For all I care you can call it ismain().
Okay, I think I'm going to officially not care now. :) None of these suggestions seem worth the effort to indoctrinate folks to some new idiom, regardless of how it's spelled.
I mostly agree -- but if people insist on a better idiom, a builtin function is the only one I can live with. I don't particularly care what that builtin function is called, as long as it is not a __dunder__ name. And it must be a function.
I'm +1 on the builtin function alternative if it compares the actual modules rather than just the names. Then it would have some benefits I think. It could be used within functions. Currently __name__ is masked by the function's __name__ attribute if you try that. It would still work if someone overwrites __name__. Not that I think it happens very often. And I don't care if it's spelled ismain or is_main. Well actually I like the underscores separating words in function names. But we have isattribute() which already doesn't follow that. So which ever is more consistent. Cheers, Ron

On Mon, Nov 25, 2013 at 9:37 PM, Ron Adam <ron3200@gmail.com> wrote:
It could be used within functions. Currently __name__ is masked by the function's __name__ attribute if you try that.
That's news to me. It was not so as of 3.3.3: Python 3.3.3 (default, Nov 25 2013, 15:41:46)
def f(): ... print(__name__) ... f() __main__
If anything, it is a magic function relying on _getframe() run-time introspection that would have a problem working inside functions.

On 11/25/2013 09:04 PM, Alexander Belopolsky wrote:
That's news to me. It was not so as of 3.3.3:
Python 3.3.3 (default, Nov 25 2013, 15:41:46)
def f(): ... print(__name__) ... f() __main__
If anything, it is a magic function relying on _getframe() run-time introspection that would have a problem working inside functions.
Woops.. yep. Hmmm, Wonder what I came across recently to make me think that. Oh well. I still think there would be some advantages from comparing the actual modules rather than the __name__ attribute. Jan pointed out some use cases. Cheers, Ron

On 25.11.2013 23:39, Barry Warsaw wrote:
On Nov 25, 2013, at 02:29 PM, Guido van Rossum wrote:
For all I care you can call it ismain().
Okay, I think I'm going to officially not care now. :) None of these suggestions seem worth the effort to indoctrinate folks to some new idiom, regardless of how it's spelled.
+1 As long as "if __name__ == '__main__': ..." doesn't stop working, I don't care either :-) -- Marc-Andre Lemburg eGenix.com Professional Python Services directly from the Source (#1, Nov 26 2013)
Python Projects, Consulting and Support ... http://www.egenix.com/ mxODBC.Zope/Plone.Database.Adapter ... http://zope.egenix.com/ mxODBC, mxDateTime, mxTextTools ... http://python.egenix.com/
::::: Try our mxODBC.Connect Python Database Interface for free ! :::::: eGenix.com Software, Skills and Services GmbH Pastor-Loeh-Str.48 D-40764 Langenfeld, Germany. CEO Dipl.-Math. Marc-Andre Lemburg Registered at Amtsgericht Duesseldorf: HRB 46611 http://www.egenix.com/company/contact/

On 25 November 2013 22:29, Guido van Rossum <guido@python.org> wrote:
I guess what I don't like about is_main() is that it's a function call, and is two words separated by an underscore. I have no technical arguments against it, just that to me it doesn't look as pretty. And also, I guess, a function call seems a little more magical than checking an attribute value. What does the function *do*? OTOH, I guess a shadowed builtin variable is a little magical too, but maybe a touch more transparent magic. ;)
For all I care you can call it ismain().
But it should be a function so that it's clear that the same function can return a different value in different contexts.
How is that clear? That's precisely what functions don't normally do (in Python, maths, other programming languages...). There already seems to be confusion around the magical super() function precisely because it does different things in different contexts and this is unexpected of something that uses function call syntax. Oscar

On 11/25/2013 03:37 PM, Oscar Benjamin wrote:
On 25 November 2013 22:29, Guido van Rossum <guido@python.org> wrote:
I guess what I don't like about is_main() is that it's a function call, and is two words separated by an underscore. I have no technical arguments against it, just that to me it doesn't look as pretty. And also, I guess, a function call seems a little more magical than checking an attribute value. What does the function *do*? OTOH, I guess a shadowed builtin variable is a little magical too, but maybe a touch more transparent magic. ;)
For all I care you can call it ismain().
But it should be a function so that it's clear that the same function can return a different value in different contexts.
How is that clear? That's precisely what functions don't normally do (in Python, maths, other programming languages...).
Any function which deals with the outside world returns different values based on context (aka the real world): - date - time - disk - geo-location - locals() - globals() - vars() etcetera, etcetera, and so-forth. -- ~Ethan~

The only other possibility not mentioned thus far is to have a main.py file and force python programs to start from it. markj

On 26 Nov 2013 10:00, "Mark Janssen" <dreamingforward@gmail.com> wrote:
The only other possibility not mentioned thus far is to have a main.py file and force python programs to start from it.
Looking for a __main__.py module (or submodule) is the way directory, zipfile and package execution work, so this style is already possible today for anyone that wants or needs it. Cheers, Nick.
markj _______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas

I think the need to change * if __ name__ == "__main__": * is capricious and obsessive. The current rule is better than anything that has been suggested so far. I never had any problems with the * if __ name__ == "__main__": *. Also in python there are other things much more difficult to learn and use, such as metaclasses.

On Nov 26, 2013, at 8:34, Alan Cristhian Ruiz <alan.cristh@gmail.com> wrote:
I think the need to change * if __ name__ == "__main__": * is capricious and obsessive. The current rule is better than anything that has been suggested so far. I never had any problems with the * if __ name__ == "__main__": *. Also in python there are other things much more difficult to learn and use, such as metaclasses.
Although I agree with your main point, I don't think that's a very good argument. __main__ is something novices have to learn early and use in code regularly; metaclasses are something only experienced developers use, and not that often (and that's even if you count using stdlib metaclasses to, e.g., create ABCs, which doesn't really require you to understand how they work). It's perfectly reasonable for an "expert" feature to be more difficult to learn than a novice feature. Also, Python doesn't have a queue of improvements to be scheduled to a team of developers. Things get improved if someone is motivated enough to write the code and drive the idea to consensus and/or BDFL approval. So, improving this would have very little bearing on improving things you care about more.

my cent: I think it's most often a bad practice (whereas it's convenient) to mix "executable" and "importable" code. Providing an easier way to do it, may encourage a bad practice. I would prefer a solution which encourage separation of "executable" and "importable" code. 2013/11/26 Andrew Barnert <abarnert@yahoo.com>
On Nov 26, 2013, at 8:34, Alan Cristhian Ruiz <alan.cristh@gmail.com> wrote:
I think the need to change * if __ name__ == "__main__": * is capricious and obsessive. The current rule is better than anything that has been suggested so far. I never had any problems with the * if __ name__ == "__main__": *. Also in python there are other things much more difficult to learn and use, such as metaclasses.
Although I agree with your main point, I don't think that's a very good argument.
__main__ is something novices have to learn early and use in code regularly; metaclasses are something only experienced developers use, and not that often (and that's even if you count using stdlib metaclasses to, e.g., create ABCs, which doesn't really require you to understand how they work). It's perfectly reasonable for an "expert" feature to be more difficult to learn than a novice feature.
Also, Python doesn't have a queue of improvements to be scheduled to a team of developers. Things get improved if someone is motivated enough to write the code and drive the idea to consensus and/or BDFL approval. So, improving this would have very little bearing on improving things you care about more. _______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas

On Wed, Nov 27, 2013 at 9:58 AM, Gregory Salvan <apieum@gmail.com> wrote:
my cent: I think it's most often a bad practice (whereas it's convenient) to mix "executable" and "importable" code. Providing an easier way to do it, may encourage a bad practice.
I would prefer a solution which encourage separation of "executable" and "importable" code.
The only way to do that is to force people to put their executable code in a __main__.py file and prevent class and function definitions within that... Gross. People need the test for main or not (imported or not) because they write unit tests for _all_ of their code, including their main program. Just because it can be imported does not mean it is a library that anyone outside of their tests _should_ import. Sure, there are some python stdlib modules and others that work as an importable library or via python -m modulename to run a program but I wouldn't call that the common case. I would not want that to stop working either. -gps
2013/11/26 Andrew Barnert <abarnert@yahoo.com>
On Nov 26, 2013, at 8:34, Alan Cristhian Ruiz <alan.cristh@gmail.com> wrote:
I think the need to change * if __ name__ == "__main__": * is capricious and obsessive. The current rule is better than anything that has been suggested so far. I never had any problems with the * if __ name__ == "__main__": *. Also in python there are other things much more difficult to learn and use, such as metaclasses.
Although I agree with your main point, I don't think that's a very good argument.
__main__ is something novices have to learn early and use in code regularly; metaclasses are something only experienced developers use, and not that often (and that's even if you count using stdlib metaclasses to, e.g., create ABCs, which doesn't really require you to understand how they work). It's perfectly reasonable for an "expert" feature to be more difficult to learn than a novice feature.
Also, Python doesn't have a queue of improvements to be scheduled to a team of developers. Things get improved if someone is motivated enough to write the code and drive the idea to consensus and/or BDFL approval. So, improving this would have very little bearing on improving things you care about more. _______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas
_______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas

On 11/30/2013 06:03 PM, Gregory P. Smith wrote:
On Wed, Nov 27, 2013 at 9:58 AM, Gregory Salvan wrote:
my cent: I think it's most often a bad practice (whereas it's convenient) to mix "executable" and "importable" code. Providing an easier way to do it, may encourage a bad practice.
I would prefer a solution which encourage separation of "executable" and "importable" code.
The only way to do that is to force people to put their executable code in a __main__.py file and prevent class and function definitions within that... Gross.
People need the test for main or not (imported or not) because they write unit tests for _all_ of their code, including their main program. Just because it can be imported does not mean it is a library that anyone outside of their tests _should_ import. Sure, there are some python stdlib modules and others that work as an importable library or via python -m modulename to run a program but I wouldn't call that the common case. I would not want that to stop working either.
+1 to gps' statements. -- ~Ethan~

On Tue, Nov 26, 2013 at 3:01 AM, Nick Coghlan <ncoghlan@gmail.com> wrote:
On 26 Nov 2013 10:00, "Mark Janssen" <dreamingforward@gmail.com> wrote:
The only other possibility not mentioned thus far is to have a main.py file and force python programs to start from it.
Looking for a __main__.py module (or submodule) is the way directory, zipfile and package execution work, so this style is already possible
today
for anyone that wants or needs it.
It also doesn't work so well for non-packages. :) That said, I like how __main__.py makes a clear separation between the package and its script form. As I said in my opening email, I think that distinction is very fuzzy for modules in general and bites both beginners and advanced users. For me anything that proposed replacing the current "if __name__ == '__main__'" idiom should help make the script/module separation more distinct. -eric

That said, I like how __main__.py makes a clear separation between the
On Dec 6, 2013 9:29 AM, "Eric Snow" <ericsnowcurrently@gmail.com> wrote: package and its script form. As I said in my opening email, I think that distinction is very fuzzy for modules in general and bites both beginners and advanced users. For me anything that proposed replacing the current "if __name__ == '__main__'" idiom should help make the script/module separation more distinct. Regardless, it may be worth adding an additional approach to highlighting the script/module duality. We could raise a warning when a module (findable on sys.path) is run as script unless via the "-m" flag. -eric

I still don't like the decorator nor the magic function name. They don't offer the same functionality. -- --Guido van Rossum (python.org/~guido)

On Sun, Nov 24, 2013 at 11:37 AM, Steven D'Aprano <steve@pearwood.info> wrote:
On Sun, Nov 24, 2013 at 09:04:59AM +1100, Chris Angelico wrote:
Just a really crazy idea... Does Python let you go "one level outside" and tinker with the code that imports __main__? I haven't looked into all that mechanism, but I know quite a bit of it is now implemented in Python, so it's theoretically possible... could you, in effect, add a line of code *after* that import that effectively calls __main__.__main__(sys.argv) ? That would do most of what you want.
It sounds like you're describing an import hook, although such things are completely opaque to me. I know they exist, but I've got no idea how they work or what they can do.
I was more trying to get to the surrounding code. When a binary is executed, you fork a new process and exec it (on Unix). When a Python script is executed, something somewhere effectively goes: sys.argv = argv[1:] # trim off the 'python' and keep the rest import argv[1] as __main__ sys.exit() If that code exists in Python somewhere, or if you can in some way tinker with it, it would be possible to insert a call: import argv[1] as __main__ try: main = __main__.__main__ except NameError: main = lambda: None main() sys.exit() or similar. I could easily spin up a little C program that embeds Python, and then tinker with the exact startup sequence; is there a convenient way to do that in Python itself? Of course, it'd always be possible to rig something that gets invoked as: $ python3 x.py my_script_file.py but I'd rather replace the current startup code rather than augment it with another layer of indirection (and another file of code in the current directory). This would be a convenient way to experiment with theories like this, without fundamentally changing anything. What I'm thinking of here is how Pike (yeah, borrowing ideas again!) allows you to choose a different master; the default master does certain setups and then calls on your code, and by changing the master you can tinker with that. Normally you wouldn't need to, but it does make certain types of experimentation very convenient. ChrisA
participants (34)
-
Alan Cristhian Ruiz
-
Alexander Belopolsky
-
Andrew Barnert
-
Antoine Pitrou
-
Barry Warsaw
-
Bruce Leban
-
Cameron Simpson
-
Chris Angelico
-
David Mertz
-
Eric Snow
-
Ethan Furman
-
Georg Brandl
-
Greg Ewing
-
Gregory P. Smith
-
Gregory Salvan
-
Guido van Rossum
-
Haoyi Li
-
INADA Naoki
-
Jan Kaliszewski
-
M.-A. Lemburg
-
Mark Janssen
-
Markus Unterwaditzer
-
MRAB
-
Nick Coghlan
-
Oscar Benjamin
-
Paul Moore
-
Philipp A.
-
Rob Cliffe
-
Ron Adam
-
Sean McQuillan
-
Stephen J. Turnbull
-
Steven D'Aprano
-
Terry Reedy
-
אלעזר