There isn't a means in argparse
to accept a range of nargs
, just values like 1
,2
,'+'
,'*'
.
You could write a custom Action
class that would check the number of values that the nargs='*'
passes it. But I think it would be just as easy to perform that test after parsing.
I could find a bug/issue that explores adding a range nargs
option if you really want to get into that.
If you didn't have other positionals you could define 3 positionals, 2 of them with ?
. You might even be able to combine them into one list with a common name and 'append' action. I'll explore that.
In [573]: p=argparse.ArgumentParser()
In [574]: p.add_argument('str',action='append')
In [575]: p.add_argument('str',nargs='?',action='append')
In [576]: p.add_argument('str',nargs='?',action='append')
In [577]: p.print_help()
usage: ipython3 [-h] str [str] [str]
positional arguments:
str
str
str
optional arguments:
-h, --help show this help message and exit
In [578]: p.parse_args('1 2 3'.split())
Out[578]: Namespace(str=['1', '2', '3'])
In [579]: p.parse_args('1 3'.split())
Out[579]: Namespace(str=['1', '3', None])
In [580]: p.parse_args('1'.split())
Out[580]: Namespace(str=['1', None, None])
Got the default
Nones. I can correct that with
p.add_argument('str', nargs='?', action='append', default=argparse.SUPPRESS)
In [586]: p.parse_args('1 2'.split())
Out[586]: Namespace(str=['1', '2'])
In [588]: p.parse_args('1 2 3 4'.split())
usage: ipython3 [-h] str [str] [str]
ipython3: error: unrecognized arguments: 4
(oops, this is coded for 1-3 argument, but you get the idea).