Использование click.CommandCollection удаляет параметры группы
import click
@click.group()
@click.option('--username')
def cli1(username):
click.echo(username)
@cli1.command()
def something():
click.echo('howdy')
@click.group()
def cli2():
pass
@cli2.command()
def somethingelse():
click.echo('doody')
cli = click.CommandCollection(sources=[cli1, cli2])
if __name__ == '__main__':
cli()
Я ожидаю, что это позволит мне пройти --username
в something
, но когда я запускаю этот скрипт:
python script.py something --username hi
Я получил:
Ошибка: нет такой опции: --username
Кажется, с помощью CommandCollection
ломает мои варианты. Кто-нибудь еще имел дело с этим раньше? В репо кликов есть открытый тикет, который не затрагивался с 2015 года и не имеет решения.
1 ответ
С небольшим количеством новой сантехники это может быть сделано.
Как??
Вы можете унаследовать от click.Group
а затем передать созданный класс click.group()
лайк:
@click.group(cls=GroupWithCommandOptions)
В новом классе параметры группы могут быть применены к команде для разбора, а затем во время вызова команды можно вызывать групповую функцию с соответствующими параметрами.
Новый групповой класс:
import click
class GroupWithCommandOptions(click.Group):
""" Allow application of options to group with multi command """
def add_command(self, cmd, name=None):
""" Hook the added command and put the group options on the command """
click.Group.add_command(self, cmd, name=name)
# add the group parameters to the command
for param in self.params:
cmd.params.append(param)
# hook the command's invoke with our own
cmd.invoke = self.build_command_invoke(cmd.invoke)
self.invoke_without_command = True
def build_command_invoke(self, original_invoke):
def command_invoke(ctx):
""" insert invocation of group function """
# separate the group parameters
ctx.obj = dict(_params=dict())
for param in self.params:
name = param.name
ctx.obj['_params'][name] = ctx.params[name]
del ctx.params[name]
# call the group function with its parameters
params = ctx.params
ctx.params = ctx.obj['_params']
self.invoke(ctx)
ctx.params = params
# now call (invoke) the original command
original_invoke(ctx)
return command_invoke
Тестовый код:
# Pass new group class to our group which needs options
@click.group(cls=GroupWithCommandOptions)
@click.option('--username')
def cli1(username):
click.echo(username)
@cli1.command()
def something():
click.echo('howdy')
@click.group()
def cli2():
pass
@cli2.command()
def somethingelse():
click.echo('doody')
cli = click.CommandCollection(sources=[cli1, cli2])
if __name__ == '__main__':
cli('something --username hi'.split())
Результаты:
hi
howdy