python - 点击: Customize "Missing argument" error handling by overriding UsageError's show function

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

我目前正在尝试自定义错误处理,当使用 Click 给出命令而未提供所需参数时。 根据this SO question这可以通过覆盖 click.exceptions.UsageErrorshow 函数来完成。 但是,我尝试修改那里提供的解决方案,但无法使其工作。

就我而言,我希望能够获取应该执行的命令(但由于缺少参数而失败),并且根据输入的命令,我想进一步处理。 我的示例代码如下所示:

@click.group(cls=MyGroup)
def myapp():
    pass

@myapp.command()
@click.argument('myarg',type=str)
def mycommand(myarg: str) -> None:
    do_stuff(myarg)

因此,如果命令类似于 myapp mycommand 并且它缺少所需的参数,我想单独处理它。 我搜索了一段时间,但我无法弄清楚如何获取命令(我尝试传递上下文,但据我所知,UsageError在初始化时没有传递任何上下文)。

如果有任何提示或想法,我将不胜感激。

编辑:myGroup 的实现如下所示:

class myGroup(click.Group):
"""
Customize help order and get_command
https://stackoverflow.com/a/47984810/713980
"""

def __init__(self, *args, **kwargs):
    self.help_priorities = {}
    super(myGroup, self).__init__(*args, **kwargs)

def get_help(self, ctx):
    self.list_commands = self.list_commands_for_help
    return super(myGroup, self).get_help(ctx)

def list_commands_for_help(self, ctx):
    """reorder the list of commands when listing the help"""
    commands = super(myGroup, self).list_commands(ctx)
    return (c[1] for c in sorted((self.help_priorities.get(command, 1000), command) for command in commands))

def command(self, *args, **kwargs):
    """Behaves the same as `click.Group.command()` except capture
    a priority for listing command names in help.
    """
    help_priority = kwargs.pop('help_priority', 1000)
    help_priorities = self.help_priorities

    def decorator(f):
        cmd = super(myGroup, self).command(*args, **kwargs)(f)
        help_priorities[cmd.name] = help_priority
        return cmd
    return decorator

def get_command(self, ctx, cmd_name):
    rv = click.Group.get_command(self, ctx, cmd_name)
    if rv is not None:
        return rv
    sim_commands = most_sim_com(cmd_name, COMMANDS)

    matches = [cmd for cmd in self.list_commands(ctx) if cmd in sim_commands]
    if not matches:
        ctx.fail(click.style('Unknown command and no similar command was found!', fg='red'))
    elif len(matches) == 1:
        click.echo(click.style(f'Unknown command! Will use best match {matches[0]}.', fg='red'))
        return click.Group.get_command(self, ctx, matches[0])
    ctx.fail(click.style(f'Unknown command. Most similar commands were {", ".join(sorted(matches))}', fg='red'))

最佳答案

这是初稿,也是我能想到的最幼稚的解决方案,因此如果不能完全解决您的问题,它可能会改变它。将您的代码更改为类似的内容会有帮助吗?

@click.group(cls=MyGroup)
def myapp():
    pass

@myapp.command()
@click.argument('myarg',type=str, required=False)
def mycommand(myarg: str=None) -> None:
    validate_my_command(myarg) # this is where you do your custom logic and error message handling

这样做的优点是它是明确的,并且与 Click 建议的执行方式保持一致。但是,如果您想对每个命令都执行此操作,我们可以考虑更复杂的方法

让我知道你的想法

关于python - 点击: Customize "Missing argument" error handling by overriding UsageError's show function,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61465229/

相关文章:

python - urwid 中是否有相当于 GUI 文本字段的内容?

node.js - 在计算机上本地存储 JWT token 的位置?

bash - 在 bash 脚本中区分 2 和 02

bash - 使用大括号参数列表多次执行命令

python - Python 中的函数给出错误消息

python - Keras 在 model.fit() 之后删除图层

linux - 试图在一行中将多个命令 append (>>)到文件

python - 为数据框创建 Parquet 创建函数

python - Pandas :在数据框中重新分配值

java - 使用进程生成器从 java 运行 cmd 命令