If I invoke a Click subcommand from another command, it doesn't look like the invoked command is validating the passed fields. Am I doing something wrong?
This is a small example:
import click
import cli_add
import cli_sub
import sys
@click.group()
@click.pass_context
def cli(ctx):
"""Main CLI"""
cli.add_command(cli_add.add)
cli.add_command(cli_sub.subtract)
if __name__ == "__main__":
sys.exit(cli())
import click
@click.group()
@click.pass_context
def subtract(ctx):
"""subtract"""
@subtract.command()
@click.option('--number', type=int, required=True)
@click.pass_context
def number(ctx, number):
click.echo("Subtract {}".format(number))
import click
import cli_sub
@click.group()
@click.pass_context
def add(ctx):
"""add"""
@add.command()
@click.option('--number', type=int, required=True)
@click.pass_context
def number(ctx, number):
if number > 0:
click.echo("Add {}".format(number))
else:
ctx.invoke(cli_sub.number)
Example calls:
python cli_main.py add number --number 1
Add 1
python cli_main.py subtract number --number 1
Subtract 1
python cli_main.py subtract number
Usage: cli_main.py subtract number [OPTIONS]
Try "cli_main.py subtract number --help" for help.
Error: Missing option "--number".
These work as expected. However, if I call the following, it fails in an unexpected way.
python cli_main.py add number --number -1
Subtract None
It does invoke the subtraction method. The problem is that I am not passing a parameter in my call to it:
ctx.invoke(cli_sub.number)
So, I'd expect it to fail and provide me with the usage text, especially since the number
option is required.
Am I not invoking this subcommand correctly? Why does the invocation not trigger parameter checks the same way directly calling the subcommand without the parameter does?
Your analysis of the problem is correct, you do need to pass the parameters. You can pass the parameter like:
ctx.invoke(cli_sub.number, number=number)
As to your other question:
Why does the invocation not trigger parameter checks the same way directly calling the sub-command without the parameter does?
This checking is done when parsing the parameters. If you are calling ctx.invoke()
directly it is expected you understand what your command needs.