From 8f4a92b548f02cf8eca041b12b16fac188e4b219 Mon Sep 17 00:00:00 2001 From: Stephen Rosen Date: Fri, 7 Jul 2023 09:19:42 -0500 Subject: [PATCH] Fix decorator typing with _Decorator type alias `_Decorator[FC]` is identical to `t.Callable[[FC], FC]`. However, `mypy` currently reads the first type incorrectly and supports the second one fully. This fix will make mypy checking work correctly on click decorators, and should have no negative impact on other type checkers because the types are effectively "the same". --- CHANGES.rst | 7 +++++++ src/click/decorators.py | 13 ++++++------- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index ce98025a67..98b7d482ea 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,5 +1,12 @@ .. currentmodule:: click +Version 8.1.5 +------------- + +Unreleased + +- Fix type annotations on the option and argument decorators. :issue:`2558` + Version 8.1.4 ------------- diff --git a/src/click/decorators.py b/src/click/decorators.py index 797449d630..88a197e3f3 100644 --- a/src/click/decorators.py +++ b/src/click/decorators.py @@ -21,7 +21,6 @@ R = t.TypeVar("R") T = t.TypeVar("T") _AnyCallable = t.Callable[..., t.Any] -_Decorator: "te.TypeAlias" = t.Callable[[T], T] FC = t.TypeVar("FC", bound=t.Union[_AnyCallable, Command]) @@ -331,7 +330,7 @@ def _param_memo(f: t.Callable[..., t.Any], param: Parameter) -> None: def argument( *param_decls: str, cls: t.Optional[t.Type[Argument]] = None, **attrs: t.Any -) -> _Decorator[FC]: +) -> t.Callable[[FC], FC]: """Attaches an argument to the command. All positional arguments are passed as parameter declarations to :class:`Argument`; all keyword arguments are forwarded unchanged (except ``cls``). @@ -359,7 +358,7 @@ def decorator(f: FC) -> FC: def option( *param_decls: str, cls: t.Optional[t.Type[Option]] = None, **attrs: t.Any -) -> _Decorator[FC]: +) -> t.Callable[[FC], FC]: """Attaches an option to the command. All positional arguments are passed as parameter declarations to :class:`Option`; all keyword arguments are forwarded unchanged (except ``cls``). @@ -385,7 +384,7 @@ def decorator(f: FC) -> FC: return decorator -def confirmation_option(*param_decls: str, **kwargs: t.Any) -> _Decorator[FC]: +def confirmation_option(*param_decls: str, **kwargs: t.Any) -> t.Callable[[FC], FC]: """Add a ``--yes`` option which shows a prompt before continuing if not passed. If the prompt is declined, the program will exit. @@ -409,7 +408,7 @@ def callback(ctx: Context, param: Parameter, value: bool) -> None: return option(*param_decls, **kwargs) -def password_option(*param_decls: str, **kwargs: t.Any) -> _Decorator[FC]: +def password_option(*param_decls: str, **kwargs: t.Any) -> t.Callable[[FC], FC]: """Add a ``--password`` option which prompts for a password, hiding input and asking to enter the value again for confirmation. @@ -433,7 +432,7 @@ def version_option( prog_name: t.Optional[str] = None, message: t.Optional[str] = None, **kwargs: t.Any, -) -> _Decorator[FC]: +) -> t.Callable[[FC], FC]: """Add a ``--version`` option which immediately prints the version number and exits the program. @@ -539,7 +538,7 @@ def callback(ctx: Context, param: Parameter, value: bool) -> None: return option(*param_decls, **kwargs) -def help_option(*param_decls: str, **kwargs: t.Any) -> _Decorator[FC]: +def help_option(*param_decls: str, **kwargs: t.Any) -> t.Callable[[FC], FC]: """Add a ``--help`` option which immediately prints the help page and exits the program.