Python Click: custom error message

I use the excellent Python Click library to handle 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 a default error message:

 $ mytool Usage: mytool [OPTIONS] <analysis directory> Error: Missing argument "analysis_dir". 

This is good, but I would really like to tell (very) novice users that additional help is available using the help flag. In other words, add the special offer in the error message when the command is not valid so that people try mytool --help for more information.

Is there an easy way to do this? I know that I can remove the required attribute and process this logic in the main function, but it looks like a hack for such a minor addition.

+7
python command-line-arguments python-click
source share
1 answer

The message design for most errors in python-click is handled by the show method of the UsageError class: click.exceptions.UsageError.show .

So, if you override this method, you can create your own customized error message. The following is an example setup that adds a help menu to any error message that 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 

After defining your main command, you can run the script modifier:

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

I have not studied whether there are calls when a ClickException is raised, other than usage errors. If so, you may need to modify your own error handler to first verify that ctx is an attribute before adding the line click.exceptions.ClickException.show = show , since it does not appear that when the ctx is initialized, the root ClickException element is dispatched.

+3
source share

All Articles