One of my very, very, very favorite things about Python is argparse. [1]
Very few libraries creates its API so well as to transcend its origins (JodaTime comes to mind).
* Node.js [2]
* Java/JVM [3]
* Go [4]
* Lua [5]
* C++ [6] [7]
It appears there is no Swift port.
That is unfortunate, because besides the basics (optionals, positions, defaults, short and log options, auto generated docs, subcommands, descriptions, repeating options), it lets you do argument groups, mutually exclusive options, customizable help behavior, variable customization, custom parsers/validators, options with multiple arguments. There's even Python support for shell autocomplete library. [7].
(One potential limitation is that it is naturally dynamic, and not typesafe like Swift's new ArgumentParser. IMO that is of relatively small practical importance compared to its other features.)
It's both simple enough to get going, but sophisticated enough that I've never wanted for anything. It's the first thing I look for when writing a CLI.
I can't stand argparse. It's like they tried their hardest to force you to be imperative and prevent composability. For example, instead of being able to define a parser for a subcommand and build a top-lever parser from that, you need to do this:
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers()
a = subparsers.add_parser('a')
a.add_argument('bar')
A better API would look more like this:
Parser(Subparsers({
'a': Parser(Arg('bar')),
}))
On top of that it has a number of bugs in edge cases they refuse to document or fix. For example, you can't have a subcommand that always collects all the remaining arguments as-is. That's a pretty basic use-case when you want to pass those arguments to another program.
./example a arg1 arg2 arg3
./example a -- arg1 --look-ma-hyphens-arg2 arg3
If you're complaining about the double hyphen syntax....that's a universal convention for UNIX-ish CLI positional arguments. Otherwise things get really murky.
./example a --help
Did I want help on the `a` subcommand, or did I want to pass `--help` to the `a` subcommand? The `--` syntax lets you distinguish.
> Python is indeed an imperative language, along with the others I listed.
JavaScript has functional origins, and in practice quite a bit of JavaScript is written in a functional-lite style. As a JS developer, I find it quite infuriating that Python doesn't support these patterns, as they make code a lot more readable, and it seems to be a matter of principle rather than a technical limitation.
> Very few libraries creates its API so well as to transcend its origins
At least in the argument parsing space, docopt[0] did as well, with official implementations in ~22 languages. It might not always be the best native approach, but the one I will reach for when I have to do argument parsing in a new language.
Argparse is fantastic. I recently had to shift some code from taking input from a csv to taking input from command line and I was dreading how much coding it'd involve. It took me 5 minutes of googling to come across argparse and another minute to find my exact use case written out in 5 lines of code.
The kicker is that once you define it and let it capture inputs, it outputs absolutely standard professional level error messages for bad parameters. I did not have to write any exception handling code at all. I could not believe that what I thought would take me several days was done in less than an hour.
Very few libraries creates its API so well as to transcend its origins (JodaTime comes to mind).
* Node.js [2]
* Java/JVM [3]
* Go [4]
* Lua [5]
* C++ [6] [7]
It appears there is no Swift port.
That is unfortunate, because besides the basics (optionals, positions, defaults, short and log options, auto generated docs, subcommands, descriptions, repeating options), it lets you do argument groups, mutually exclusive options, customizable help behavior, variable customization, custom parsers/validators, options with multiple arguments. There's even Python support for shell autocomplete library. [7].
(One potential limitation is that it is naturally dynamic, and not typesafe like Swift's new ArgumentParser. IMO that is of relatively small practical importance compared to its other features.)
It's both simple enough to get going, but sophisticated enough that I've never wanted for anything. It's the first thing I look for when writing a CLI.
[1] https://docs.python.org/3/library/argparse.html
[2] http://nodeca.github.io/argparse/
[3] https://argparse4j.github.io/
[4] https://github.com/akamensky/argparse
[5] https://github.com/mpeterv/argparse
[6] https://github.com/jbms/argparse
[7] https://github.com/mmahnic/argumentum
[8] https://pypi.org/project/argcomplete/