Вложенные команды и справка с помощью щелчка

#python #python-click

Вопрос:

Рассмотрим пример вложенной команды с помощью щелчка (здесь):

 #  foo.py

@click.group()
@click.option("--debug/--no-debug", default=False)
@click.pass_context
def cli(ctx, debug):
    # ensure that ctx.obj exists and is a dict (in case `cli()` is called
    # by means other than the `if` block below)
    ctx.ensure_object(dict)

    ctx.obj["DEBUG"] = debug


@cli.command()
@click.pass_context
def sync(ctx):
    click.echo(f"Debug is {'on' if ctx.obj['DEBUG'] else 'off'}")


if __name__ == "__main__":
    cli(obj={})
 

Выполнение python foo.py --help возвращает следующее:

 Usage: foo.py [OPTIONS] COMMAND [ARGS]...

Options:
  --debug / --no-debug
  --help                Show this message and exit.

Commands:
  sync
 

Обратите внимание на это указание опции «глобальный» debug . Однако при запуске python foo.py sync --help возвращаемая строка:

 Usage: foo.py sync [OPTIONS]

Options:
  --help  Show this message and exit.
 

и нет никакого упоминания о «глобальном» варианте. Есть ли способ распечатать параметры родительских команд при использовании click таким образом?

Комментарии:

1. Не очень понятно, что вам нужно. Вы хотите иметь возможность подать --global заявку как до, так и после sync ? Или просто хотите каким-то образом отобразить оба параметра в интерфейсе командной строки и параметры sync одновременно?

2. Я пытаюсь понять последнее. При запуске foo.py sync неявно глобальные параметры влияют на поведение sync . Поэтому может быть полезно, чтобы при запуске foo.py sync --help были упомянуты неявные параметры.

Ответ №1:

Почему это работает именно так

В следующем вызове:

 python foo.py sync --help`
 

Щелкните, чтобы выбрать --help опцию для применения к sync подкоманде.

Если пользователь хочет просмотреть параметры родительской команды, они будут запущены:

 python foo.py --help
 

Щелчок заходит так далеко, что игнорирует любые следующие аргументы после анализа a --help (нетерпеливый анализ):

 python foo.py --help these will be just ignored
 

Изменение вывода —help

Я предполагаю, что вы хотели бы что-то вроде:

 $ clicmd subcmd --help 
Usage: clicmd subcmd [OPTIONS] COMMAND [ARGS]   # (as provided by click)

Some usage instructions                         # (as provided by click)

Options:
# options for `subcmd`                          # (as provided by click)

Inherited/global options from `clicmd`:    # (This section would be new)  
# relevant options that apply here 

Commands:
# subcommand info, if any.                 # (as provided by click)
 

Чтобы сделать что-то подобное, вы могли бы выйти из click.command класса и реализовать format_options функцию.
https://click.palletsprojects.com/en/8.0.x/api/#click.Команда.format_options

 class YourCmd(click.Command):
    def format_options(self, ctx, formatter):
        # implement your extra options here

@click.command(cls=YourCmd)
def your_cli_cmd():
    pass
 
только частично связано, но, возможно, полезно для вас

Допустим, вы хотите получить доступ к параметрам родительской команды только один или два раза.
Для этого вы можете использовать @click.pass_context , чтобы получить параметры родительской команды.

Вот минимальный пример, который я только что написал для вас:

 @click.group()
@click.option("--debug/--nodebug", help="Toggle for verbose logging output")
@click.pass_context
def how_to_access_parent(ctx, debug):
    ctx.ensure_object(dict)
    ctx.obj["DEBUG"] = debug


@how_to_access_parent.command()
@click.option("--childopt", type=click.INT, help="something childish")
@click.pass_context
def childcmd(ctx, childopt):
    parent_cmd = ctx.parent.command
    for param in parent_cmd.params:
        click.echo(param.get_help_record(ctx))
        # ('--debug / --nodebug', 'Toggle for verbose logging output')


how_to_access_parent(obj={})
 

Комментарии:

1. Эта gh команда является хорошим примером интерфейса командной строки, который использует «унаследованные параметры» в своей документации. Например cli.github.com/manual/gh_pr_diff