Python Click-仅在成功执行父命令时才执行子命令 [英] Python Click - only execute subcommand if parent command executed successfully
问题描述
我正在使用点击来构建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屋!