Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Argparse: Required arguments listed under "optional arguments"?

I use the following simple code to parse some arguments; note that one of them is required. Unfortunately, when the user runs the script without providing the argument, the displayed usage/help text does not indicate that there is a non-optional argument, which I find very confusing. How can I get python to indicate that an argument is not optional?

Here is the code:

import argparse if __name__ == '__main__':     parser = argparse.ArgumentParser(         description='Foo')     parser.add_argument('-i','--input', help='Input file name', required=True)     parser.add_argument('-o','--output', help='Output file name', default="stdout")     args = parser.parse_args()     print ("Input file: %s" % args.input )     print ("Output file: %s" % args.output ) 

When running above code without providing the required argument, I get the following output:

usage: foo.py [-h] -i INPUT [-o OUTPUT]  Foo  optional arguments:     -h, --help            show this help message and exit     -i INPUT, --input INPUT                           Input file name     -o OUTPUT, --output OUTPUT                           Output file name 
like image 296
mort Avatar asked Jun 12 '14 09:06

mort


People also ask

How do you add an optional argument in Argparse?

To add an optional argument, simply omit the required parameter in add_argument() . args = parser. parse_args()if args.

What is a compulsory argument?

Mandatory (or compulsory) arguments are arguments that have to be specified. Examples: If you want a footnote, you need to use the \footnote command, which has a mandatory argument that specifies the contents of the footnote.

How do you make an argument optional in Python?

You can define Python function optional arguments by specifying the name of an argument followed by a default value when you declare a function. You can also use the **kwargs method to accept a variable number of arguments in a function. To learn more about coding in Python, read our How to Learn Python guide.


2 Answers

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 INPUT  Foo  optional arguments:   -h, --help            show this help message and exit   -o OUTPUT, --output OUTPUT                         Output file name  required named arguments:   -i INPUT, --input INPUT                         Input file name 
like image 62
poke Avatar answered Nov 28 '22 09:11

poke


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_ARG  optional arguments:   --optional_arg OPTIONAL_ARG 

I can live without -h, --help showing up in the optional arguments group.

like image 38
Karl Rosaen Avatar answered Nov 28 '22 07:11

Karl Rosaen