I went and coded up the three suggestions given as answers in this thread. The test code appears at the bottom of this answer. Conclusion: The best all-around answer so far is nargs=REMAINDER
, but it might really depend on your use case.
Here are the differences I observed:
(1) nargs=REMAINDER
wins the user-friendliness test.
$ python test.py --help
Using nargs=* : usage: test.py [-h] [-i I] [otherthings [otherthings ...]]
Using nargs=REMAINDER : usage: test.py [-h] [-i I] ...
Using parse_known_args : usage: test.py [-h] [-i I]
(2) nargs=*
quietly filters out the first --
argument on the command line, which seems bad. On the other hand, all methods respect --
as a way to say "please don't parse any more of these strings as known args."
$ ./test.py hello -- -- cruel -- -- world
Using nargs=* : ['hello', '--', 'cruel', '--', '--', 'world']
Using nargs=REMAINDER : ['hello', '--', '--', 'cruel', '--', '--', 'world']
Using parse_known_args : ['hello', '--', '--', 'cruel', '--', '--', 'world']
$ ./test.py -i foo -- -i bar
Using nargs=* : ['-i', 'bar']
Using nargs=REMAINDER : ['--', '-i', 'bar']
Using parse_known_args : ['--', '-i', 'bar']
(3) Any method except parse_known_args
dies if it tries to parse a string beginning with -
and it turns out not to be valid.
$ python test.py -c hello
Using nargs=* : "unrecognized arguments: -c" and SystemExit
Using nargs=REMAINDER : "unrecognized arguments: -c" and SystemExit
Using parse_known_args : ['-c', 'hello']
(4) nargs=REMAINDER
completely stops parsing when it hits the first unknown argument. parse_known_args
will gobble up arguments that are "known", no matter where they appear on the line (and will die if they look malformed).
$ python test.py hello -c world
Using nargs=* : "unrecognized arguments: -c world" and SystemExit
Using nargs=REMAINDER : ['hello', '-c', 'world']
Using parse_known_args : ['hello', '-c', 'world']
$ python test.py hello -i world
Using nargs=* : ['hello']
Using nargs=REMAINDER : ['hello', '-i', 'world']
Using parse_known_args : ['hello']
$ python test.py hello -i
Using nargs=* : "error: argument -i: expected one argument" and SystemExit
Using nargs=REMAINDER : ['hello', '-i']
Using parse_known_args : "error: argument -i: expected one argument" and SystemExit
Here's my test code.
#!/usr/bin/env python
import argparse
import sys
def using_asterisk(argv):
parser = argparse.ArgumentParser()
parser.add_argument('-i', dest='i', default='i.log')
parser.add_argument('otherthings', nargs='*')
try:
options = parser.parse_args(argv)
return options.otherthings
except BaseException as e:
return e
def using_REMAINDER(argv):
parser = argparse.ArgumentParser()
parser.add_argument('-i', dest='i', default='i.log')
parser.add_argument('otherthings', nargs=argparse.REMAINDER)
try:
options = parser.parse_args(argv)
return options.otherthings
except BaseException as e:
return e
def using_parse_known_args(argv):
parser = argparse.ArgumentParser()
parser.add_argument('-i', dest='i', default='i.log')
try:
options, rest = parser.parse_known_args(argv)
return rest
except BaseException as e:
return e
if __name__ == '__main__':
print 'Using nargs=* : %r' % using_asterisk(sys.argv[1:])
print 'Using nargs=REMAINDER : %r' % using_REMAINDER(sys.argv[1:])
print 'Using parse_known_args : %r' % using_parse_known_args(sys.argv[1:])