Python Нажмите автозаполнение для (str, str) вариант - PullRequest
2 голосов
/ 27 октября 2019

Я пишу инструмент CLI с Python и Click. Одна из команд имеет параметр type=(str, str)), который используется следующим образом: command subcommand --option foo bar.

Существует несколько вариантов выбора для первого аргумента (foo) и для каждого выбора первого аргумента. Есть несколько вариантов для второго (бар). Таким образом, параметры второго аргумента зависят от выбора первого!

Вопрос: как я могу использовать поддержку , которую предоставляет Click , чтобы написать автозаполнение для этого?

В частности:

  • нужны ли мне две функции завершения, по одной для каждого аргумента?
  • И как вторая функция обеспечивает выбор первого аргумента?
  • Как определить две функции завершения для одной опции?
  • Или я могу использовать одну функцию для обоих аргументов? Как это будет выглядеть?

1 Ответ

1 голос
/ 30 октября 2019

Для автозаполнения опции щелчка, состоящей из двух строк, в которой вторая строка зависит от первой, вам не нужны две функции завершения. Вам просто нужен способ определить, какая из двух строк в данный момент завершается. Для опции с именем --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)]

Используя автозаполнение

Вы можете передать autocompletionФункция для щелчка, например:

@click.option('--opt', type=(str, str), autocompletion=get_opts)

Как это работает?

Функция autocompletion передает список 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')

Результаты теста:

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
...