Skip to content

Commit

Permalink
Deduplicate --help option definition (pallets#2563)
Browse files Browse the repository at this point in the history
Co-authored-by: Andreas Backx <[email protected]>
  • Loading branch information
kdeldycke and AndreasBackx authored Nov 2, 2024
1 parent 9aeb586 commit 26aa7bf
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 35 deletions.
1 change: 1 addition & 0 deletions src/click/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
from .decorators import confirmation_option as confirmation_option
from .decorators import group as group
from .decorators import help_option as help_option
from .decorators import HelpOption as HelpOption
from .decorators import make_pass_decorator as make_pass_decorator
from .decorators import option as option
from .decorators import pass_context as pass_context
Expand Down
22 changes: 8 additions & 14 deletions src/click/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -1285,25 +1285,19 @@ def get_help_option_names(self, ctx: Context) -> t.List[str]:
return list(all_names)

def get_help_option(self, ctx: Context) -> t.Optional["Option"]:
"""Returns the help option object."""
"""Returns the help option object.
Unless ``add_help_option`` is ``False``.
"""
help_options = self.get_help_option_names(ctx)

if not help_options or not self.add_help_option:
return None

def show_help(ctx: Context, param: "Parameter", value: str) -> None:
if value and not ctx.resilient_parsing:
echo(ctx.get_help(), color=ctx.color)
ctx.exit()

return Option(
help_options,
is_flag=True,
is_eager=True,
expose_value=False,
callback=show_help,
help=_("Show this message and exit."),
)
# Avoid circular import.
from .decorators import HelpOption

return HelpOption(help_options)

def make_parser(self, ctx: Context) -> OptionParser:
"""Creates the underlying option parser for this command."""
Expand Down
51 changes: 30 additions & 21 deletions src/click/decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -522,32 +522,41 @@ def callback(ctx: Context, param: Parameter, value: bool) -> None:
return option(*param_decls, **kwargs)


def help_option(*param_decls: str, **kwargs: t.Any) -> t.Callable[[FC], FC]:
"""Add a ``--help`` option which immediately prints the help page
class HelpOption(Option):
"""Pre-configured ``--help`` option which immediately prints the help page
and exits the program.
"""

This is usually unnecessary, as the ``--help`` option is added to
each command automatically unless ``add_help_option=False`` is
passed.
def __init__(
self,
param_decls: t.Optional[t.Sequence[str]] = None,
**kwargs: t.Any,
) -> None:
if not param_decls:
param_decls = ("--help",)

:param param_decls: One or more option names. Defaults to the single
value ``"--help"``.
:param kwargs: Extra arguments are passed to :func:`option`.
"""
kwargs.setdefault("is_flag", True)
kwargs.setdefault("expose_value", False)
kwargs.setdefault("is_eager", True)
kwargs.setdefault("help", _("Show this message and exit."))
kwargs.setdefault("callback", self.show_help)

def callback(ctx: Context, param: Parameter, value: bool) -> None:
if not value or ctx.resilient_parsing:
return
super().__init__(param_decls, **kwargs)

echo(ctx.get_help(), color=ctx.color)
ctx.exit()
@staticmethod
def show_help(ctx: Context, param: Parameter, value: bool) -> None:
"""Callback that print the help page on ``<stdout>`` and exits."""
if value and not ctx.resilient_parsing:
echo(ctx.get_help(), color=ctx.color)
ctx.exit()

if not param_decls:
param_decls = ("--help",)

kwargs.setdefault("is_flag", True)
kwargs.setdefault("expose_value", False)
kwargs.setdefault("is_eager", True)
kwargs.setdefault("help", _("Show this message and exit."))
kwargs["callback"] = callback
def help_option(*param_decls: str, **kwargs: t.Any) -> t.Callable[[FC], FC]:
"""Decorator for the pre-configured ``--help`` option defined above.
:param param_decls: One or more option names. Defaults to the single
value ``"--help"``.
:param kwargs: Extra arguments are passed to :func:`option`.
"""
kwargs.setdefault("cls", HelpOption)
return option(*param_decls, **kwargs)

0 comments on commit 26aa7bf

Please sign in to comment.