Argh follows Argparse's grouping of arguments into two bunches:
"Positional" = determined by position and required (possibly optional with nargs set to ? or *)
"Optional" AKA "options" = determined by name e.g. --foo
The motivation is that "required options are generally considered bad form because users expect options to be optional, and thus they should be avoided when possible" as per Argparse docs.
Problem
Although it's a sensible approach that enforces better interfaces in general, in some cases this limitation is very unfortunate.
A real use case: I have a single command script with a few arguments that expect intrinsically very long strings as values (e.g. URLs, digests, etc.). The interface is simple, but the command is completely unreadable. If I want to share the command with args as example or read it in the logs, basically I have to split it line by line and insert comments. It doesn't make sense and the idea of a clean API leads to the worst possible API in practice (in this particular use case).
It would be useful if an argument could be both named and required, just like in Python:
def func(foo, bar):
...
# these calls are equivalent:
func(123, 456)
func(foo=123, bar=456)
Argh should not force the developer to always choose whether the argument is required or can be called by name. The following calls should be equivalent:
It should however force the developer to do an extra step when making a required argument look like an option to make sure they understand that it's not the norm and that they know what they are doing.
Currently a mix of a positional argument in the function signature (def func(foo):) with an option notation (@arg('--foo')) throws an exception on assembling stage.
Background
Argh follows Argparse's grouping of arguments into two bunches:
nargs
set to?
or*
)--foo
The motivation is that "required options are generally considered bad form because users expect options to be optional, and thus they should be avoided when possible" as per Argparse docs.
Problem
Although it's a sensible approach that enforces better interfaces in general, in some cases this limitation is very unfortunate.
A real use case: I have a single command script with a few arguments that expect intrinsically very long strings as values (e.g. URLs, digests, etc.). The interface is simple, but the command is completely unreadable. If I want to share the command with args as example or read it in the logs, basically I have to split it line by line and insert comments. It doesn't make sense and the idea of a clean API leads to the worst possible API in practice (in this particular use case).
It would be useful if an argument could be both named and required, just like in Python:
Argh should not force the developer to always choose whether the argument is required or can be called by name. The following calls should be equivalent:
It should however force the developer to do an extra step when making a required argument look like an option to make sure they understand that it's not the norm and that they know what they are doing.
Currently a mix of a positional argument in the function signature (
def func(foo):
) with an option notation (@arg('--foo')
) throws an exception on assembling stage.Solution
It seems that the usual workaround for this is adding
required=True
and putting the argument under a special group, see https://stackoverflow.com/questions/24180527/argparse-required-arguments-listed-under-optional-arguments