7

クリックで、次のコマンドを定義しています。

@click.command('time', short_help='Timesheet Generator')
@click.argument('time_command', type=click.Choice(['this', 'last']))
@click.argument('data_mode', type=click.Choice(['excel', 'exchange']), default='exchange')
@click.option('--password', prompt=True, hide_input=True, confirmation_prompt=False)
@pass_context
def cli(ctx, time_command, data_mode, password):

私が抱えている問題は、data_mode引数が等しい場合にのみパスワードを要求することですexchange。どうすればこれをやってのけることができますか?

4

2 に答える 2

2

click.Optionから派生したカスタム クラスを構築し、そのクラスで次のclick.Option.handle_parse_result()ようなメソッドをオーバーライドすることで、別のパラメータが特定の値と一致しない場合にプロンプ​​トを表示する必要をなくすことができます。

カスタム クラス:

import click

def PromptIf(arg_name, arg_value):

    class Cls(click.Option):

        def __init__(self, *args, **kwargs):
            kwargs['prompt'] = kwargs.get('prompt', True)
            super(Cls, self).__init__(*args, **kwargs)

        def handle_parse_result(self, ctx, opts, args):
            assert any(c.name == arg_name for c in ctx.command.params), \
                "Param '{}' not found for option '{}'".format(
                    arg_name, self.name)

            if arg_name not in opts:
                raise click.UsageError(
                    "Illegal usage: `%s` is a required parameter with" % (
                        arg_name))

            # remove prompt from 
            if opts[arg_name] != arg_value:
                self.prompt = None

            return super(Cls, self).handle_parse_result(ctx, opts, args)

    return Cls

カスタム クラスの使用:

カスタム クラスを使用するには、次のようにclsパラメータをclick.optionデコレータに渡します。

@click.option('--an_option', cls=PromptIf('an_argument', 'an_arg_value'))

目的の値を調べるパラメーターの名前と、確認する値を渡します。

これはどのように作動しますか?

これが機能するのは、click が適切に設計された OO フレームワークであるためです。通常、@click.option()デコレーターはclick.Optionオブジェクトをインスタンス化しますが、この動作をclsパラメーターでオーバーライドできます。click.Optionそのため、独自のクラスから継承して目的のメソッドをオーバーライドするのは比較的簡単です。

この場合click.Option.handle_parse_result()、他の指定されたパラメーターが目的のパラメーターと一致しない場合にプロンプ​​トを表示する必要性をオーバーライドして無効にします。

注: この回答は、この回答に触発されたものです。

テストコード:

@click.command()
@click.argument('an_argument', type=click.Choice(['excel', 'exchange']),
                default='exchange')
@click.option('--password', hide_input=True, confirmation_prompt=False,
              cls=PromptIf('an_argument', 'exchange'))
def cli(an_argument, password):
    click.echo(an_argument)
    click.echo(password)

cli('exchange'.split())
于 2018-04-01T23:04:33.093 に答える