Python Click-仅在成功执行父命令时才执行子命令 [英] Python Click - only execute subcommand if parent command executed successfully

查看:150
本文介绍了Python Click-仅在成功执行父命令时才执行子命令的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用点击来构建Python CLI,并遇到了异常处理方式的问题在点击.

I'm using Click to build a Python CLI and am running into an issue with how exceptions are handles in Click.

我不确定这里的用语(子命令",父命令"),但是从我的示例中,您将得到我希望的想法.让我们假设这段代码:

I'm not sure about the wording ("subcommand", "parentcommand") here but from my example you'll get the idea I hope. Let's assume this code:

@click.group()
@click.option("--something")
def mycli(something):
    try:
        #do something with "something" and set ctx
        ctx.obj = {}
        ctx.obj["somevar"] = some_result
    except:
        print("Something went wrong")
        raise

    #only if everything went fine call mycommand

@click.group()
@click.pass_context
def mygroup(ctx):
    pass

@mygroup.command(name="mycommand")
@click.pass_context
def mycommand(ctx):
    #this only works if somevar is set in ctx so don't call this if setting went wrong in mycli

当应用程序启动时,它被称为:

When the application starts this is called:

if __name__ == "__main__":
    mycli.add_command(mygroup)
    mycli()

然后我像这样启动程序:

I then start the program like this:

python myapp --something somevalue mycommand

预期的行为:首先调用mycli并执行其中的代码.如果引发异常,则该异常将被except块捕获,并显示一条消息并引发该异常.因为我们没有其他try/except块,这将导致脚本终止.从未调用子"命令mycommand,因为程序在运行父"命令mycli时已终止.

Expected behaviour: first mycli is called and the code in it is executed. If an exception is thrown it's caught by the except block, a message is printed and the exception is raised. Because we have no other try/except block this will result in termination of the script. The "sub"-command mycommand is never called because the program already terminated when running the "parent"-command mycli.

实际行为:捕获到异常并打印消息,但仍调用mycommand.然后,它失败,并显示另一个异常消息,因为未设置必需的上下文变量.

Actual behaviour: the exception is caughtand the message is printed, but mycommand is still called. It then fails with another exception message because the required context variable was not set.

我该如何处理?基本上,我只想仅在mycli中的所有内容都正常的情况下才执行子命令mycommand.

How would I handle something like that? Basically I only want to call the subcommand mycommand only to be executed if everything in mycli went fine.

推荐答案

要处理该异常,但不继续执行子命令,可以像下面这样简单地调用exit():

To handle the exception, but not continue onto the subcommands, you can simply call exit() like:

import click

@click.group()
@click.option("--something")
@click.pass_context
def mycli(ctx, something):
    ctx.obj = dict(a_var=something)
    try:
        if something != '1':
            raise IndexError('An Error')
    except Exception as exc:
        click.echo('Exception: {}'.format(exc))
        exit()

测试代码:

@mycli.group()
@click.pass_context
def mygroup(ctx):
    click.echo('mygroup: {}'.format(ctx.obj['a_var']))
    pass


@mygroup.command()
@click.pass_context
def mycommand(ctx):
    click.echo('mycommand: {}'.format(ctx.obj['a_var']))


if __name__ == "__main__":
    commands = (
        'mygroup mycommand',
        '--something 1 mygroup mycommand',
        '--something 2 mygroup mycommand',
        '--help',
        '--something 1 mygroup --help',
        '--something 1 mygroup mycommand --help',
    )

    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)
            mycli(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)]
-----------
> mygroup mycommand
Exception: An Error
-----------
> --something 1 mygroup mycommand
mygroup: 1
mycommand: 1
-----------
> --something 2 mygroup mycommand
Exception: An Error
-----------
> --help
Usage: test.py [OPTIONS] COMMAND [ARGS]...

Options:
  --something TEXT
  --help            Show this message and exit.

Commands:
  mygroup
-----------
> --something 1 mygroup --help
Usage: test.py mygroup [OPTIONS] COMMAND [ARGS]...

Options:
  --help  Show this message and exit.

Commands:
  mycommand
-----------
> --something 1 mygroup mycommand --help
mygroup: 1
Usage: test.py mygroup mycommand [OPTIONS]

Options:
  --help  Show this message and exit.

这篇关于Python Click-仅在成功执行父命令时才执行子命令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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