单击:通过覆盖 UsageError 的显示函数自定义 "Missing argument" 错误处理
Click: Customize "Missing argument" error handling by overriding UsageError's show function
我目前正在尝试使用 Click 在没有提供所需参数的情况下给出命令时自定义错误处理。
根据 ,这可以通过覆盖 click.exceptions.UsageError
的 show
函数来完成。
但是,我试图在那里修改提供的解决方案,但我无法让它工作。
在我的例子中,我希望能够获得应该执行的命令(但由于缺少参数而失败)并且根据输入的命令,我想进一步处理。
我的示例代码如下所示:
@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
"""
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
建议的这样做方式保持一致。但是,如果你想对每个命令都这样做,我们可以考虑更复杂的方法
告诉我你的想法
我目前正在尝试使用 Click 在没有提供所需参数的情况下给出命令时自定义错误处理。
根据 click.exceptions.UsageError
的 show
函数来完成。
但是,我试图在那里修改提供的解决方案,但我无法让它工作。
在我的例子中,我希望能够获得应该执行的命令(但由于缺少参数而失败)并且根据输入的命令,我想进一步处理。 我的示例代码如下所示:
@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
"""
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
建议的这样做方式保持一致。但是,如果你想对每个命令都这样做,我们可以考虑更复杂的方法
告诉我你的想法