Repository: pallets/click

Issue:
Consider not showing the default value of boolean flags without a secondary option (False)
Unless I'm missing something, the default value of such options should be obvious: `False`. As a consequence, `[default: False]` feels like superfluous noise. This is certainly true for the `--help` option, which should never show a default.



Discussion:

Resolving patch:
diff --git a/src/click/core.py b/src/click/core.py
--- a/src/click/core.py
+++ b/src/click/core.py
@@ -2416,25 +2416,26 @@ class Option(Parameter):
 
     All other parameters are passed onwards to the parameter constructor.
 
-    :param show_default: controls if the default value should be shown on the
-                         help page. Normally, defaults are not shown. If this
-                         value is a string, it shows the string instead of the
-                         value. This is particularly useful for dynamic options.
-    :param show_envvar: controls if an environment variable should be shown on
-                        the help page.  Normally, environment variables
-                        are not shown.
-    :param prompt: if set to `True` or a non empty string then the user will be
-                   prompted for input.  If set to `True` the prompt will be the
-                   option name capitalized.
+    :param show_default: Controls if the default value should be shown
+        on the help page. Normally, defaults are not shown. If this
+        value is a string, it shows that string in parentheses instead
+        of the actual value. This is particularly useful for dynamic
+        options. For single option boolean flags, the default remains
+        hidden if its value is ``False``.
+    :param show_envvar: Controls if an environment variable should be
+        shown on the help page. Normally, environment ariables are not
+        shown.
+    :param prompt: If set to ``True`` or a non empty string then the
+        user will be prompted for input. If set to ``True`` the prompt
+        will be the option name capitalized.
     :param confirmation_prompt: Prompt a second time to confirm the
         value if it was prompted for. Can be set to a string instead of
         ``True`` to customize the message.
     :param prompt_required: If set to ``False``, the user will be
         prompted for input only when the option was specified as a flag
         without a value.
-    :param hide_input: if this is `True` then the input on the prompt will be
-                       hidden from the user.  This is useful for password
-                       input.
+    :param hide_input: If this is ``True`` then the input on the prompt
+        will be hidden from the user. This is useful for password input.
     :param is_flag: forces this option to act as a flag.  The default is
                     auto detection.
     :param flag_value: which value should be used for this flag if it's
@@ -2452,6 +2453,10 @@ class Option(Parameter):
     :param help: the help string.
     :param hidden: hide this option from help outputs.
 
+    .. versionchanged:: 8.1.0
+        The default of a single option boolean flag is not shown if the
+        default value is ``False``.
+
     .. versionchanged:: 8.0.1
         ``type`` is detected from ``flag_value`` if given.
     """
@@ -2745,6 +2750,8 @@ def _write_opts(opts: t.Sequence[str]) -> str:
                 default_string = split_opt(
                     (self.opts if self.default else self.secondary_opts)[0]
                 )[1]
+            elif self.is_bool_flag and not self.secondary_opts and not default_value:
+                default_string = ""
             else:
                 default_string = str(default_value)
 


Test patch:
diff --git a/tests/test_formatting.py b/tests/test_formatting.py
--- a/tests/test_formatting.py
+++ b/tests/test_formatting.py
@@ -322,12 +322,13 @@ def cli():
         pass
 
     result = runner.invoke(cli, ["--help"])
+    # the default to "--help" is not shown because it is False
     assert result.output.splitlines() == [
         "Usage: cli [OPTIONS]",
         "",
         "Options:",
         "  -f TEXT  Output file name  [default: out.txt]",
-        "  --help   Show this message and exit.  [default: False]",
+        "  --help   Show this message and exit.",
     ]
 
 
diff --git a/tests/test_options.py b/tests/test_options.py
--- a/tests/test_options.py
+++ b/tests/test_options.py
@@ -700,16 +700,37 @@ def test_show_default_boolean_flag_name(runner, default, expect):
     assert f"[default: {expect}]" in message
 
 
-def test_show_default_boolean_flag_value(runner):
-    """When a boolean flag only has one opt, it will show the default
-    value, not the opt name.
+def test_show_true_default_boolean_flag_value(runner):
+    """When a boolean flag only has one opt and its default is True,
+    it will show the default value, not the opt name.
     """
     opt = click.Option(
-        ("--cache",), is_flag=True, show_default=True, help="Enable the cache."
+        ("--cache",),
+        is_flag=True,
+        show_default=True,
+        default=True,
+        help="Enable the cache.",
+    )
+    ctx = click.Context(click.Command("test"))
+    message = opt.get_help_record(ctx)[1]
+    assert "[default: True]" in message
+
+
+@pytest.mark.parametrize("default", [False, None])
+def test_hide_false_default_boolean_flag_value(runner, default):
+    """When a boolean flag only has one opt and its default is False or
+    None, it will not show the default
+    """
+    opt = click.Option(
+        ("--cache",),
+        is_flag=True,
+        show_default=True,
+        default=default,
+        help="Enable the cache.",
     )
     ctx = click.Context(click.Command("test"))
     message = opt.get_help_record(ctx)[1]
-    assert "[default: False]" in message
+    assert "[default: " not in message
 
 
 def test_show_default_string(runner):