3

I'm trying to write a script in which a user can choose from three different options:

python foo.py 
python foo.py -a
python foo.py -b address_arg data_arg

If the user chooses the last option I need them to provide two additional arguments for address and data.

I currently have it working so that it requires one argument, say for the address here:

parser.add_argument('-b', '--boo', dest='address', type=str, help="Help message")

Which works if I run

python foo.py -b 0x00

But how do I require the user provide the second argument for data?

gravytrain
  • 73
  • 5

2 Answers2

6

You can set the number of expected args with nargs=2.

https://docs.python.org/3/library/argparse.html#the-add-argument-method

>>> import argparse
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('-b', '--bar', nargs=2)
_StoreAction(option_strings=['-b', '--bar'], dest='bar', nargs=2, const=None, default=None, type=None, choices=None, help=None, metavar=None)
>>> args = parser.parse_args(['--bar', 'arg1', 'arg2'])
>>> args.bar
['arg1', 'arg2']
>>> args = parser.parse_args(['--bar', 'arg1'])
usage: [-h] [-b BAR BAR]
: error: argument -b/--bar: expected 2 arguments

Note that here the displayed help shows -b BAR BAR, which is kind of annoying (it duplicates the argument name by default). You can set metavar to a tuple to display better help messages for the two arguments you need to pass.

>>> parser.add_argument('-f', '--foo', nargs=2, metavar=('desc1', 'desc2'))
_StoreAction(option_strings=['-f', '--foo'], dest='foo', nargs=2, const=None, default=None, type=None, choices=None, help=None, metavar=('desc1', 'desc2'))
>>> parser.print_help()
usage: [-h] [-b BAR BAR] [-f desc1 desc2]

optional arguments:
  -h, --help            show this help message and exit
  -b BAR BAR, --bar BAR BAR
  -f desc1 desc2, --foo desc1 desc2

For more on that, see here: https://docs.python.org/3/library/argparse.html#metavar

alkasm
  • 22,094
  • 5
  • 78
  • 94
  • Thank you! What if I need to require arg1 but allow arg2 to be optional? – gravytrain Sep 19 '18 at 19:24
  • @gravytrain You can use `nargs='+'` and it will error if at least one argument was not provided, and it lets you provide multiple arguments and packs all of them into a list. More here: https://docs.python.org/3/library/argparse.html#nargs. You can do further customization with the `action` that the other answerer suggested, which I'd recommend if you're doing complicated command line parsing. – alkasm Sep 19 '18 at 19:38
0

You enforce the extra argument in the action routine for -b.

In there, you check for the existence and validity of the data_arg you expect. For existence alone, a simple check for quantity of arguments will do the job.

Prune
  • 76,765
  • 14
  • 60
  • 81