Max*_*Tet 7 python python-click
我正在使用 Python 和 Click 编写一个 CLI 工具。其中一个命令有一个选项,其type=(str, str))使用方式如下:command subcommand --option foo bar。
第一个参数 (foo) 有多个选项可供选择,对于第一个参数的每个选择,第二个参数 (bar) 也有多个选项可供选择。因此第二个参数的选项取决于第一个参数的选择!
问题是:如何使用Click提供的支持来为此编写自动完成功能?
尤其:
Ste*_*uch 10
要自动完成由两个字符串组成的点击选项,其中第二个字符串依赖于第一个字符串,您不需要两个完成函数。您只需要一种方法来确定当前正在完成两个字符串中的哪一个。对于名为的选项,--opt我们可以完成类似的类型(str, str):
def get_opts(ctx, args, incomplete):
""" auto complete for option "opt"
:param ctx: The current click context.
:param args: The list of arguments passed in.
:param incomplete: The partial word that is being completed, as a
string. May be an empty string '' if no characters have
been entered yet.
:return: list of possible choices
"""
opts = {
'foo1': ('bar11', 'bar21', 'bar31'),
'foo2': ('bar12', 'bar22', 'bar32'),
'fox3': ('bar13', 'bar23', 'bar33'),
}
if args[-1] == '--opt':
possible_choices = opts.keys()
elif args[-1] in opts:
possible_choices = opts[args[-1]]
else:
possible_choices = ()
return [arg for arg in possible_choices if arg.startswith(incomplete)]
Run Code Online (Sandbox Code Playgroud)
您可以传递该autocompletion函数来单击:
@click.option('--opt', type=(str, str), autocompletion=get_opts)
Run Code Online (Sandbox Code Playgroud)
该autocompletion函数传递一个 的列表args。当完成一个选项时,我们可以在.txt文件中找到我们的选项名称args。在这种情况下,我们可以在 args 中查找--opt来获取锚点,以确定我们是否正在完成第一个字符串或第二个字符串。然后我们返回与已输入的字符匹配的字符串。
import click
@click.command()
@click.option('--opt', type=(str, str), autocompletion=get_opts)
@click.argument('arg')
def cli(opt, arg):
"""My Great Cli"""
if __name__ == "__main__":
commands = (
('--opt', 2, 'foo1 foo2 fox3'),
('--opt f', 2, 'foo1 foo2 fox3'),
('--opt fo', 2, 'foo1 foo2 fox3'),
('--opt foo', 2, 'foo1 foo2'),
('--opt fox', 2, 'fox3'),
('--opt foz', 2, ''),
('--opt foo2 b', 3, 'bar12 bar22 bar32'),
('--opt foo2 bar1', 3, 'bar12'),
('--opt foo2 baz', 3, ''),
)
import os
import sys
from unittest import mock
from click._bashcomplete import do_complete
failed = []
for cmd_args in commands:
cmd_args_with_arg = (
'arg ' + cmd_args[0], cmd_args[1] + 1, cmd_args[2])
for cmd in (cmd_args, cmd_args_with_arg):
with mock.patch('click._bashcomplete.echo') as echo:
os.environ['COMP_WORDS'] = 'x ' + cmd[0]
os.environ['COMP_CWORD'] = str(cmd[1])
do_complete(cli, 'x', False)
completions = [c[0][0] for c in echo.call_args_list]
if completions != cmd[2].split():
failed.append(completions, cmd[2].split())
print('Click Version: {}'.format(click.__version__))
print('Python Version: {}'.format(sys.version))
if failed:
for fail in failed:
print('Got {}, expected {}'.format(completions, cmd[2].split()))
else:
print('All tests passed')
Run Code Online (Sandbox Code Playgroud)
Click Version: 7.0
Python Version: 3.6.3 (v3.6.3:2c5fed8, Oct 3 2017, 18:11:49) [MSC v.1900 64 bit (AMD64)]
All tests passed
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3804 次 |
| 最近记录: |