Export to GitHub

argparse - issue #3

API for collecting unrecognized options


Posted on Mar 28, 2009 by Grumpy Rabbit

It would be nice to be able to specify somehow that unrecognized options should be collected somewhere instead of raising exceptions. The current behavior::

>>> parser = argparse.ArgumentParser(prog='PROG') >>> parser.add_argument('--foo') >>> parser.parse_args('--foo F --bar --baz'.split()) usage: PROG [-h] [--foo FOO] PROG: error: no such option: --bar

But sometimes you might prefer to have::

>>> parser = argparse.ArgumentParser(prog='PROG') >>> parser.add_argument('--foo') >>> parser.parse_known_args('--foo F --bar --baz'.split()) Namespace(foo='F'), ['--bar', '--baz']

Comment #1

Posted on Jun 6, 2009 by Happy Panda

One use case to keep in mind would be a script that runs another program with --options. In fact, I'd be happy to just have a way to say that "everything after this argument is an argument and not an --option even if it has hyphens". I'm not sure how to implement this, though.

Comment #2

Posted on Jun 8, 2009 by Helpful Horse

The standard mechanism for this is the special non-option '--'. It triggers the option recognition without having a name to let the parser know that everything after the '--' is positional...

Comment #3

Posted on Jun 10, 2009 by Grumpy Rabbit

Yes, argparse already supports the special '--' non-option. That's the current recommended workaround. Something like::

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('my_arg')
>>> parser.add_argument('their_arg', nargs='*')
>>> parser.parse_args('MINE -- --theirs theirs theirs'.split())
Namespace(my_arg='MINE', their_arg=['--theirs', 'theirs', 'theirs'])

I'm still not sure what the best way to implement this is. Some of the places that would need to be changed::

The place where errors are raised for invalid options:
self.error(_('no such option: %s') % option_string)

The places where errors are raised for extra positionals:
msg = _('extra arguments found: %s')
self.error(_('extra arguments found: %s') % ' '.join(extras))

There may be other places, but those are the ones that jumped out at me first. I'll try to make some time to look into this, but if anyone is feeling generous and wants to take a stab at a patch, I'd be happy for the help.

Comment #4

Posted on Jun 14, 2009 by Grumpy Rabbit

Ok, this actually turned out to be much easier than I thought it would be. You can now call parser.parse_known_args() as of r23. It works just like the example code in the first post, returning a tuple of the usual namespace object, followed by the remaining arg strings.

I'd be grateful if a few people could try this out and let me know how it goes before I make the next argparse release.

Status: Fixed

Labels:
Type-Enhancement Priority-Low