From 8473b3ced140296b9dd869957e0026eebd94634b Mon Sep 17 00:00:00 2001 From: Kyle Altendorf Date: Mon, 8 May 2023 11:03:33 -0400 Subject: [PATCH] Use t.Mapping not t.Dict for parameters (#2265) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Sagi Buchbinder Shadur --- CHANGES.rst | 2 ++ src/click/core.py | 18 ++++++++++-------- src/click/shell_completion.py | 9 ++++++--- 3 files changed, 18 insertions(+), 11 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 7b1e5b3c3..2d560885d 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -5,6 +5,8 @@ Version 8.1.4 Unreleased +- Replace all ``typing.Dict`` occurrences to ``typing.MutableMapping`` for + parameter hints. :issue:`2255` - Improve type hinting for decorators and give all generic types parameters. :issue:`2398` - Fix return value and type signature of `shell_completion.add_completion_class` function. :pr:`2421` diff --git a/src/click/core.py b/src/click/core.py index e2412bb3f..fd391b5f4 100644 --- a/src/click/core.py +++ b/src/click/core.py @@ -264,7 +264,7 @@ def __init__( info_name: t.Optional[str] = None, obj: t.Optional[t.Any] = None, auto_envvar_prefix: t.Optional[str] = None, - default_map: t.Optional[t.Dict[str, t.Any]] = None, + default_map: t.Optional[t.MutableMapping[str, t.Any]] = None, terminal_width: t.Optional[int] = None, max_content_width: t.Optional[int] = None, resilient_parsing: bool = False, @@ -311,7 +311,7 @@ def __init__( ): default_map = parent.default_map.get(info_name) - self.default_map: t.Optional[t.Dict[str, t.Any]] = default_map + self.default_map: t.Optional[t.MutableMapping[str, t.Any]] = default_map #: This flag indicates if a subcommand is going to be executed. A #: group callback can use this information to figure out if it's @@ -862,7 +862,7 @@ class BaseCommand: def __init__( self, name: t.Optional[str], - context_settings: t.Optional[t.Dict[str, t.Any]] = None, + context_settings: t.Optional[t.MutableMapping[str, t.Any]] = None, ) -> None: #: the name the command thinks it has. Upon registering a command #: on a :class:`Group` the group will default the command name @@ -874,7 +874,7 @@ def __init__( context_settings = {} #: an optional dictionary with defaults passed to the context. - self.context_settings: t.Dict[str, t.Any] = context_settings + self.context_settings: t.MutableMapping[str, t.Any] = context_settings def to_info_dict(self, ctx: Context) -> t.Dict[str, t.Any]: """Gather information that could be useful for a tool generating @@ -1117,7 +1117,7 @@ def main( def _main_shell_completion( self, - ctx_args: t.Dict[str, t.Any], + ctx_args: t.MutableMapping[str, t.Any], prog_name: str, complete_var: t.Optional[str] = None, ) -> None: @@ -1193,7 +1193,7 @@ class Command(BaseCommand): def __init__( self, name: t.Optional[str], - context_settings: t.Optional[t.Dict[str, t.Any]] = None, + context_settings: t.Optional[t.MutableMapping[str, t.Any]] = None, callback: t.Optional[t.Callable[..., t.Any]] = None, params: t.Optional[t.List["Parameter"]] = None, help: t.Optional[str] = None, @@ -1804,7 +1804,9 @@ class Group(MultiCommand): def __init__( self, name: t.Optional[str] = None, - commands: t.Optional[t.Union[t.Dict[str, Command], t.Sequence[Command]]] = None, + commands: t.Optional[ + t.Union[t.MutableMapping[str, Command], t.Sequence[Command]] + ] = None, **attrs: t.Any, ) -> None: super().__init__(name, **attrs) @@ -1815,7 +1817,7 @@ def __init__( commands = {c.name: c for c in commands if c.name is not None} #: The registered subcommands by their exported names. - self.commands: t.Dict[str, Command] = commands + self.commands: t.MutableMapping[str, Command] = commands def add_command(self, cmd: Command, name: t.Optional[str] = None) -> None: """Registers another :class:`Command` with this group. If the name diff --git a/src/click/shell_completion.py b/src/click/shell_completion.py index 3b3a1dfe8..f93256e70 100644 --- a/src/click/shell_completion.py +++ b/src/click/shell_completion.py @@ -16,7 +16,7 @@ def shell_complete( cli: BaseCommand, - ctx_args: t.Dict[str, t.Any], + ctx_args: t.MutableMapping[str, t.Any], prog_name: str, complete_var: str, instruction: str, @@ -214,7 +214,7 @@ class ShellComplete: def __init__( self, cli: BaseCommand, - ctx_args: t.Dict[str, t.Any], + ctx_args: t.MutableMapping[str, t.Any], prog_name: str, complete_var: str, ) -> None: @@ -487,7 +487,10 @@ def _is_incomplete_option(ctx: Context, args: t.List[str], param: Parameter) -> def _resolve_context( - cli: BaseCommand, ctx_args: t.Dict[str, t.Any], prog_name: str, args: t.List[str] + cli: BaseCommand, + ctx_args: t.MutableMapping[str, t.Any], + prog_name: str, + args: t.List[str], ) -> Context: """Produce the context hierarchy starting with the command and traversing the complete arguments. This only follows the commands,