I have the following python program:
#!/usr/bin/env python
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('arg', choices=['foo', 'bar', 'baz'], default='foo', nargs='*')
args = parser.parse_args()
print(args)
If I invoke the program like this:
./prog.py
the output is
Namespace(arg='foo')
But if I invoke the program with foo
as an argument:
./prog.py foo
the output is
Namespace(arg=['foo'])
Question
How can I get arg
's default value to become a list
?
I've tried
I've tried setting default=['foo']
but that results in:
prog.py: error: argument arg: invalid choice: ['foo'] (choose from 'foo', 'bar', 'baz')
This is a duplicate of an old, but open, bug/issue
http://bugs.python.org/issue9625 (argparse: Problem with defaults for variable nargs when using choices
)
A positional
with *
gets some special handling. Its default is always passed through the choices
test if you don't provide values.
Compare that with the case of an optional
In [138]: p=argparse.ArgumentParser()
In [139]: a=p.add_argument('--arg',choices=['foo','bar','baz'],nargs='*')
In [140]: p.parse_args([])
Out[140]: Namespace(arg=None)
In [141]: a.default=['foo']
In [142]: p.parse_args([])
Out[142]: Namespace(arg=['foo'])
The default is accepted without testing:
In [143]: a.default=['xxx']
In [144]: p.parse_args([])
Out[144]: Namespace(arg=['xxx'])
The relevant code is:
def _get_values(self, action, arg_strings):
...
# when nargs='*' on a positional, if there were no command-line
# args, use the default if it is anything other than None
elif (not arg_strings and action.nargs == ZERO_OR_MORE and
not action.option_strings):
if action.default is not None:
value = action.default
else:
value = arg_strings
self._check_value(action, value)
The proposed bug/issue patch makes a small change to this block of code.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With