'How to get one or none arguments with click?

Click allows for variadic arguments like this:

@click.command()
@click.argument('src', nargs=-1)
@click.argument('dst', nargs=1)
def copy(src, dst):
    """Move file SRC to DST."""
    for fn in src:
        click.echo(f"move {fn} to folder {dst}")

But how can I specify at most one argument? While it may be interesting to have a minimum and maximum number, I am looking for adding an optional argument.

I think nargs=-1 and checking if n<2 myself would work like this

@click.command()
@click.argument('some_argument')
@click.argument('optional_argument', nargs=-1)
def example(some_argument, optional_argument):
    if len(option_argument) > 1:
        print("Too many arguments")
        return
    # do something with or without the optional argument

but the automatically generated helptext then just should some_argument optional_argument... and it should indicate it by some_argument [optional_argument]. And of course it would be nice if click could handle the check itself instead of only checking for zero or more arguments.



Solution 1:[1]

I think that you may need a command option (Click docs) here, since the argument is really optional:

@click.command()
@click.argument('some_argument')
@click.option('optional_argument', default='some value')
def example(some_argument, optional_argument):
    # do something with or without the optional argument

Because optional_argument is now an option, the command can be used without providing a value for optional_argument or providing a single value (that will override the default value).

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 aaossa