如何在点击中为群组操作创建例外 [英] How do I create an exception to a group action in click

查看:89
本文介绍了如何在点击中为群组操作创建例外的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在某些情况下,我想为我的大多数click命令运行一个通用功能(check_upgrade()),但是在某些情况下,我不想运行它.我宁愿不依赖开发人员记住添加装饰器或函数调用来显式运行此检查,而宁愿默认情况下运行它,然后让装饰器可以为其中@bypass_upgrade_check) >不应运行.

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