Browse Source

Add autocomplete method to Transformers

Co-authored-by: Danny <[email protected]>
pull/7836/head
Josh 3 years ago
committed by GitHub
parent
commit
151948a09a
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 19
      discord/app_commands/commands.py
  2. 36
      discord/app_commands/transformers.py

19
discord/app_commands/commands.py

@ -167,12 +167,20 @@ def validate_context_menu_name(name: str) -> str:
def _validate_auto_complete_callback(
callback: AutocompleteCallback[GroupT, ChoiceT]
callback: AutocompleteCallback[GroupT, ChoiceT],
skip_binding: bool = False,
) -> AutocompleteCallback[GroupT, ChoiceT]:
requires_binding = is_inside_class(callback)
required_parameters = 2 + requires_binding
binding = getattr(callback, '__self__', None)
if binding is not None:
callback = callback.__func__
requires_binding = (binding is None and is_inside_class(callback)) or skip_binding
callback.requires_binding = requires_binding
callback.binding = binding
required_parameters = 2 + requires_binding
params = inspect.signature(callback).parameters
if len(params) != required_parameters:
raise TypeError('autocomplete callback requires either 2 or 3 parameters to be passed')
@ -581,8 +589,9 @@ class Command(Generic[GroupT, P, T]):
raise CommandSignatureMismatch(self)
if param.autocomplete.requires_binding:
if self.binding is not None:
choices = await param.autocomplete(self.binding, interaction, value)
binding = param.autocomplete.binding or self.binding
if binding is not None:
choices = await param.autocomplete(binding, interaction, value)
else:
raise TypeError('autocomplete parameter expected a bound self parameter but one was not provided')
else:

36
discord/app_commands/transformers.py

@ -61,6 +61,8 @@ __all__ = (
)
T = TypeVar('T')
FuncT = TypeVar('FuncT', bound=Callable[..., Any])
ChoiceT = TypeVar('ChoiceT', str, int, float, Union[str, int, float])
NoneType = type(None)
if TYPE_CHECKING:
@ -249,6 +251,35 @@ class Transformer:
"""
raise NotImplementedError('Derived classes need to implement this.')
@classmethod
async def autocomplete(
cls, interaction: Interaction, value: Union[int, float, str]
) -> List[Choice[Union[int, float, str]]]:
"""|coro|
An autocomplete prompt handler to be automatically used by options using this transformer.
.. note::
Autocomplete is only supported for options with a :meth:`~discord.app_commands.Transformer.type`
of :attr:`~discord.AppCommandOptionType.string`, :attr:`~discord.AppCommandOptionType.integer`,
or :attr:`~discord.AppCommandOptionType.number`.
Parameters
-----------
interaction: :class:`~discord.Interaction`
The autocomplete interaction being handled.
value: Union[:class:`str`, :class:`int`, :class:`float`]
The current value entered by the user.
Returns
--------
List[:class:`~discord.app_commands.Choice`]
A list of choices to be displayed to the user, a maximum of 25.
"""
raise NotImplementedError('Derived classes can implement this.')
class _TransformMetadata:
__discord_app_commands_transform__: ClassVar[bool] = True
@ -679,4 +710,9 @@ def annotation_to_parameter(annotation: Any, parameter: inspect.Parameter) -> Co
if parameter.kind in (parameter.POSITIONAL_ONLY, parameter.VAR_KEYWORD, parameter.VAR_POSITIONAL):
raise TypeError(f'unsupported parameter kind in callback: {parameter.kind!s}')
if inner.autocomplete is not Transformer.autocomplete:
from .commands import _validate_auto_complete_callback
result.autocomplete = _validate_auto_complete_callback(inner.autocomplete, skip_binding=True)
return result

Loading…
Cancel
Save