[Python] Make option depend on previous option

Discussão em 'Python' iniciado por Stack, Abril 19, 2025.

  1. Stack

    Stack Membro Participativo

    Is there an idiomatic way, using the Python Click library, to create a command where one option depends on a value set by a previous option?

    A concrete example (my use case) would be that a command takes an option of type click.File as input, but also an encoding option which specifies the encoding of the input stream:

    import click

    @click.command()
    @click.option("--encoding", type=str, default="utf-8")
    @click.option("--input",
    type=click.File("r", encoding="CAN I SET THIS DYNAMICALLY BASED ON --encoding?"))
    def cli(encoding, input):
    pass


    I guess it would have to involve some kind of deferred evaluation using a callable, but I'm not sure if it's even possible given the current Click API.

    I've figured out I can do something along the following lines:

    import click

    @click.command()
    @click.pass_context
    @click.option("--encoding", type=str, default="utf-8")
    @click.option("--input", type=str, default="-")
    def cli(ctx, encoding, input):
    input = click.File("r", encoding=encoding)(input, ctx=ctx)


    But it somehow feels less readable / maintainable to decouple the option decorator from the semantically correct type constraint that applies to it, and put str in there instead as a dummy. So if there's a way to keep these two together, please enlighten me.

    A proposed workaround:

    I guess I could use the click.File type twice, making it lazy in the decorator so that the file isn't actually left opened, the first time around:

    @click.option("--input", type=click.File("r", lazy=True), default="-")


    This feels semantically more satisfying, but also redundant.

    Continue reading...

Compartilhe esta Página