interactions-py / interactions.py

A highly extensible, easy to use, and feature complete bot framework for Discord
https://interactions-py.github.io/interactions.py/
MIT License
838 stars 184 forks source link

[BUG] SelectDefaultValues.from_object needs client positional argument #1653

Closed retr0-init closed 6 months ago

retr0-init commented 7 months ago

Library Version

5.11.0

Describe the Bug

When I try to create the SelectDefaultValues with the class method from_object, the init function missing a positional argument client, which needs to be passed in.

Steps to Reproduce

  1. Use the following code:
    interactions.models.discord.components.SelectDefaultValues.from_object(ctx.author)
  2. It will raise the error immediately

Expected Results

It will raise an error to indicate that client positional argument is missing.

Minimal Reproducible Code

import interactions
bot = interactions.Client(intents=Intents.DEFAULT)
@interactions.slash_command(
    name="test",
    description="test"
)
async def test_cmd(ctx: interactions.SlashContext):
    component = interactions.UserSelectMenu(max_values=3, default_values=[interactions.models.discord.components.SelectDefaultValues.from_object(ctx.author)])
    # Or the following code is the same as above
    # component = interactions.UserSelectMenu(max_values=3, default_values=[ctx.author])
    await ctx.send("Test", components=[component])

bot.start("TOKEN")

Traceback

Traceback (most recent call last):
  File "/venv/lib/python3.11/site-packages/interactions/client/client.py", line 1900, in __dispatch_interaction
    response = await callback
               ^^^^^^^^^^^^^^
  File "/venv/lib/python3.11/site-packages/interactions/client/client.py", line 1771, in _run_slash_command
    return await command(ctx, **ctx.kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/venv/lib/python3.11/site-packages/interactions/models/internal/command.py", line 132, in __call__
    await self.call_callback(self.callback, context)
  File "/venv/lib/python3.11/site-packages/interactions/models/internal/application_commands.py", line 833, in call_callback
    return await self.call_with_binding(callback, ctx, *new_args, **new_kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/venv/lib/python3.11/site-packages/interactions/models/internal/callback.py", line 43, in call_with_binding
    return await callback(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/extensions/template.py", line 22, in test_cmd
    )

  File "/venv/lib/python3.11/site-packages/interactions/models/discord/components.py", line 351, in from_object
    return cls(id=obj.id, type="user")
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: SelectDefaultValues.__init__() missing 1 required positional argument: 'client'

Checklist

Additional Information

I did a very simple hack in the library but it has a very limited usage:

@attrs.define(eq=False, order=False, hash=False, slots=False)
class SelectDefaultValues(DiscordObject):
    id: Snowflake
    """ID of a user, role, or channel"""
    type: str
    """Type of value that id represents. Either "user", "role", or "channel"""

    @classmethod
    def from_object(cls, obj: DiscordObject, client) -> "SelectDefaultValues":
        """Create a default value from a discord object."""
        match obj:
            case d_models.User():
                return cls(client=client, id=obj.id, type="user")
            case d_models.Member():
                return cls(client=client, id=obj.id, type="user")
            case d_models.BaseChannel():
                return cls(client=client, id=obj.id, type="channel")
            case d_models.Role():
                return cls(client=client, id=obj.id, type="role")
            case _:
                raise TypeError(
                    f"Cannot convert {obj} of type {type(obj)} to a SelectDefaultValues - Expected User, Channel, Member, or Role"
                )

Then I can use it as:

import interactions
bot = interactions.Client(intents=Intents.DEFAULT)
@interactions.slash_command(
    name="test",
    description="test"
)
async def test_cmd(ctx: interactions.SlashContext):
    component = interactions.UserSelectMenu(max_values=3, default_values=[interactions.models.discord.components.SelectDefaultValues.from_object(ctx.author, client)])

bot.start("TOKEN")