Is there an idiomatic way using the Python Click library to create a command in which one parameter depends on the value set by the previous option?
A specific example (my use case) is that the command accepts a click.File
type as an input parameter, as well as an encoding parameter that defines 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 suppose that would have to include some kind of deferred evaluation using the called one, but I'm not sure if this is possible even using the current Click API.
I realized that I can do something in 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 seems less readable / supported to separate the option decoder from the semantically correct type constraint that applies to it, and instead put str
instead as a dummy. Therefore, if there is a way to keep these two together, please enlighten me.
Proposed Solution:
I think I could use the type click.File
twice, making it lazy in the decorator so that the file is not actually open, for the first time:
@click.option("--input", type=click.File("r", lazy=True), default="-")
It feels semantically more satisfying, but also redundant.