My code sample:
import click
def std_cb(ctx, param, standardize):
if standardize:
opt = click.Option(param_decls=['-a'],
help='this option only exists when -S is set')
else:
opt = click.Option(param_decls=['-b'],
help='this option only exists when -S is not set')
ctx.command.params.append(opt)
return standardize
@click.command()
@click.option('-S', '--standardize/--no-standardize', is_eager=True,
is_flag=True, default=False, callback=std_cb)
def get_options(standardize, **extra_opts):
print(locals())
if __name__ == '__main__':
uis = get_options.main(standalone_mode=False)
What I'm trying to achieve is to be able to dynamically create different options for a given command depending on the value of an eager flag option to the same command using the click library.
When I execute the above command on the CLI as $ python cli_test.py, this is printed to stdout {'standardize': False, 'extra_opts': {}}, as expected. Similarly $ python cli_test.py -S prints {'standardize': True, 'extra_opts': {}}, also expected.
And when I invoke the built-in --help option with $ python cli_test.py --help, I get:
Usage: cli_test.py [OPTIONS]
Options:
-S, --standardize / --no-standardize
-b TEXT this option only exists when -S is not set
--help Show this message and exit.
Which seems to suggest that the attachment of the --no-standardize specific option via the std_cb callback for the -S flag is working as well.
Similarly, $ python cli_test.py --help -S, produces:
Usage: cli_test.py [OPTIONS]
Options:
-S, --standardize / --no-standardize
-a TEXT this option only exists when -S is set
--help Show this message and exit.
Now with the -a option appearing due to the presence of the -S flag.
However, if I were to try and do $ python cli_test.py -b hello, I'd get the error: click.exceptions.NoSuchOption: no such option: -b.
And similarly, $ python cli_test.py -S -a world produces click.exceptions.NoSuchOption: no such option: -a, despite them showing up in the help page under their applicable -S flag value.
What I had expected to see from the given code example is of course, $ python cli_test.py -b hello printing {'standardize': True, 'extra_opts': {'b': 'hello'}}.
And $ python cli_test.py -S -a world printing {'standardize': True, 'extra_opts': {'a': 'world'}}.
In the Click docs, the authors do state that using @click.option "is equivalent to creating an Option instance manually and attaching it to the Command.params list.", so I'm not really sure what I'm doing wrong.