Repository: pallets/click (Python)

Issue:
show_default in group's context_settings not propagated to subcommands
### Expected Behavior

#1018 and #1225 seems to have fixed supporting a global `show_default` option via context settings, but in Click 7.1.2, it doesn't cover my use case yet.

I thought the following should work with 7.1+:

```python
import click

@click.group(context_settings={
    'show_default': True,
    'help_option_names': ['-x', '--xhelp'],
})
@click.pass_context
def main(ctx):
    print('==== main ====')
    print(ctx.show_default)
    print(ctx.help_option_names)

@main.command()
@click.option('-v', '--value', type=int, default=123, help='some value')
@click.pass_context
def do(ctx, value):
    print('==== do ====')
    print(ctx.show_default)
    print(ctx.help_option_names)
    print('----')
    print(value)

main()
```

```console
$ python test-click.py -x
Usage: test-click.py [OPTIONS] COMMAND [ARGS]...

Options:
  -x, --xhelp  Show this message and exit.  [default: False]

Commands:
  do

$ python test-click.py do -x
==== main ====
True
['-x', '--xhelp']
Usage: test-click.py do [OPTIONS]

Options:
  -v, --value INTEGER  some value  [default: 123]
  -x, --xhelp          Show this message and exit.

$ python test-click.py do
==== main ====
True
['-x', '--xhelp']
==== do ====
True
['-x', '--xhelp']
----
123
```

### Actual Behavior

But the current implementation seems to loose the value of `show_default` when "going into" subcommands.

```console
$ python test-click.py -x
Usage: test-click.py [OPTIONS] COMMAND [ARGS]...

Options:
  -x, --xhelp  Show this message and exit.  [default: False]

Commands:
  do

$ python test-click.py do -x
==== main ====
True
['-x', '--xhelp']
Usage: test-click.py do [OPTIONS]

Options:
  -v, --value INTEGER  some value
  -x, --xhelp          Show this message and exit.

$ python test-click.py do
==== main ====
True
['-x', '--xhelp']
==== do ====
None
['-x', '--xhelp']
----
123
```

### Environment

* Python version: 3.8.3
* Click version: 7.1.2



Discussion:

Patch:
diff --git a/CHANGES.rst b/CHANGES.rst
index 5a7bde257..8f58527e8 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -75,6 +75,8 @@ Unreleased
     :issue:`1272`
 -   If only a name is passed to ``option()``, Click suggests renaming it
     to ``--name``. :pr:`1355`
+-   A context's ``show_default`` parameter defaults to the value from
+    the parent context. :issue:`1565`
 
 
 Version 7.1.2
diff --git a/src/click/core.py b/src/click/core.py
index e62059e9f..a678bd752 100644
--- a/src/click/core.py
+++ b/src/click/core.py
@@ -173,21 +173,6 @@ class Context:
     A context can be used as context manager in which case it will call
     :meth:`close` on teardown.
 
-    .. versionadded:: 2.0
-       Added the `resilient_parsing`, `help_option_names`,
-       `token_normalize_func` parameters.
-
-    .. versionadded:: 3.0
-       Added the `allow_extra_args` and `allow_interspersed_args`
-       parameters.
-
-    .. versionadded:: 4.0
-       Added the `color`, `ignore_unknown_options`, and
-       `max_content_width` parameters.
-
-    .. versionadded:: 7.1
-       Added the `show_default` parameter.
-
     :param command: the command class for this context.
     :param parent: the parent context.
     :param info_name: the info name for this invocation.  Generally this
@@ -242,9 +227,28 @@ class Context:
                   codes are used in texts that Click prints which is by
                   default not the case.  This for instance would affect
                   help output.
-    :param show_default: if True, shows defaults for all options.
-                    Even if an option is later created with show_default=False,
-                    this command-level setting overrides it.
+    :param show_default: Show defaults for all options. If not set,
+        defaults to the value from a parent context. Overrides an
+        option's ``show_default`` argument.
+
+    .. versionchanged:: 8.0
+        The ``show_default`` parameter defaults to the value from the
+        parent context.
+
+    .. versionchanged:: 7.1
+       Added the ``show_default`` parameter.
+
+    .. versionchanged:: 4.0
+        Added the ``color``, ``ignore_unknown_options``, and
+        ``max_content_width`` parameters.
+
+    .. versionchanged:: 3.0
+        Added the ``allow_extra_args`` and ``allow_interspersed_args``
+        parameters.
+
+    .. versionchanged:: 2.0
+        Added the ``resilient_parsing``, ``help_option_names``, and
+        ``token_normalize_func`` parameters.
     """
 
     #: The formatter class to create with :meth:`make_formatter`.
@@ -398,6 +402,10 @@ def __init__(
         #: Controls if styling output is wanted or not.
         self.color = color
 
+        if show_default is None and parent is not None:
+            show_default = parent.show_default
+
+        #: Show option default values when formatting help text.
         self.show_default = show_default
 
         self._close_callbacks = []


Test patch:
diff --git a/tests/test_context.py b/tests/test_context.py
index c1be8f35f..bfccb85f5 100644
--- a/tests/test_context.py
+++ b/tests/test_context.py
@@ -267,6 +267,20 @@ def test2(ctx, foo):
     assert result.output == "foocmd\n"
 
 
+def test_propagate_show_default_setting(runner):
+    """A context's ``show_default`` setting defaults to the value from
+    the parent context.
+    """
+    group = click.Group(
+        commands={
+            "sub": click.Command("sub", params=[click.Option(["-a"], default="a")]),
+        },
+        context_settings={"show_default": True},
+    )
+    result = runner.invoke(group, ["sub", "--help"])
+    assert "[default: a]" in result.output
+
+
 def test_exit_not_standalone():
     @click.command()
     @click.pass_context