Repository: pallets/click

Issue:
`@option` processing help argument despite docstring saying that it forwards arguments unchanged
https://github.com/pallets/click/blob/8b48450d5d63c747600e069d4c3e2274f41c8360/src/click/decorators.py#L244-L245

This code should be moved into `Option` or the docstring should be updated.


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
@@ -1133,13 +1133,6 @@ class Command(BaseCommand):
     Click.  A basic command handles command line parsing and might dispatch
     more parsing to commands nested below it.
 
-    .. versionchanged:: 2.0
-       Added the `context_settings` parameter.
-    .. versionchanged:: 8.0
-       Added repr showing the command name
-    .. versionchanged:: 7.1
-       Added the `no_args_is_help` parameter.
-
     :param name: the name of the command to use unless a group overrides it.
     :param context_settings: an optional dictionary with defaults that are
                              passed to the context object.
@@ -1161,6 +1154,20 @@ class Command(BaseCommand):
 
     :param deprecated: issues a message indicating that
                              the command is deprecated.
+
+    .. versionchanged:: 8.1
+        Indentation in ``help`` is cleaned here instead of only in the
+        ``@command`` decorator. ``epilog`` and ``short_help`` are also
+        cleaned.
+
+    .. versionchanged:: 8.0
+        Added a ``repr`` showing the command name.
+
+    .. versionchanged:: 7.1
+        Added the ``no_args_is_help`` parameter.
+
+    .. versionchanged:: 2.0
+        Added the ``context_settings`` parameter.
     """
 
     def __init__(
@@ -1187,10 +1194,20 @@ def __init__(
         #: will automatically be handled before non eager ones.
         self.params: t.List["Parameter"] = params or []
 
-        # if a form feed (page break) is found in the help text, truncate help
-        # text to the content preceding the first form feed
-        if help and "\f" in help:
-            help = help.split("\f", 1)[0]
+        if help:
+            help = inspect.cleandoc(help)
+
+            # Discard help text after a first form feed (page break)
+            # character, to allow writing longer documentation in
+            # docstrings that does not show in help output.
+            if "\f" in help:
+                help = help.partition("\f")[0]
+
+        if epilog:
+            epilog = inspect.cleandoc(epilog)
+
+        if short_help:
+            short_help = inspect.cleandoc(short_help)
 
         self.help = help
         self.epilog = epilog
@@ -2415,6 +2432,10 @@ class Option(Parameter):
     :param help: the help string.
     :param hidden: hide this option from help outputs.
 
+    .. versionchanged:: 8.1.0
+        Help text indentation is cleaned here instead of only in the
+        ``@option`` decorator.
+
     .. versionchanged:: 8.1.0
         The ``show_default`` parameter overrides
         ``Context.show_default``.
@@ -2449,6 +2470,9 @@ def __init__(
         show_envvar: bool = False,
         **attrs: t.Any,
     ) -> None:
+        if help:
+            help = inspect.cleandoc(help)
+
         default_is_missing = "default" not in attrs
         super().__init__(param_decls, type=type, multiple=multiple, **attrs)
 
diff --git a/src/click/decorators.py b/src/click/decorators.py
--- a/src/click/decorators.py
+++ b/src/click/decorators.py
@@ -137,14 +137,9 @@ def _make_command(
     except AttributeError:
         params = []
 
-    help = attrs.get("help")
+    if attrs.get("help") is None:
+        attrs["help"] = inspect.getdoc(f)
 
-    if help is None:
-        help = inspect.getdoc(f)
-    else:
-        help = inspect.cleandoc(help)
-
-    attrs["help"] = help
     return cls(
         name=name or f.__name__.lower().replace("_", "-"),
         callback=f,
@@ -297,9 +292,6 @@ def option(*param_decls: str, **attrs: t.Any) -> t.Callable[[FC], FC]:
     def decorator(f: FC) -> FC:
         # Issue 926, copy attrs, so pre-defined options can re-use the same cls=
         option_attrs = attrs.copy()
-
-        if option_attrs.get("help"):
-            option_attrs["help"] = inspect.cleandoc(option_attrs["help"])
         OptionClass = option_attrs.pop("cls", None) or Option
         _param_memo(f, OptionClass(param_decls, **option_attrs))
         return f


Test patch: