Python Click: custom error message

大憨熊 提交于 2019-12-10 02:58:56

问题


I use the excellent Python Click library for handling command line options in my tool. Here's a simplified version of my code (full script here):

@click.command(
    context_settings = dict( help_option_names = ['-h', '--help'] )
)
@click.argument('analysis_dir',
                 type = click.Path(exists=True),
                 nargs = -1,
                 required = True,
                 metavar = "<analysis directory>"
)

def mytool(analysis_dir):
   """ Do stuff """

if __name__ == "__main__":
    mytool()

If someone runs the command without any flags, they get the default click error message:

$ mytool

Usage: mytool [OPTIONS] <analysis directory>

Error: Missing argument "analysis_dir".

This is nice, but I'd quite like to tell (very) novice users that more help is available by using the help flag. In other words, add a custom sentence to the error message when the command is invalid telling people to try mytool --help for more information.

Is there an easy way to do this? I know I could remove the required attribute and handle this logic in the main function, but that feels kind of hacky for such a minor addition.


回答1:


Message construction for most errors in python-click is handled by the show method of the UsageError class: click.exceptions.UsageError.show.

So, if you redefine this method, you will be able to create your own customized error message. Below is an example of a customization which appends the help menu to any error message which answers this SO question:

def modify_usage_error(main_command):
    '''
        a method to append the help menu to an usage error

    :param main_command: top-level group or command object constructed by click wrapper 
    :return: None
    '''

    from click._compat import get_text_stderr
    from click.utils import echo
    def show(self, file=None):
        import sys
        if file is None:
            file = get_text_stderr()
        color = None
        if self.ctx is not None:
            color = self.ctx.color
            echo(self.ctx.get_usage() + '\n', file=file, color=color)
        echo('Error: %s\n' % self.format_message(), file=file, color=color)
        sys.argv = [sys.argv[0]]
        main_command()

    click.exceptions.UsageError.show = show

Once you define your main command, you can then run the modifier script:

import click
@click.group()
def cli():
    pass

modify_usage_error(cli)

I have not explored whether there are runtime invocations of ClickException other than usage errors. If there are, then you might need to modify your custom error handler to first check that ctx is an attribute before you add the line click.exceptions.ClickException.show = show since it does not appear that ClickException is fed ctx at initialization.



来源:https://stackoverflow.com/questions/39596070/python-click-custom-error-message

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