Python argparse ignore unrecognised arguments
Asked Answered
A

3

296

Optparse, the old version just ignores all unrecognised arguments and carries on. In most situations, this isn't ideal and was changed in argparse. But there are a few situations where you want to ignore any unrecognised arguments and parse the ones you've specified.

For example:

parser = argparse.ArgumentParser()
parser.add_argument('--foo', dest="foo")
parser.parse_args()

$python myscript.py --foo 1 --bar 2
error: unrecognized arguments: --bar

Is there anyway to override this?

Autostability answered 10/10, 2012 at 11:22 Comment(1)
Very handy if you're writing a wrapper to another program, and you want to capture and modify a few arguments, but pass the rest on!Santonin
C
528

Replace

args = parser.parse_args()

with

args, unknown = parser.parse_known_args()

For example,

import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--foo')
args, unknown = parser.parse_known_args(['--foo', 'BAR', 'spam'])
print(args)
# Namespace(foo='BAR')
print(unknown)
# ['spam']
Cheesecloth answered 10/10, 2012 at 11:28 Comment(9)
+1 - didn't knew there was some thing like parse_known_argsPhenology
Nor did I! I even missed it in the docs docs.python.org/library/…. ThanksAutostability
This came up when trying to use nosetest with parseargs (it refused to allow nosetest args to be used) the reason was because I was doing parser.parse_args(None) rather than parser.parse_args([]) in my tests.Gloomy
FWIW, using parse_known_args rather than parse_args enables the use of ArgumentParser in code within the scope of if __name__ == 'main': (a condition that is True for all cells in an IPython Notebook ... which I find greatly aids the development and testing code that I want to eventually migrate to a script invoked from a command line)Yarak
Oops: s/main/__main__/Yarak
This doesn't seem to work with optional args that are "known" not being passed in.Hornswoggle
Unfortunately unknown is simply array and there is no built-in way to convert to nice dictionary (as we don't know types). Alternative: https://mcmap.net/q/101988/-is-it-possible-to-use-argparse-to-capture-an-arbitrary-set-of-optional-arguments.Saccharify
Note that the unknown args can then be passed to another argparse instance, for example a subparser.Iyar
was able to work around a SystemExit condition with pytest -s -v with this solutionKarilynn
H
31

You can puts the remaining parts into a new argument with parser.add_argument('args', nargs=argparse.REMAINDER) if you want to use them.

Hereat answered 22/9, 2014 at 4:51 Comment(3)
This works with parse_args() and doesn't require parse_known_args() (on Python 2.7).Osterhus
Using argparse.REMAINDER seems to be fraught with long-standing bugs. I certainly can't get it to work. parse_known_args() is a good alternative.Despairing
Just ran into a long-standing REMAINDER bug today: bugs.python.org/issue17050Civvies
G
10

Actually argparse does still "ignore" _unrecognized_args. As long as these "unrecognized" arguments don't use the default prefix you will hear no complaints from the parser.

Using @anutbu's configuration but with the standard parse.parse_args(), if we were to execute our program with the following arguments.

$ program --foo BAR a b +cd e

We will have this Namespaced data collection to work with.

Namespace(_unrecognized_args=['a', 'b', '+cd', 'e'], foo='BAR')

If we wanted the default prefix - ignored we could change the ArgumentParser and decide we are going to use a + for our "recognized" arguments instead.

parser = argparse.ArgumentParser(prefix_chars='+')
parser.add_argument('+cd')

The same command will produce

Namespace(_unrecognized_args=['--foo', 'BAR', 'a', 'b'], cd='e')

Put that in your pipe and smoke it =)

nJoy!

Glint answered 28/11, 2012 at 2:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.