如何在点击中为群组操作创建例外 [英] How do I create an exception to a group action in click
问题描述
在某些情况下,我想为我的大多数click命令运行一个通用功能(check_upgrade()
),但是在某些情况下,我不想运行它.我宁愿不依赖开发人员记住添加装饰器或函数调用来显式运行此检查,而宁愿默认情况下运行它,然后让装饰器可以为其中
I have a case where I'd like to run a common function (check_upgrade()
) for most of my click commands, but there are a few cases where I don't want to run it. Rather than relying on developers to remember to add a decorator or function call to explicitly run this check, I'd prefer to instead run it by default and then have a decorator that one can add (e.g. @bypass_upgrade_check
) for commands where check_upgrade()
should not run.
我希望有这样的东西:
class State(object):
def __init__(self):
self.bypass_upgrade_check = False
pass_state = click.make_pass_decorator(State, ensure=True)
def bypass_upgrade_check(func):
@pass_state
def wrapper(state, *args, **kwargs):
state.bypass_upgrade_check = True
func(*args, **kwargs)
return wrapper
@click.group()
@pass_state
def common(state):
if not state.bypass_upgrade_check:
check_upgrade()
@common.command()
def cmd1():
# check_upgrade() runs here
pass
@bypass_upgrade_check
@common.command()
def cmd2():
# don't run check_upgrade() here
pass
但这不起作用.实际上,它从来没有调用bypass_upgrade_check()
函数.
But this doesn't work. It doesn't actually ever call the bypass_upgrade_check()
function.
是否有一种方法可以修饰命令,以便可以在运行组代码之前修改状态?还是完全可以做到这一点的另一种方法?
Is there a way to decorate a command in such a way that I can modify the state before the group code runs? Or another method altogether that accomplishes this?
推荐答案
为跟踪哪些命令绕过升级检查,我建议在绕过标记装饰器中将该状态存储在click.Command
对象上.然后,如果将click.Context
传递给您的组,则可以查看命令对象以查看其是否标记为允许跳过升级,例如:
To keep track of which commands bypass the upgrade check, I suggest that in the bypass marking decorator you store that state on the click.Command
object. Then if you pass the click.Context
to your group, you can then look at the command object to see if it is marked to allow skipping upgrade like:
def bypass_upgrade_check(func):
setattr(func, 'do_upgrade_check', False)
@click.group()
@click.pass_context
def cli(ctx):
sub_cmd = ctx.command.commands[ctx.invoked_subcommand]
if getattr(sub_cmd, 'do_upgrade_check', True):
check_upgrade()
测试代码:
import click
def check_upgrade():
click.echo('Checking Upgrade!')
def bypass_upgrade_check(func):
setattr(func, 'do_upgrade_check', False)
@click.group()
@click.pass_context
def cli(ctx):
sub_cmd = ctx.command.commands[ctx.invoked_subcommand]
if getattr(sub_cmd, 'do_upgrade_check', True):
check_upgrade()
@cli.command()
def cmd1():
# check_upgrade() runs here
click.echo('cmd1')
@bypass_upgrade_check
@cli.command()
def cmd2():
# don't run check_upgrade() here
click.echo('cmd2')
if __name__ == "__main__":
commands = (
'cmd1',
'cmd2',
)
import sys, time
time.sleep(1)
print('Click Version: {}'.format(click.__version__))
print('Python Version: {}'.format(sys.version))
for cmd in commands:
try:
time.sleep(0.1)
print('-----------')
print('> ' + cmd)
time.sleep(0.1)
cli(cmd.split())
except BaseException as exc:
if str(exc) != '0' and \
not isinstance(exc, (click.ClickException, SystemExit)):
raise
结果:
Click Version: 6.7
Python Version: 3.6.3 (v3.6.3:2c5fed8, Oct 3 2017, 18:11:49) [MSC v.1900 64 bit (AMD64)]
-----------
> cmd1
Checking Upgrade!
cmd1
-----------
> cmd2
cmd2
这篇关于如何在点击中为群组操作创建例外的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!