Skip to content

Commit 22351f8

Browse files
committed
Use default=True as a sentinel for non-boolean flags
Refs: #3111
1 parent 5850ef9 commit 22351f8

1 file changed

Lines changed: 25 additions & 5 deletions

File tree

src/click/core.py

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2891,13 +2891,33 @@ 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+
(:issue:`3121`, :pr:`3225`).
2900+
2901+
For example, with ``--upper/--lower`` feature switches where
2902+
``flag_value="upper"`` and ``default=True``, the default resolves
2903+
to ``"upper"``.
2904+
2905+
.. caution::
2906+
This substitution only applies to **non-boolean** flags
2907+
(:attr:`is_bool_flag` is ``False``). For boolean flags, ``True`` is
2908+
not a sentinel but a legitimate Python value, so ``default=True`` is
2909+
returned as-is. Without this distinction, ``flag_value=False,
2910+
default=True`` would silently always return ``False``, regardless of
2911+
whether the flag was passed or not.
2912+
2913+
.. versionchanged:: 8.3
2914+
``default=True`` is no longer substituted with ``flag_value`` for
2915+
boolean flags, fixing negative boolean flags like ``flag_value=False,
2916+
default=True``. :issue:`3111`
2917+
"""
28942918
value = super().get_default(ctx, call=False)
28952919

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:
2920+
if value is True and self.is_flag and not self.is_bool_flag:
29012921
value = self.flag_value
29022922
elif call and callable(value):
29032923
value = value()

0 commit comments

Comments
 (0)