Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accessing the choices passed to argument in argparser?

Is it possible to access the tuple of choices passed to an argument? If so, how do I go about it

for example if I have

parser = argparse.ArgumentParser(description='choose location')
parser.add_argument(
    "--location",
    choices=('here', 'there', 'anywhere')
)
args = parser.parse_args()

can I access the tuple ('here', 'there', 'anywhere')?

like image 631
af3ld Avatar asked Sep 12 '16 23:09

af3ld


People also ask

How do you make an argument optional in Argparse?

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

What does Argparse return?

Later, calling parse_args() will return an object with two attributes, integers and accumulate . The integers attribute will be a list of one or more integers, and the accumulate attribute will be either the sum() function, if --sum was specified at the command line, or the max() function if it was not.


2 Answers

It turns out that parser.add_argument actually returns the associated Action. You can pick the choices off of that:

>>> import argparse
>>> parser = argparse.ArgumentParser(description='choose location')
>>> action = parser.add_argument(
...     "--location",
...     choices=('here', 'there', 'anywhere')
... )
>>> action.choices
('here', 'there', 'anywhere')

Note that (AFAIK) this isn't documented anywhere and may be considered an "implementation detail" and therefore subject to change without notice, etc. etc.

There also isn't any publicly accessible way to get at the actions stored on an ArgumentParser after they've been added. I believe that they are available as parser._actions if you're willing to go mucking about with implementation details (and assume any risks involved with that)...


Your best bet is to probably create a constant for the location choices and then use that in your code:

LOCATION_CHOICES = ('here', 'there', 'anywhere')

parser = argparse.ArgumentParser(description='choose location')
parser.add_argument(
    "--location",
    choices=LOCATION_CHOICES
)
args = parser.parse_args()

# Use LOCATION_CHOICES down here...
like image 123
mgilson Avatar answered Sep 29 '22 18:09

mgilson


There might be a better way, but I don't see any in the documentation. If you know the parser option you should be able to do:

parser = argparse.ArgumentParser()
parser.add_argument("--location", choices=("here", "there", "everywhere"))

storeaction = next(a for a in parser._actions if "--location" in a.option_strings)

storeaction.choices
# ('here', 'there', 'everywhere')

As in mgilson's answer, accessing the _actions attribute is undocumented and the underscored prefix means "Hey, you probably shouldn't be messing with me." Don't be surprised if this breaks between versions of Python.

like image 43
Adam Smith Avatar answered Sep 29 '22 19:09

Adam Smith