Pycord-Development / pycord

Pycord is a modern, easy to use, feature-rich, and async ready API wrapper for Discord written in Python
https://docs.pycord.dev
MIT License
2.74k stars 462 forks source link

Autocomplete callbacks can't be methods of classes #392

Closed Luc1412 closed 2 years ago

Luc1412 commented 3 years ago

Summary

If the automcomplete

Reproduction Steps

  1. Create a Cog
  2. Implement a command with an autocomplete option
  3. Implement the callback into the cog or any other class

Minimal Reproducible Code

class Example(commands.Cog):
    async def _example_autocomplete(self, ctx: AutocompleteContext):
        return []

    example_option = discord.Option(str, autocomplete=_player_name_autocomplete)

Expected Results

The class reference should be filled like in command callbacks.

Actual Results

Exception in event: on_interaction

Traceback (most recent call last):
  File "C:\Users\USER\PycharmProjects\EasyFnStatsV3\venv\lib\site-packages\discord\client.py", line 352, in _run_event
    await coro(*args, **kwargs)
  File "C:\Users\USER\PycharmProjects\EasyFnStatsV3\bot.py", line 273, in on_interaction
    return await command.invoke_autocomplete_callback(interaction)
  File "C:\Users\USER\PycharmProjects\EasyFnStatsV3\venv\lib\site-packages\discord\commands\commands.py", line 760, in invoke_autocomplete_callback
    await command.invoke_autocomplete_callback(interaction)
  File "C:\Users\USER\PycharmProjects\EasyFnStatsV3\venv\lib\site-packages\discord\commands\commands.py", line 506, in invoke_autocomplete_callback
    result = await option.autocomplete(ctx)
TypeError: _player_name_autocomplete() missing 1 required positional argument: 'ctx'

Intents

guilds, members, emojis, webhooks, voice_states, guild_messages, guild_reactions, dm_messages, dm_reactions

System Information

Checklist

Additional Context

As an alternative, you can put the callback outside of a cog. This would cause that you can't access the bot, cog, or any other useful reference.

izxxr commented 3 years ago

I can reproduce this.

Luc1412 commented 3 years ago

A possible fix would be adding self.callback.__self__ as first parameter if the function is in a class at https://github.com/Pycord-Development/pycord/blob/master/discord/commands/commands.py#L541

rmenai commented 3 years ago

I'm not sure if this is related but whenever I try to use an autocomplete I get this error

TypeError: Autocomplete callback must be a coroutine.

Here is my code

@staticmethod
async def num_picker(ctx: ApplicationContext) -> Iterable[int]:
    """Return a list of random integers."""
    return [random.randint(1, 100) for _ in range(25)]

@slash_command(guild_ids=settings.dev_guild_ids)
async def num(
        self, ctx: ApplicationContext,
        extension: Option(int, autocomplete=num_picker)
 -> None:
    await ctx.respond(extension)
Dorukyum commented 3 years ago

I'm not sure if this is related but whenever I try to use an autocomplete I get this error


TypeError: Autocomplete callback must be a coroutine.

Here is my code


@staticmethod

async def num_picker(ctx: ApplicationContext) -> Iterable[int]:

    """Return a list of random integers."""

    return [random.randint(1, 100) for _ in range(25)]

@slash_command(guild_ids=settings.dev_guild_ids)

async def num(

        self, ctx: ApplicationContext,

        extension: Option(int, autocomplete=num_picker)

 -> None:

    await ctx.respond(extension)

You used a staticmethod, which should run like a normal function. Also we're thinking about making autocomplete accept sync functions.

CodeWithSwastik commented 2 years ago

This has been fixed, let me know if there are any issues.