@@ -2891,13 +2891,32 @@ def to_info_dict(self) -> dict[str, t.Any]:
28912891 def get_default (
28922892 self , ctx : Context , call : bool = True
28932893 ) -> t .Any | t .Callable [[], t .Any ] | None :
2894+ """For non-boolean flag options, ``default=True`` is treated as a
2895+ sentinel meaning "activate this flag by default" and is resolved to
2896+ :attr:`flag_value`. This resolution is performed lazily here (rather
2897+ than eagerly in :meth:`__init__`) to prevent callable ``flag_value``
2898+ values (like classes) from being instantiated prematurely.
2899+
2900+ For example, with ``--upper/--lower`` feature switches where
2901+ ``flag_value="upper"`` and ``default=True``, the default resolves
2902+ to ``"upper"``.
2903+
2904+ .. caution::
2905+ This substitution only applies to **non-boolean** flags
2906+ (:attr:`is_bool_flag` is ``False``). For boolean flags, ``True`` is
2907+ not a sentinel but a legitimate Python value, so ``default=True`` is
2908+ returned as-is. Without this distinction,
2909+ ``flag_value=False, default=True`` would silently always return
2910+ ``False``, regardless of whether the flag was passed.
2911+
2912+ .. versionchanged:: 8.3
2913+ ``default=True`` is no longer substituted with ``flag_value`` for
2914+ boolean flags, fixing negative boolean flags like
2915+ ``flag_value=False, default=True``. :issue:`3111`
2916+ """
28942917 value = super ().get_default (ctx , call = False )
28952918
2896- # Lazily resolve default=True to flag_value. Doing this here
2897- # (instead of eagerly in __init__) prevents callable flag_values
2898- # (like classes) from being instantiated by the callable check below.
2899- # https://github.com/pallets/click/issues/3121
2900- if value is True and self .is_flag :
2919+ if value is True and self .is_flag and not self .is_bool_flag :
29012920 value = self .flag_value
29022921 elif call and callable (value ):
29032922 value = value ()
0 commit comments