uplime
uplime

Reputation: 3

Raise exception if ArgumentParser encounters unknown argument

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

Upvotes: 0

Views: 545

Answers (1)

David
David

Reputation: 1216

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

Upvotes: 1

Related Questions