This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author paul.j3
Recipients Michael.Edwards, chris.jerdonek, eric.araujo, idank, jaraco, paul.j3, rr2do2
Date 2013-04-17.20:24:49
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <>
An alternative to Jason's example:

parser = argparse.ArgumentParser()
parser.add_argument('app_args', nargs=argparse.REMAINDER)
args = parser.parse_args(['--config', 'bar', 'app'])
print vars(args)
# as expected: {'app': 'app', 'app_args': [], 'config': 'bar'}

When you have several positionals, one or more of which may have 0 arguments (*,?,...), it is best to put all of the optional arguments first.  

With 'app --config bar', parse_args identifies a 'AOA' pattern (argument, optional, argument).  It then checks which positional arguments match.  'app' claims 1, 'app_args' claims 2 (REMAINDER means match everything that follows).  That leaves nothing for '--config'.

What you expected was that 'app' would match with the 1st string, '--config' would match the next 2, leaving nothing for 'app_args'.  

In I wrote a patch that would give the results you want if 'app_args' uses '*'.  That is makes it possible to interleave positional and optional argument strings.  But it does not change the behavior of REMAINDER.

parser.add_argument('app_args', nargs='*')


Maybe the documentation example for REMAINDER needs to modified to show just how 'greedy' REMAINDER is.  Adding a:


does not change the outcome.  REMAINDER still grabs '--arg1' even though it is a defined argument.

Namespace(arg1=False, args=['--arg1', 'XX', 'ZZ'], command='cmd', foo='B')
Date User Action Args
2013-04-17 20:24:49paul.j3setrecipients: + paul.j3, jaraco, eric.araujo, chris.jerdonek, idank, rr2do2, Michael.Edwards
2013-04-17 20:24:49paul.j3setmessageid: <>
2013-04-17 20:24:49paul.j3linkissue14174 messages
2013-04-17 20:24:49paul.j3create