Entrypoint function for modules (AKA if __name__ == '__main__' ) with built-in argument parsing

Maybe the def __main__() argument is already a dead horse, given the number of discussions it has created that have ended nowhere, but I think one argument in favour of its implementation would be including argument parsing in it, for example: # main.py def __run__(first_num, second_num, print_operation=False): """ Adds two numbers. positional arguments: - first_num: the first number. - second_num: the second number. optional arguments: - print_operation: prints the sum operation to stdout. """ result = int(first_num) + int(second_num) if print_operation: print(f'{first_num} + {second_num} = {result}') else: print(result) $ python main.py -h Adds two numbers. positional parameters: - first_num: the first number. - second_num: the second number. optional arguments: - print_operation: prints the sum operation to stdout. $ python main.py 1 2 --verbose 1 + 2 = 3 $ python main.py 1 2 3 The -h flag would print the function docstring. We could also add type hints for casting (I'm not entirely sure how feasible this is): def __run__(first_num: int, second_num: int, print_operation=False): ... result = first_num + second_num # no need for casting here ... Since __main__ is already a built-in function, I abstained from using it as the designated function name (I picked __run__, but any other suggestions would be welcome, also thought of __entrypoint__, __exec__). Thoughts?

I think you might find plac[1] and fire[2] rather interesting. I do feel an explicit __run__ would go against the spirit of "explicit is better than implicit" a bit... [1] https://micheles.github.io/plac/ [2] https://github.com/google/python-fire On Tue, Jul 30, 2019, 8:03 PM <agustinscaramuzza@gmail.com> wrote:

On Jul 30, 2019, at 15:21, agustinscaramuzza@gmail.com wrote:
Couldn’t you get nearly the same effect in Python today just by adding one line: __run__(*sys.argv[1:]) That doesn’t do any fancy parsing of the arguments, but, except for the -h magic, neither does your proposal. Also:
$ python main.py -h
Does —help also work? (It’s pretty weird that you use a long arg for verbose but a short arg for help.)
$ python main.py 1 2 --verbose 1 + 2 = 3
But if I run the same thing in the more traditional way: $ python main.py —verbose 1 2 … I’ll get an error, because the first argument isn’t an int and can’t be added to 1. Also: $ python main.py 1 2 —quiet … does the same thing as —verbose, which is pretty misleading. Not that I haven’t done the quick hacky “this script isn’t going to be used by anyone but me, and only for the next two days, and it only needs one flag, so just assume any third arg is that flag” thing. But that’s hardly something you want a language feature to actively encourage. There are lots of great third-party libraries that make turning a function into a command-line utility a lot easier than using argparse. I think whenever you want anything more than argv and don’t want argparse, you should probably just use one of those libraries.

On Jul 30, 2019, at 20:49, Andrew Barnert via Python-ideas <python-ideas@python.org> wrote:
There are lots of great third-party libraries that make turning a function into a command-line utility a lot easier than using argparse. I think whenever you want anything more than argv and don’t want argparse, you should probably just use one of those libraries.
That being said, maybe the docs should make that recommendation somewhere? For example, just as urllib.request points you to requests if you want a higher-level HTTP client, argparse could point you to click if you want something a little more automated and/or fire if you want something dead simple for a quick&dirty script. (Not necessarily those two; those are just the ones I’m most familiar with…) Or maybe there could be a mention in the tutorial, in the section on command-line arguments, which currently mentions getopt as the simple choice and argparse as the fancy one, but maybe it could instead mention fire, click, and argparse. (The getopt library is only really good when you’re familiar with C getopt and happen to be thinking in exactly those terms—as its own docs say up-top. So I’m not sure it’s a good idea for the tutorial to even mention it…)

Ouch, the tutorial definitely should no longer recommend getopt (or optparse) and just stick to argparse (or sys.argv[1:] if you want simple :-). I filed newcomer-friendly issue https://bugs.python.org/issue37726. The problem with recommending click or fire is that it doesn't look to me like any of those are category killers the way requests became years ago. On Tue, Jul 30, 2019 at 9:07 PM Andrew Barnert via Python-ideas < python-ideas@python.org> wrote:
-- --Guido van Rossum (python.org/~guido) *Pronouns: he/him/his **(why is my pronoun here?)* <http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-c...>

