【问题标题】:Python Click: custom error messagePython 点击​​:自定义错误信息
【发布时间】:2017-01-28 11:52:45
【问题描述】:

我使用出色的 Python Click 库来处理我的工具中的命令行选项。这是我的代码的简化版本(完整脚本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()

如果有人在没有任何标志的情况下运行命令,他们会收到默认的点击错误消息:

$ mytool

Usage: mytool [OPTIONS] <analysis directory>

Error: Missing argument "analysis_dir".

这很好,但我很想告诉(非常)新手用户,使用帮助标志可以获得更多帮助。换句话说,当命令无效时,在错误消息中添加一个自定义语句,告诉人们尝试mytool --help 以获取更多信息。

有没有简单的方法来做到这一点?我知道我可以删除 required 属性并在 main 函数中处理这个逻辑,但是对于这样一个小添加感觉有点 hacky。

【问题讨论】:

  • 我遇到了完全相同的问题。如果发生错误,我想自动打印出帮助,或者至少告诉用户如何打印出帮助。否则,我们必须假设使用我们工具的每个人都熟悉基于 unix 的思维方式。到目前为止,我很喜欢 click,但对这个问题没有得到回答感到沮丧,因为我想要一些有助于构建新手可以轻松使用的工具的东西。
  • 刚找到这个,可能是个解决办法:stackoverflow.com/questions/35642202/…
  • 不,那没用。
  • 是的 - 我查看了这个 @blubberdiblub 但不知道如何在不使用 command.main(['command-name', 'args', 'go', 'here']) 语法时实际实现它。我在任何地方都找不到任何例子并放弃了。如果您对如何使用上面示例中的语法应用它有任何指示,那将非常有帮助!

标签: python command-line-arguments python-click


【解决方案1】:

python-click 中大多数错误的消息构造由 UsageError 类的 show 方法处理:click.exceptions.UsageError.show

因此,如果您重新定义此方法,您将能够创建自己的自定义错误消息。下面是一个自定义示例,它将帮助菜单附加到任何回答此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

一旦你定义了你的主命令,你就可以运行修改器脚本:

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

modify_usage_error(cli)

除了使用错误之外,我还没有探索过是否存在 ClickException 的运行时调用。如果有,那么您可能需要修改您的自定义错误处理程序,以首先检查 ctx 是否是一个属性,然后再添加行 click.exceptions.ClickException.show = show,因为在初始化时似乎没有为 ClickException 提供 ctx。

【讨论】:

  • 太棒了,谢谢 RJ!这在一个例外情况下完美运行 - 我不得不删除对 main_command() 的最终函数调用,因为这会导致递归错误。
  • 这感觉很好! github.com/ewels/MultiQC/commit/62cc60我已经有七个月没能做到这一点了!再次感谢!
  • 任何建议如何一次覆盖所有点击异常类型?理想情况下,当单击添加的新异常时它不会中断?
  • 您可能会尝试遍历 dir(click.exceptions),排除内置方法 stackoverflow.com/a/21542780/4941585 然后 setattr(object, 'show', show)。 docs.python.org/3/library/functions.html#setattr 但是这可能会导致意外行为。
猜你喜欢
  • 2019-06-13
  • 2023-03-21
  • 2018-01-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-03
  • 2021-02-10
相关资源
最近更新 更多