click: Can't access help of subcommands without going through parent's prompts
I have a script with subcommands that both require a username/password. I abstracted this to the parent. Here’s a short example demonstrating the issue:
import click
@click.group()
@click.option('--username', default='admin', prompt=True)
@click.password_option()
def cli(username, password):
"""This is my parent description"""
pass
@cli.command()
@click.option('--reference', help="I should be able to see this without entering a username and password.")
def subcommand(reference):
"""This is my subcommand"""
pass
If you access the main help:
my_prog --help
It displays the help page without any prompting for username or password, as expected. However, if you try to access the help page for the subcommand:
my_prog subcommand --help
It prompts for username and password before displaying the help page of the subcommand. This makes sense, but it still isn’t expected behavior by the end user. As my sample program says, I should be able to see help without entering a username and password.
What’s the correct way to model my desired behavior? Do I have to move and duplicate the username and password prompt options into each of my sub commands?
About this issue
- Original URL
- State: closed
- Created 9 years ago
- Reactions: 15
- Comments: 15 (3 by maintainers)
Commits related to this issue
- change click obj from dict to new LazyClient light wrapper this should work around the click issue that invokes parent commands when a child-command is passed '--help' ( pallets/click#295 ) fixes #1... — committed to costela/wile by costela 7 years ago
- Share common options through subcommand decorator Previously the common options where given for the base command `main`, which destroyed the `--help` on subcommands (see https://github.com/pallets/cl... — committed to konradkonrad/raiden-contracts by konradkonrad 6 years ago
- Share common options through subcommand decorator Previously the common options where given for the base command `main`, which destroyed the `--help` on subcommands (see https://github.com/pallets/cl... — committed to konradkonrad/raiden-contracts by konradkonrad 6 years ago
This is a tough one to fix and I am not sure if it will be entirely possible without causing more issues elsewhere. 😦
I don’t think this is solvable within Click in a general way.
Click parses and process all args and callbacks for a command before moving on to a subcommand. The subcommand can be resolved dynamically based on the current command’s context, so it’s not possible to guarantee what commands and params will be processed before actually running the pipeline. Additionally, the help option isn’t guaranteed to be
--help, and--helpcould also show up as the value of another option, so it’s not possible to guarantee that--helpshowing up in the raw args means the help callback will be executed.There are a few different solutions a project can implement:
prompt_requiredargument, that changes the behavior of prompts so they’re only shown if the option is required or if the flag without a value is given. This applies to prompts, but it doesn’t apply to missing required parameters.prompt=Truein the parameters, use a helper function before the values are actually used that will callclick.prompt()if they weren’t provided.--helpparam can be customized to figure out the subcommand and show its help.helpcommand (likegit help <command name>) is fairly straightforward to implement usinggroup.get_command(ctx, name)andcommand.get_help(ctx).