python argparse — customizing error messages

北城以北 提交于 2020-01-31 04:59:08

问题


I want to generate custom error messages for particular usage errors in my command-line program that uses the argparse library. I know I can override the general presentation of the error by subclassing argparse.ArgumentParser:

class HelpParser(argparse.ArgumentParser):
    def error(self, message):
        sys.stderr.write('error: %s\n' % message)
        sys.exit(2)

parser = HelpParser(... ...)
args = parser.parse_args()

But when my error method is called, message has already been formatted by the library. For example,

> python prog.py old stuff

usage: prog [-h] {hot,cold,rain,snow} ...
prog: error: argument subparser: invalid choice: 'old' (choose from u'hot', u'cold', u'rain', u'snow')

How can I change how the stuff after error: is presented, for instance to

usage: prog [-h] {hot,cold,rain,snow} ...
error: 'old' is not a valid option. select from 'hot', 'cold', 'rain', 'snow'

?


回答1:


Looking at the source code, you could over-ride this particular error message by overriding this method:

def _check_value(self, action, value):
    # converted value must be one of the choices (if specified)
    if action.choices is not None and value not in action.choices:
        args = {'value': value,
                'choices': ', '.join(map(repr, action.choices))}
        msg = _('invalid choice: %(value)r (choose from %(choices)s)')
        raise ArgumentError(action, msg % args)

The issue is that if you wanted to override all possible error messages, you'd have to basically re-write this module. All the various error messages are pre-formatted throughout -in the various methods that detect each type of error.




回答2:


Adding to @Gerrat's answer, the _ function is imported as

from gettext import gettext as _, ngettext

It is using the gettext module, https://docs.python.org/2/library/gettext.html, to enable internationalization. I'm not familiar with that module, but presumably you could use it to perform a certain amount English paraphrasing. But maybe not as much as you'd like.

Error messages pass through several levels. Functions like _check_values write the basic message. ArgumentError adds the argument name (argument subparser: in your example). parser.error adds the usage and prog. parser.exit takes care of the sys.exit step.

def error(self, message):
    ...
    self.print_usage(_sys.stderr)
    args = {'prog': self.prog, 'message': message}
    self.exit(2, _('%(prog)s: error: %(message)s\n') % args)


来源:https://stackoverflow.com/questions/30956688/python-argparse-customizing-error-messages

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!