Skip to content

Commit

Permalink
Fix default values of multiple options with optional values
Browse files Browse the repository at this point in the history
  • Loading branch information
ikapelyukhin committed Jul 13, 2021
1 parent ddcabdd commit 29c74c8
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 0 deletions.
2 changes: 2 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ Unreleased
:issue:`1969`
- Fix shell completion for arguments that start with a forward slash
such as absolute file paths. :issue:`1929`
- Fix default values of multiple options with optional values.
:issue:`2001`


Version 8.0.1
Expand Down
10 changes: 10 additions & 0 deletions src/click/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -2857,6 +2857,16 @@ def consume_value(
) -> t.Tuple[t.Any, ParameterSource]:
value, source = super().consume_value(ctx, opts)

if self.multiple:
value = [self._consume_single_value(ctx, v, source)[0] for v in value]
else:
value, source = self._consume_single_value(ctx, value, source)

return value, source

def _consume_single_value(
self, ctx: Context, value: t.Any, source: ParameterSource
) -> t.Tuple[t.Any, ParameterSource]:
# The parser will emit a sentinel value if the option can be
# given as a flag without a value. This is different from None
# to distinguish from the flag not being given at all.
Expand Down
55 changes: 55 additions & 0 deletions tests/test_options.py
Original file line number Diff line number Diff line change
Expand Up @@ -769,6 +769,61 @@ def cli(opt, a, b):
assert result.return_value == expect


@pytest.mark.parametrize(
("args", "expect"),
[
(None, ((), None, ())),
(["--opt"], (("flag",), None, ())),
(["--opt", "-a", 42], (("flag",), "42", ())),
(["--opt", "test", "-a", 42], (("test",), "42", ())),
(["--opt=test", "-a", 42], (("test",), "42", ())),
(["-o"], (("flag",), None, ())),
(["-o", "-a", 42], (("flag",), "42", ())),
(["-o", "test", "-a", 42], (("test",), "42", ())),
(["-otest", "-a", 42], (("test",), "42", ())),
(["a", "b", "c"], ((), None, ("a", "b", "c"))),
(["--opt", "a", "b", "c"], (("a",), None, ("b", "c"))),
(["--opt", "test"], (("test",), None, ())),
(["-otest", "a", "b", "c"], (("test",), None, ("a", "b", "c"))),
(["--opt=test", "a", "b", "c"], (("test",), None, ("a", "b", "c"))),
(
["--opt", "--opt", "--opt", "-a", 42],
(
(
"flag",
"flag",
"flag",
),
"42",
(),
),
),
(
["--opt", "--opt", "test", "--opt", "-a", 42],
(
(
"flag",
"test",
"flag",
),
"42",
(),
),
),
],
)
def test_multiple_option_with_optional_value(runner, args, expect):
@click.command()
@click.option("-o", "--opt", is_flag=False, flag_value="flag", multiple=True)
@click.option("-a")
@click.argument("b", nargs=-1)
def cli(opt, a, b):
return opt, a, b

result = runner.invoke(cli, args, standalone_mode=False, catch_exceptions=False)
assert result.return_value == expect


def test_type_from_flag_value():
param = click.Option(["-a", "x"], default=True, flag_value=4)
assert param.type is click.INT
Expand Down

0 comments on commit 29c74c8

Please sign in to comment.