Reputation: 7714
Is it possible to add an optional argument with argparse as -<integer>,
similar to unix head
and tail
commands which accept -<integer> to say how many lines to print,
or similar to git log
which accepts -<integer> to say how many log entries to print?
For example,
head -4 # print four lines
tail -12 # print 12 lines.
git log -7 # print 7 log entries
Whereas the argument is optional, for example these all work:
head # print default number of lines
tail # print default number of lines
git log # print all log entries through system pager
Thanks.
Upvotes: 2
Views: 300
Reputation: 231385
Trying to accept dash numbers as argument flags creates ambiguities. When should they be interpreted as negative numbers and when as flags? In addition argparse
does not allow 'dynamic' or patterns; you have define each flag.
Normally '-2' is parsed as a value - numeric if type is int
:
In [250]: p=argparse.ArgumentParser()
In [251]: p.add_argument('foo', type=int);
In [252]: p.parse_args(['-2'])
Out[252]: Namespace(foo=-2)
We can define a flag with a numeric character:
In [253]: p.add_argument('-3','--third');
In [254]: p.parse_args(['2'])
Out[254]: Namespace(foo=2, third=None)
That disables the use of negative numbers:
In [255]: p.parse_args(['-2'])
usage: ipython3 [-h] [-3 THIRD] foo
ipython3: error: the following arguments are required: foo
In [257]: p.parse_args('-3 xxx 3'.split())
Out[257]: Namespace(foo=3, third='xxx')
In [260]: p.parse_args('-3 -1 3'.split())
usage: ipython3 [-h] [-3 THIRD] foo
ipython3: error: argument -3/--third: expected one argument
According to gnu-unix/linux the pattern you want is obsolete
https://www.gnu.org/software/coreutils/manual/html_node/head-invocation.html
Normally lines are specified with:
‘-n [-]num’
where the negative value counts from the end (as a negative slicing does in Python).
For compatibility head also supports an obsolete option syntax -[num][bkm][cqv]
Early versions of utilities like this parsed the command line values directly (in C code) with whatever syntax the writer thought convenient (as much from a coding standpoint as final usage). You too can do that as indicated in the other answer. But as the systems matured developers used parsers like getopt
, and tried to standardize usage.
https://www.gnu.org/software/coreutils/manual/html_node/Common-options.html#Common-options
Generally argparse
builds on POSIX standards as inherited via the getopt
and optparse
modules.
Upvotes: 0
Reputation: 1011
argparse
doesn't support dynamic option names.
Source: I tried to do the same thing you ask.
You can accomplish the task itself, but it would have to run either before or after argparse
and it would have to modify sys.argv
. That makes it so half of the solution will be side-stepping argparse
. I recommend you try to find a library that supports this style of parameter passing.
Upvotes: 4