Skip to content

Commit

Permalink
Allow is_flag=True, multiple=True with non-bool flag_value
Browse files Browse the repository at this point in the history
Allows creating options with is_flag=True and multiple=True if
flag_value is also set to a non-bool value.

Fixes pallets#2292
  • Loading branch information
Brandon Carpenter committed May 24, 2022
1 parent 9c6f4c8 commit 63889fd
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 1 deletion.
10 changes: 10 additions & 0 deletions CHANGES.rst
@@ -1,5 +1,15 @@
.. currentmodule:: click

Version 8.1.4
-------------

Released TBD

- Do not show an error when attempting to create an option with
``multiple=True, is_flag=True`` if ``flag_value`` is not a ``bool``.
:issue:`2292`


Version 8.1.3
-------------

Expand Down
2 changes: 1 addition & 1 deletion src/click/core.py
Expand Up @@ -2580,7 +2580,7 @@ def __init__(
if self.is_flag:
raise TypeError("'count' is not valid with 'is_flag'.")

if self.multiple and self.is_flag:
if self.multiple and self.is_flag and isinstance(self.flag_value, bool):
raise TypeError("'multiple' is not valid with 'is_flag', use 'count'.")

def to_info_dict(self) -> t.Dict[str, t.Any]:
Expand Down
33 changes: 33 additions & 0 deletions tests/test_options.py
Expand Up @@ -922,3 +922,36 @@ def test_invalid_flag_combinations(runner, kwargs, message):
click.Option(["-a"], **kwargs)

assert message in str(e.value)


@pytest.mark.parametrize(
("args", "expected"),
[
([], "tags= verbosity=0"),
(["--foo", "--bar", "--baz"], "tags=foo,bar,baz verbosity=0"),
(["--bar", "--foo", "-vv"], "tags=bar,foo verbosity=2"),
(["--verbose"], "tags= verbosity=1"),
(["--quiet"], "tags= verbosity=-1"),
(["--bar", "--foo", "-m", "foo", "-vvvq"], "tags=bar,foo,foo verbosity=2"),
],
)
def test_multi_value_flags(runner, args, expected):
@click.command()
@click.option("--bar", "tags", flag_value="bar", multiple=True)
@click.option("--baz", "tags", flag_value="baz", multiple=True)
@click.option("--foo", "tags", flag_value="foo", multiple=True)
@click.option(
"-m", "--tag", "tags", type=click.Choice(["foo", "bar", "baz"]), multiple=True
)
@click.option(
"-q", "--quiet", "verbosity", is_flag=True, flag_value=-1, multiple=True
)
@click.option(
"-v", "--verbose", "verbosity", is_flag=True, flag_value=1, multiple=True
)
def cli(tags, verbosity):
click.echo(f"tags={','.join(tags)} verbosity={sum(verbosity)}", nl=False)

result = runner.invoke(cli, args)
assert not result.exception
assert result.output == expected

0 comments on commit 63889fd

Please sign in to comment.