paul j3 added the comment: An alternative to Jason's example:
parser = argparse.ArgumentParser() parser.add_argument('app') parser.add_argument('--config') 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 http://bugs.python.org/issue14191 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: parser.add_argument('--arg1',action='store_true') 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') ---------- nosy: +paul.j3 _______________________________________ Python tracker <rep...@bugs.python.org> <http://bugs.python.org/issue14174> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com