On Jul 30, 2019, at 21:18, Guido van Rossum <guido@python.org> wrote:
The problem with recommending click or fire is that it doesn't look to me like any of those are category killers the way requests became years ago.
Yeah, that’s true. And honestly, I can’t imagine how any of them _could_ become a category killer, because the category is just so broad; there are just too many things you sometimes want to be simpler or more automated than argparse, and they sometimes even conflict with each other. (For example, fire calling literal_eval on args is great for a lot of quick&dirty scripts, but would be disastrous for many other programs.) So… never mind.

I think you might find plac[1] and fire[2] rather interesting. I do feel an explicit __run__ would go against the spirit of "explicit is better than implicit" a bit... [1] https://micheles.github.io/plac/ [2] https://github.com/google/python-fire On Tue, Jul 30, 2019, 8:03 PM <agustinscaramuzza@gmail.com> wrote:

On Jul 30, 2019, at 15:21, agustinscaramuzza@gmail.com wrote:
Couldn’t you get nearly the same effect in Python today just by adding one line: __run__(*sys.argv[1:]) That doesn’t do any fancy parsing of the arguments, but, except for the -h magic, neither does your proposal. Also:
$ python main.py -h
Does —help also work? (It’s pretty weird that you use a long arg for verbose but a short arg for help.)
$ python main.py 1 2 --verbose 1 + 2 = 3
But if I run the same thing in the more traditional way: $ python main.py —verbose 1 2 … I’ll get an error, because the first argument isn’t an int and can’t be added to 1. Also: $ python main.py 1 2 —quiet … does the same thing as —verbose, which is pretty misleading. Not that I haven’t done the quick hacky “this script isn’t going to be used by anyone but me, and only for the next two days, and it only needs one flag, so just assume any third arg is that flag” thing. But that’s hardly something you want a language feature to actively encourage. There are lots of great third-party libraries that make turning a function into a command-line utility a lot easier than using argparse. I think whenever you want anything more than argv and don’t want argparse, you should probably just use one of those libraries.

On Jul 30, 2019, at 20:49, Andrew Barnert via Python-ideas <python-ideas@python.org> wrote:
There are lots of great third-party libraries that make turning a function into a command-line utility a lot easier than using argparse. I think whenever you want anything more than argv and don’t want argparse, you should probably just use one of those libraries.
That being said, maybe the docs should make that recommendation somewhere? For example, just as urllib.request points you to requests if you want a higher-level HTTP client, argparse could point you to click if you want something a little more automated and/or fire if you want something dead simple for a quick&dirty script. (Not necessarily those two; those are just the ones I’m most familiar with…) Or maybe there could be a mention in the tutorial, in the section on command-line arguments, which currently mentions getopt as the simple choice and argparse as the fancy one, but maybe it could instead mention fire, click, and argparse. (The getopt library is only really good when you’re familiar with C getopt and happen to be thinking in exactly those terms—as its own docs say up-top. So I’m not sure it’s a good idea for the tutorial to even mention it…)

Ouch, the tutorial definitely should no longer recommend getopt (or optparse) and just stick to argparse (or sys.argv[1:] if you want simple :-). I filed newcomer-friendly issue https://bugs.python.org/issue37726. The problem with recommending click or fire is that it doesn't look to me like any of those are category killers the way requests became years ago. On Tue, Jul 30, 2019 at 9:07 PM Andrew Barnert via Python-ideas < python-ideas@python.org> wrote:
-- --Guido van Rossum (python.org/~guido) *Pronouns: he/him/his **(why is my pronoun here?)* <http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-c...>

On Jul 30, 2019, at 21:18, Guido van Rossum <guido@python.org> wrote:
The problem with recommending click or fire is that it doesn't look to me like any of those are category killers the way requests became years ago.
Yeah, that’s true. And honestly, I can’t imagine how any of them _could_ become a category killer, because the category is just so broad; there are just too many things you sometimes want to be simpler or more automated than argparse, and they sometimes even conflict with each other. (For example, fire calling literal_eval on args is great for a lot of quick&dirty scripts, but would be disastrous for many other programs.) So… never mind.
participants (4)
-
agustinscaramuzza@gmail.com
-
Andrew Barnert
-
Guido van Rossum
-
Ryan Gonzalez