Как получить доступ к контексту клика в настройке параметров? - PullRequest
1 голос
/ 03 апреля 2019

Я пытаюсь создать приложение cli, используя щелчок Python, и хочу использовать функцию, назначенную для click.core.Context.obj, в качестве функции обратного вызова опции. Функция, которую я использую в качестве функции обратного вызова, генерируется на основе ввода, поэтому я не могу импортировать эту функцию.

Вот код, который у меня есть:

Класс будет присвоен контексту:

class Config:
    def __init__(self, func_name):
        self.function = getattr(Config, func_name)

    def func_a():
        pass

    def func_b():
        pass

Команда:

import click


@click.group(name='group')
@click.option('-f', '--func-name')
@pass_context
def the_group(ctx, func_name):
    ctx.obj = Config(func_name)


@click.command('command')
@click.option('-o', '--my-option', callback=ctx.obj.function) # I want to use the function here
@click.pass_context
def the_command(ctx, my_option):
    click.echo(my_option)

Функция обратного вызова, которую я использовал в приведенном выше коде, не работает. Как правильно вызвать функцию ctx.obj.function?

1 Ответ

0 голосов
/ 05 апреля 2019

Я бы предложил добавить @staticmethod к вашему классу Config для использования в качестве цели callback, например:

Метод обратного вызова:

@staticmethod
def click_callback(ctx, param, value):
    getattr(ctx.obj, ctx.obj.func_name)()
    return value

Тестовый код:

import click

class Config:
    def __init__(self, func_name):
        self.func_name = func_name

    def func_a(self):
        click.echo('Func A')

    def func_b(self):
        click.echo('Func B')

    @staticmethod
    def click_callback(ctx, param, value):
        getattr(ctx.obj, ctx.obj.func_name)()
        return value


@click.group()
@click.option('-f', '--func-name', required=True)
@click.pass_context
def group(ctx, func_name):
    ctx.obj = Config(func_name)


@group.command()
@click.option('--my-option', '-o', callback=Config.click_callback)
def command(my_option):
    click.echo('command: {}'.format(my_option))


if __name__ == "__main__":
    commands = (
        '-f func_a command -o optionA',
        '-f func_b command -o optionB',
        '-f func_a command -o ',
        'command',
        '--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)
            group(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)]
-----------
> -f func_a command -o optionA
Func A
command: optionA
-----------
> -f func_b command -o optionB
Func B
command: optionB
-----------
> -f func_a command -o 
Error: -o option requires an argument
-----------
> command
Usage: test.py [OPTIONS] COMMAND [ARGS]...

Error: Missing option "-f" / "--func-name".
-----------
> --help
Usage: test.py [OPTIONS] COMMAND [ARGS]...

Options:
  -f, --func-name TEXT  [required]
  --help                Show this message and exit.

Commands:
  command
-----------
> 
Usage: test.py [OPTIONS] COMMAND [ARGS]...

Options:
  -f, --func-name TEXT  [required]
  --help                Show this message and exit.

Commands:
  command
...