New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How should argument parser help and usage message be displayed? #18687
Comments
@arezaii — Something not obvious to me (quite possibly due to lack of experience with argparse systems) is what the benefit of a number of predefined fields in the help/usage message is, as follows:
rather than having a single multi-line Also, if one of these is left blank / undefined, do we get a blank line, or is the entire line suppressed? Other comments: In:
to my eye, the all-caps headers look very old-school / man-page-y. The first thing I thought to look at to see what modern programs do was This makes me wonder whether we could identify programs that we'd consider to be good examples of modern usage/help messages that we'd want to model our choices after and use to guide answers to questions. That said, I'll take a stab at them all the same:
I think the user doesn't need to know the range indices, right, just the number of values? If that's correct, I'd probably come up with some way of indicating the number of arguments expected and keeping the indices to the implementation.
I think they should definitely be available somewhere/somehow, but don't have an intuition as to where/how. What do other programs do? I think for
It feels to me like printing both options in usage is overkill, but I'm also not sure whether I'd print just the shorter or longer versions. The longer versions obviously take more space, but are also more self-descriptive. I think mostly it seems to me that a program with a lot of options is probably going to need a manually curated usage line rather than an automatically generated one (which is not to say that the default one shouldn't do something reasonable, but I'm mentally comparing what an auto-generated usage would look like for
No strong insight here. |
The goal here is to provide flexibility to the user to customize the message in part, without having to replace the entire message or losing out on the auto-generated parts. For example, say I have a requirement to print out a short disclaimer before my help message, I can add that using I can also take advantage of generated field headings, alignment and spacing without having to fiddle with the format of my input.
The entire line would be suppressed, so the help message takes up only the vertical space it needs based on the defined fields.
I didn't look at individual apps so much as other argument parsing libraries. Python has adopted the lowercase headings, but both Rust and Swift have maintained uppercase headings. Here are some sample outputs from the other libraries I looked at: Python:
Rust:
Swift:
The commonality is that it looks like we could improve readability by adding an extra line between each heading. Apart from that, I prefer the look of the Swift output, but we can adapt/adopt any style we find reasonable.
Not sure if I got the right meaning. In the example, I was trying to express that the number of values is constrained by the range, so 4..10 expects at least 4 and at most 10 values and I am not sure how/if we should indicate that in the usage string. It may make more sense for the developer to choose to include that information in the
I didn't find much in the way of precedent to follow for these types of indicators.
There's mixed support for this. Python has an option to add them programmatically, but it appears to be all or nothing across every option/argument. Rust has the ability to specify the display property of a default value for every argument and sets them to display by default. Swift displays the defaults and it's not clear to me if this can be disabled. A compromise might be leaving it up to the developer to add them to the |
When the argument parser generates and displays help, how should it be formatted?
Depending on feedback here and on #18648, I was thinking of some format similar to this:
Other parsers give you some ability to modify the message format, with Rust having probably the most flexible/generous by way of custom templates. I'm not proposing anything that elegant, and initially the format would be fixed.
For a simple program like the quickstart example, the help output might look like:
There is still work to be done with pretty printing the help output with perfect column alignment and awareness of the screen size, this example is just using dumb tabs.
Usage Messages
For usage messages, I would propose ordering the parts something like this:
Where optional arguments or values are wrapped in
[ ]
and required ones are wrapped in< >
Subcommands are a little tricky because no individual subcommand can be required, but a program may require some selected subcommand to do anything useful. Ideally the main program should always support a call to
help
so technically the subcommand isn't required . Therefore, I propose that they are identified in the usage message as[SUBCOMMAND]
and have the help message list the available commands under theSUBCOMMANDS:
heading.There is a question of how multiple values should be indicated, and for simplicity I propose using
...
to indicate 'or more' values. Some output examples to demonstrate:[--flag <VAL>]
[--flag]
--flag <VAL ...>]
[--flag [VAL ...]]
[ ]
replaced with< >
It is less clear how to represent arguments which expect a specific range, say 4..10 values, or exactly 8 values.
Other questions:
Should default values for arguments and options be displayed in the help output? In the usage message? If so, how/where? This could be at the end of the help message for an argument/option, but not displayed at all in the case of flags and subcommands.
For flags/options with multiple possible identifiers, should they all be represented in the usage message? e.g. the usage message from the quickstart includes
[-h, --help]
, should it just display[-h]
there and the longer version in the help output underOPTIONS:
?For parsers that operate on subcommands, how to give them the whole path from the parent? That is, for a command like
mason add -h
, how to tell theadd
subcommand parser that the usage message should appendmason
? There could be a "parent" property on the argument parser, or that might be a reason to have separatebinaryName
andprogram
arguments, wherebinaryName
represents the path to the subcommand parser, whose name is represented inprogram
.The text was updated successfully, but these errors were encountered: