From aa6f36017e5132836ea8679a4143a08944fa5c8c Mon Sep 17 00:00:00 2001 From: Ivan Kapelyukhin Date: Tue, 13 Jul 2021 21:49:39 +0200 Subject: [PATCH] option with multiple and flag_value replaces internal placeholder Co-authored-by: David Lord --- CHANGES.rst | 2 ++ src/click/core.py | 8 ++++++++ tests/test_options.py | 23 +++++++++++++++++++++++ 3 files changed, 33 insertions(+) diff --git a/CHANGES.rst b/CHANGES.rst index 7c6e4a705..b82b477bc 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -24,6 +24,8 @@ Unreleased :issue:`2072` - Default values are not cast to the parameter type twice during processing. :issue:`2085` +- Options with ``multiple`` and ``flag_value`` use the flag value + instead of leaving an internal placeholder. :issue:`2001` Version 8.0.1 diff --git a/src/click/core.py b/src/click/core.py index 6cdba37d6..77a536aa3 100644 --- a/src/click/core.py +++ b/src/click/core.py @@ -2853,6 +2853,14 @@ def consume_value( value = self.flag_value source = ParameterSource.COMMANDLINE + elif ( + self.multiple + and value is not None + and any(v is _flag_needs_value for v in value) + ): + value = [self.flag_value if v is _flag_needs_value else v for v in value] + source = ParameterSource.COMMANDLINE + # The value wasn't set, or used the param's default, prompt if # prompting is enabled. elif ( diff --git a/tests/test_options.py b/tests/test_options.py index 06a70b463..2e343372b 100644 --- a/tests/test_options.py +++ b/tests/test_options.py @@ -792,6 +792,29 @@ def cli(opt, a, b): assert result.return_value == expect +def test_multiple_option_with_optional_value(runner): + cli = click.Command( + "cli", + params=[ + click.Option(["-f"], is_flag=False, flag_value="flag", multiple=True), + click.Option(["-a"]), + click.Argument(["b"], nargs=-1), + ], + callback=lambda **kwargs: kwargs, + ) + result = runner.invoke( + cli, + ["-f", "-f", "other", "-f", "-a", "1", "a", "b"], + standalone_mode=False, + catch_exceptions=False, + ) + assert result.return_value == { + "f": ("flag", "other", "flag"), + "a": "1", + "b": ("a", "b"), + } + + def test_type_from_flag_value(): param = click.Option(["-a", "x"], default=True, flag_value=4) assert param.type is click.INT