Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python argparse select a list from choices

How do you use argparse to provide a list of arguments from a group of choices. For example, lets say I want something like:

python sample.py --p1 ['a','b'] --p2 ['x','y']

Where p1 can only be any or all from list of 'a', 'b', 'c' and p2 can only be any or all from list of 'x', 'y', 'z'

like image 448
user1179317 Avatar asked Sep 08 '20 03:09

user1179317


2 Answers

I found a way to get the behavior you want, but with a different syntax than what you present. You have to specify each choice with a unique parameter name/value pair. If that's ok, then the following works:

parser = argparse.ArgumentParser(prog='game.py')
parser.add_argument('--p1', choices=['a', 'b', 'c'], action='append')
args = parser.parse_args(['--p1', 'a', '--p1', 'b'])
print(args)

Result:

Namespace(p1=['a', 'b'])

but this fails appropriately:

parser = argparse.ArgumentParser(prog='game.py')
parser.add_argument('--p1', choices=['a', 'b', 'c'], action='append')
args = parser.parse_args(['--p1', 'a', '--p1', 'b', '--p1', 'x'])
print(args)

Result:

usage: game.py [-h] [--p1 {a,b,c}]
game.py: error: argument --p1: invalid choice: 'x' (choose from 'a', 'b', 'c')

I can find nothing in the docs that suggests that ArgumentParser will take a list of valid values as a parameter value, which is what your version would require.

like image 155
CryptoFool Avatar answered Sep 23 '22 06:09

CryptoFool


Using nargs with choices:

In [1]: import argparse
In [2]: p = argparse.ArgumentParser()
In [3]: p.add_argument('-a',nargs='+', choices=['x','y','z'])
Out[3]: _StoreAction(option_strings=['-a'], dest='a', nargs='+', const=None, default=None, type=None, choices=['x', 'y', 'z'], help=None, metavar=None)

In [4]: p.parse_args('-a x y z x x'.split())
Out[4]: Namespace(a=['x', 'y', 'z', 'x', 'x'])

In [5]: p.parse_args('-a x y z w x'.split())
usage: ipython3 [-h] [-a {x,y,z} [{x,y,z} ...]]
ipython3: error: argument -a: invalid choice: 'w' (choose from 'x', 'y', 'z')
like image 24
hpaulj Avatar answered Sep 26 '22 06:09

hpaulj