Reputation: 908
I'm writing a program that takes two argument (paths) and as an option -l
, witch enables save the log in a log file.
I'm using argparse
and create the following argument:
parser.add_argument('-l', '--logfile',
nargs='?',
const='tranfer.log',
default=False,
help='save log of the transfer')
These are the forms of use:
prog.py path_1 path_2
. Nothing special.prog.py -l filename path_1 path_2
. Save the log in filename
file.prog.py -l path_1 path_2
. Save the log the file by default (say, logfile
).I have a problem in item 3, because prog.py
takes path_1
as the filename of the log file. The issue was easily fixed puttin -l
option at the end of the line.
prog.py path_1 path_2 -l
But I was wondering if there's a way of tell argparse
to use the last two option as the path files, because I'll be not the only one who use the program.
Path argument were add as follows:
parser.add_argument('left_path',
action='store',
help='first path')
parser.add_argument('right_path',
action='store',
help='second path')
Upvotes: 4
Views: 3591
Reputation: 231355
Your assessment is right,
prog.py -l path_1 path_2
will assign path_1
to l
and path_2
to the first positional, and raise an error about missing 2nd positional.
http://bugs.python.org/issue9338 argparse optionals with nargs='?', '*' or '+' can't be followed by positionals
is a bug/issue that deals with this. Patches have been proposed, but not implemented. It's not trivial. When handing -l
the parser would have to look ahead to see how many arguments are needed to satisfy the positionals, and refrain from consuming the next string (even though by your definition it has every right to do so).
It's also been discussed in previous SO questions.
https://stackoverflow.com/a/29853186/901925
https://stackoverflow.com/a/26986546/901925
You have to either put the optional last, or use some other means of signaling the end of its list of arguments (--
or other flagged optional). Or change the argument definitions, so that -l
is not ?
(or the equivalent), or change the positionals to flagged.
Upvotes: 3
Reputation: 568
you can also store all options in a single argument and check by hand, as in
parser.add_argument('-p', dest='path', nargs='?',
default=('path1/','path2/'))
args = parser.parse_args()
if len(args.path) == 3:
args.logfile = args.path[0]
args.path = args.path[1:]
elif len(args.path) == 2:
args.logfile = ''
else:
print 'Error'
but then you have to have the -p
flag if you want to set the paths to be different from the defaults.
Upvotes: 0
Reputation: 309
The neat way to do this would be to introduce option flags for the both the paths arguments too. Then there would be no ambiguity and you'd be able to say:
prog.py -l -leftpath path_1 -rightpath path_2
Upvotes: 0