diff --git a/src/click/core.py b/src/click/core.py index 6adc65ccd6..4ca8f842bc 100644 --- a/src/click/core.py +++ b/src/click/core.py @@ -3145,10 +3145,9 @@ def prompt_for_value(self, ctx: Context) -> t.Any: default = bool(default) return confirm(self.prompt, default) - # If show_default is set to True/False, provide this to `prompt` as well. For - # non-bool values of `show_default`, we use `prompt`'s default behavior + # Pass show_default to prompt regardless of its type (bool or str). prompt_kwargs: t.Any = {} - if isinstance(self.show_default, bool): + if self.show_default is not None: prompt_kwargs["show_default"] = self.show_default return prompt( diff --git a/src/click/termui.py b/src/click/termui.py index 2e98a0771c..fca119dd1c 100644 --- a/src/click/termui.py +++ b/src/click/termui.py @@ -60,7 +60,7 @@ def hidden_prompt_func(prompt: str) -> str: def _build_prompt( text: str, suffix: str, - show_default: bool = False, + show_default: bool | str = False, default: t.Any | None = None, show_choices: bool = True, type: ParamType | None = None, @@ -69,7 +69,10 @@ def _build_prompt( if type is not None and show_choices and isinstance(type, Choice): prompt += f" ({', '.join(map(str, type.choices))})" if default is not None and show_default: - prompt = f"{prompt} [{_format_default(default)}]" + if isinstance(show_default, str): + prompt = f"{prompt} [{show_default}]" + else: + prompt = f"{prompt} [{_format_default(default)}]" return f"{prompt}{suffix}" @@ -88,7 +91,7 @@ def prompt( type: ParamType | t.Any | None = None, value_proc: t.Callable[[str], t.Any] | None = None, prompt_suffix: str = ": ", - show_default: bool = True, + show_default: bool | str = True, err: bool = False, show_choices: bool = True, ) -> t.Any: diff --git a/tests/test_options.py b/tests/test_options.py index f198d10183..c99eb06f02 100644 --- a/tests/test_options.py +++ b/tests/test_options.py @@ -1248,6 +1248,20 @@ def test_show_default_string(runner): assert "[default: (unlimited)]" in message +def test_show_default_string_in_prompt(runner): + """When show_default is a string and prompt is enabled, the string is + shown in the prompt instead of the actual default value.""" + + @click.command() + @click.option("--name", default="secret", show_default="custom", prompt=True) + def cli(name): + click.echo(f"Name: {name}") + + result = runner.invoke(cli, input="\n") + assert "Name [custom]: " in result.output + assert "secret" not in result.output.split("\n")[0] + + def test_show_default_with_empty_string(runner): """When show_default is True and default is set to an empty string.""" opt = click.Option(["--limit"], default="", show_default=True)