9

I just stumbled upon a piece of code that defines a click option as such:

@click.option(
    "-s",
    "--status",
    default=True,
    is_flag=True,
    help="Show status",
)

Does this means that the status is True, unless the -s is supplied, in which case it will become False?

3 Answers 3

7

For options that are both a flag and defaulted to True, specifying the option on the command line will set that option to False; while not specifying will give the default True.

Test Code:

import click    

@click.command()
@click.option(
    "-s",
    "--status",
    default=True,
    is_flag=True,
    help="Show status",
)
def main(status):
    click.echo('status: {}'.format(status))


if __name__ == "__main__":
    commands = (
        '',
        '-s',
        '--status',
        '--help',
    )

    import sys, time

    time.sleep(1)
    print('Click Version: {}'.format(click.__version__))
    print('Python Version: {}'.format(sys.version))
    for command in commands:
        try:
            time.sleep(0.1)
            print('-----------')
            print('> ' + command)
            time.sleep(0.1)
            main(command.split())

        except BaseException as exc:
            if str(exc) != '0' and \
                    not isinstance(exc, (click.ClickException, SystemExit)):
                raise

Results:

Click Version: 6.7
Python Version: 3.6.3 (v3.6.3:2c5fed8, Oct  3 2017, 18:11:49) [MSC v.1900 64 bit (AMD64)]
-----------
> 
status: True
-----------
> -s
status: False
-----------
> --status
status: False
-----------
> --help
Usage: test.py [OPTIONS]

Options:
  -s, --status  Show status
  --help        Show this message and exit.
Sign up to request clarification or add additional context in comments.

Comments

4

While the question is old, I just stumbled upon, having a similar question. And I found the answer rather incomplete. So here is what I found out.

Actually the code example makes no sense. When using default=True, you should always specify an extra for name of the variable, otherwise either the variable or the option has a reversed logic.

So, in the original example, if you want --status to be the default, re-write the code like this:

@click.option(
    "-n",
    "--no-status",
    "status"
    default=True,
    is_flag=True,
    help="Do not show status",
)
def main(status):
...

If you change an existing tool like this, you may also want to re-add --status as a documented obsolete option to stay compatible.

Comments

2

@click.option('--status/--no-status', default=True) is the way to go, as suggested by click documentation

Example:

script.py:

import click

@click.command
@click.option('--status/--no-status', default=True)
def main(status):
    click.echo('status: {}'.format(status))

if __name__ == '__main__':
    main()
$ python3 script.py 
status: True

$ python3 script.py --status
status: True

$ python3 script.py --no-status
status: False

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.