From c735682ac6814a5c6d69e681c8c3d47c7d9e26f2 Mon Sep 17 00:00:00 2001 From: Rapptz Date: Wed, 3 Aug 2022 19:02:36 -0400 Subject: [PATCH] Fix autocomplete bindings not working for transformer instances --- discord/app_commands/commands.py | 25 +++++++++++++------------ discord/app_commands/transformers.py | 2 +- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/discord/app_commands/commands.py b/discord/app_commands/commands.py index 054969964..cc0af720d 100644 --- a/discord/app_commands/commands.py +++ b/discord/app_commands/commands.py @@ -226,21 +226,22 @@ def validate_context_menu_name(name: str) -> str: def _validate_auto_complete_callback( - callback: AutocompleteCallback[GroupT, ChoiceT], - skip_binding: bool = False, + callback: AutocompleteCallback[GroupT, ChoiceT] ) -> AutocompleteCallback[GroupT, ChoiceT]: + # This function needs to ensure the following is true: + # If self.foo is passed then don't pass command.binding to the callback + # If Class.foo is passed then it is assumed command.binding has to be passed + # If free_function_foo is passed then no binding should be passed at all + # Passing command.binding is mandated by pass_command_binding binding = getattr(callback, '__self__', None) - if binding is not None: - callback = callback.__func__ - requires_binding = True - else: - requires_binding = is_inside_class(callback) or skip_binding + pass_command_binding = binding is None and is_inside_class(callback) - callback.requires_binding = requires_binding - callback.binding = binding + # 'method' objects can't have dynamic attributes + if binding is None: + callback.pass_command_binding = pass_command_binding - required_parameters = 2 + requires_binding + required_parameters = 2 + pass_command_binding params = inspect.signature(callback).parameters if len(params) != required_parameters: raise TypeError(f'autocomplete callback {callback.__qualname__!r} requires either 2 or 3 parameters to be passed') @@ -714,8 +715,8 @@ class Command(Generic[GroupT, P, T]): await interaction.response.autocomplete([]) return - if param.autocomplete.requires_binding: - binding = param.autocomplete.binding or self.binding + if getattr(param.autocomplete, 'pass_command_binding', False): + binding = self.binding if binding is not None: choices = await param.autocomplete(binding, interaction, value) else: diff --git a/discord/app_commands/transformers.py b/discord/app_commands/transformers.py index bbf426b28..994714dae 100644 --- a/discord/app_commands/transformers.py +++ b/discord/app_commands/transformers.py @@ -810,6 +810,6 @@ def annotation_to_parameter(annotation: Any, parameter: inspect.Parameter) -> Co if inner.autocomplete.__func__ is not Transformer.autocomplete: from .commands import _validate_auto_complete_callback - result.autocomplete = _validate_auto_complete_callback(inner.autocomplete, skip_binding=True) + result.autocomplete = _validate_auto_complete_callback(inner.autocomplete) return result