Re: Entrypoint function for modules (AKA if __name__ == '__main__' ) with built-in argument parsing
Ouch! That's what happens when you don't proof read your emails :S Replace --verbose with --print_operation, the idea of the snippet was to show an example for keyword parameters.
On Jul 31, 2019, at 06:28, Agustín Scaramuzza <agustinscaramuzza@gmail.com> wrote:
Ouch! That's what happens when you don't proof read your emails :S
Replace --verbose with --print_operation, the idea of the snippet was to show an example for keyword parameters.
OK, so how does the magic code know that print_operation is a flag that takes no arguments? Especially if I type this: python run.py —print_operation 1 2 With argparse, getopt, click, etc., this works because I’ve specified that it’s a zero-argument flag; if I hadn’t, it would be equivalent to —print_operation=1, with 2 as the first positional arg. Does the default value of False somehow imply that? (Also, with any of those libraries, I could call it the more normal —print-operation. And the help would be generated automatically instead of making me keep the docstring and the code in sync and quite possibly get it wrong. And so on. It would help if you designed a library to do this, so you could show how it works (and why it’s better than, e.g., fire to write the same program). The bit about running __run__ automagically is the easy part: import sys main = sys.modules['__main__'] run = getattr(main, '__run__') args, kw = sys.argv[1:], {} run(*args, **kw) … which you can then use in a script by adding one line: def __run__(a, b=1): print(int(a) + int(b)) import my_run_lib Or you could rely on the function being installed as a setuptools entrypoint script and not even need the magic part. The hard part is designing and building the parse function that replaces that args, kw = line. You can use argparse to do the parsing, you can access inspect.signature(run) to build up the parser, etc., so there’s no magic at all needed there. Even with your idea about using annotations to “cast” things, the “magic” part is trivial—you can get the annotation values trivially from the signature or the function itself, and they’re going to be the builtin or global type or function values without you having to do anything. It’s deciding what to do with them that’s hard. And then of course you need to show why the result easier/better/whatever than things like fire, click, etc. Then the only question is why the implicit dispatch call is better than an explicit dispatcher call like fire’s and/or installing the function as a setuptools entrypoint script. If people are sold on that, they can probably be sold on making it slightly more magical by having Python always import this module at the end of __main__ (or do the equivalent). And then you’ve got your case for why it has to come with Python (because otherwise it requires some horrible monkeypatching, or hacking up __site__ with an import hook at install time or something). But if nobody is sold on it without that last bit of magic, I don’t think it’s nearly enough to make the idea compelling on its own. Also, if you have a design for a simplified semi-magical arg parser that actually is easier to use than fire and usable in more cases, even if you can’t get it accepted into Python, that seems like something you should write anyway and put on PyPI (maybe even with instructions or even a script for hacking __site__ or writing a user startup file to make it automatic), because I think a sizable number of people would want that. (In fact, even if you can get it accepted into Python, some people will want a backport that they can use with 3.7.
participants (2)
-
Agustín Scaramuzza
-
Andrew Barnert