I'm using the Python (version 3.9.4) library argparse
to parse a small number of option flags. For a number of reasons, I'd like to handle errors in my code rather than argparse.ArgumentParser
. Namely, how an unrecognized argument is handled. For example, if I ran my-python-program --foobar
, I'd like to be able to catch an exception and perform work there. This testcase disables almost all of the errors I've tried, except for an invalid argument:
import argparse
import sys
try:
parser = argparse.ArgumentParser(add_help=False, exit_on_error=False, usage=None)
parser.add_argument("--help", action="store_true", default=False)
parser.add_argument("--hello", default="Hello, world!")
args = parser.parse_args()
print(args.help, args.hello)
except Exception as err:
print("a problem occurred!", file=sys.stderr)
print(f"error: {err}", file=sys.stderr)
Instead, running my-python-program --foobar
gives me:
usage: my-python-program [--help] [--hello HELLO]
my-python-program: error: unrecognized arguments: --foobar
If you look at the Python argparse
source code, you can see that it calls self.error
on an error. This function (at the bottom of the file), by default, prints the error message and quits. You can override this method in a subclass to raise an error instead.
import argparse
import sys
class MyArgumentParser(argparse.ArgumentParser):
"""An argument parser that raises an error, instead of quits"""
def error(self, message):
raise ValueError(message)
try:
parser = MyArgumentParser(add_help=False, exit_on_error=False, usage=None)
parser.add_argument("--help", action="store_true", default=False)
parser.add_argument("--hello", default="Hello, world!")
args = parser.parse_args()
print(args.help, args.hello)
except Exception as err:
print("a problem occurred!", file=sys.stderr)
print(f"error: {err}", file=sys.stderr)
Output:
$ python3 test.py --foobar
a problem occurred!
error: unrecognized arguments: --foobar