Argparse: Required arguments listed under "optional arguments"? Argparse: Required arguments listed under "optional arguments"? python python

Argparse: Required arguments listed under "optional arguments"?


Parameters starting with - or -- are usually considered optional. All other parameters are positional parameters and as such required by design (like positional function arguments). It is possible to require optional arguments, but this is a bit against their design. Since they are still part of the non-positional arguments, they will still be listed under the confusing header “optional arguments” even if they are required. The missing square brackets in the usage part however show that they are indeed required.

See also the documentation:

In general, the argparse module assumes that flags like -f and --bar indicate optional arguments, which can always be omitted at the command line.

Note: Required options are generally considered bad form because users expect options to be optional, and thus they should be avoided when possible.

That being said, the headers “positional arguments” and “optional arguments” in the help are generated by two argument groups in which the arguments are automatically separated into. Now, you could “hack into it” and change the name of the optional ones, but a far more elegant solution would be to create another group for “required named arguments” (or whatever you want to call them):

parser = argparse.ArgumentParser(description='Foo')parser.add_argument('-o', '--output', help='Output file name', default='stdout')requiredNamed = parser.add_argument_group('required named arguments')requiredNamed.add_argument('-i', '--input', help='Input file name', required=True)parser.parse_args(['-h'])
usage: [-h] [-o OUTPUT] -i INPUTFoooptional arguments:  -h, --help            show this help message and exit  -o OUTPUT, --output OUTPUT                        Output file namerequired named arguments:  -i INPUT, --input INPUT                        Input file name


Since I prefer to list required arguments before optional, I hack around it via:

    parser = argparse.ArgumentParser()    parser._action_groups.pop()    required = parser.add_argument_group('required arguments')    optional = parser.add_argument_group('optional arguments')    required.add_argument('--required_arg', required=True)    optional.add_argument('--optional_arg')    return parser.parse_args()

and this outputs:

usage: main.py [-h] [--required_arg REQUIRED_ARG]               [--optional_arg OPTIONAL_ARG]required arguments:  --required_arg REQUIRED_ARGoptional arguments:  --optional_arg OPTIONAL_ARG

I can live without 'help' showing up in the optional arguments group.


Building off of @Karl Rosaen

parser = argparse.ArgumentParser()optional = parser._action_groups.pop() # Edited this linerequired = parser.add_argument_group('required arguments')# remove this line: optional = parser...required.add_argument('--required_arg', required=True)optional.add_argument('--optional_arg')parser._action_groups.append(optional) # added this linereturn parser.parse_args()

and this outputs:

usage: main.py [-h] [--required_arg REQUIRED_ARG]           [--optional_arg OPTIONAL_ARG]required arguments:  --required_arg REQUIRED_ARGoptional arguments:  -h, --help                    show this help message and exit  --optional_arg OPTIONAL_ARG