diff --git a/src/click/core.py b/src/click/core.py index 6adc65ccd6..9485afa38e 100644 --- a/src/click/core.py +++ b/src/click/core.py @@ -2820,8 +2820,10 @@ def __init__( # and a flag_value set to something else. Refs: # https://github.com/pallets/click/issues/3024#issuecomment-3146199461 # https://github.com/pallets/click/pull/3030/commits/06847da + self._default_from_flag_value = False if self.default is True and self.flag_value is not UNSET: self.default = self.flag_value + self._default_from_flag_value = True # Set the default flag_value if it is not set. if self.flag_value is UNSET: @@ -2885,6 +2887,37 @@ def to_info_dict(self) -> dict[str, t.Any]: ) return info_dict + @t.overload + def get_default( + self, ctx: Context, call: t.Literal[True] = True + ) -> t.Any | None: ... + + @t.overload + def get_default( + self, ctx: Context, call: bool = ... + ) -> t.Any | t.Callable[[], t.Any] | None: ... + + def get_default( + self, ctx: Context, call: bool = True + ) -> t.Any | t.Callable[[], t.Any] | None: + value = ctx.lookup_default(self.name, call=False) # type: ignore + + if value is UNSET: + value = self.default + + # Don't call the default if it was set from the flag_value via + # the ``default=True`` alignment. A callable flag_value (e.g. a + # class used as a flag value) should be returned as-is, not + # instantiated. See https://github.com/pallets/click/issues/3121 + if ( + call + and callable(value) + and not self._default_from_flag_value + ): + value = value() + + return value + def get_error_hint(self, ctx: Context) -> str: result = super().get_error_hint(ctx) if self.show_envvar and self.envvar is not None: diff --git a/tests/test_options.py b/tests/test_options.py index f198d10183..e2c473bba8 100644 --- a/tests/test_options.py +++ b/tests/test_options.py @@ -2148,7 +2148,7 @@ def scan(pro): {"flag_value": Class1, "default": True}, {"flag_value": Class2}, [], - re.compile(r"''"), + "", ), ( {"flag_value": Class1, "default": True}, @@ -2170,7 +2170,7 @@ def scan(pro): {"flag_value": Class1, "type": UNPROCESSED, "default": True}, {"flag_value": Class2, "type": UNPROCESSED}, [], - re.compile(r""), + Class1, ), ( {"flag_value": Class1, "type": UNPROCESSED, "default": True},