Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ These changes are available on the `master` branch, but have not yet been releas
([#3105](https://github.com/Pycord-Development/pycord/pull/3105))
- Fixed the update of a user's `avatar_decoration` to now cause an `on_user_update`
event to fire. ([#3103](https://github.com/Pycord-Development/pycord/pull/3103))
- Fixed the `slash_command`, `message_command` and `user_command` decorators to
explicitly list the accepted parameters, and have a return type.
([#3119](https://github.com/Pycord-Development/pycord/pull/3119))
Comment thread
Paillat-dev marked this conversation as resolved.
Outdated

### Deprecated

Expand Down
141 changes: 134 additions & 7 deletions discord/bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,11 @@
from .utils import MISSING, async_all, find, get

if TYPE_CHECKING:
from .cog import Cog
from .commands import Option
from .ext.commands import Cooldown
from .member import Member
from .permissions import Permissions

C = TypeVar("C", bound=MessageCommand | SlashCommand | UserCommand)
CoroFunc = Callable[..., Coroutine[Any, Any, Any]]
Expand Down Expand Up @@ -909,7 +913,24 @@ async def callback() -> None:
if not autocomplete_task.done():
autocomplete_task.cancel()

def slash_command(self, **kwargs):
def slash_command(
self,
Comment thread
ToothyDev marked this conversation as resolved.
checks: list[Callable[[ApplicationContext], bool]] | None = MISSING,
cog: Cog | None = MISSING,
contexts: set[InteractionContextType] | None = MISSING,
cooldown: Cooldown | None = MISSING,
default_member_permissions: Permissions | None = MISSING,
description: str | None = MISSING,
description_localizations: dict[str, str] | None = MISSING,
guild_ids: list[int] | None = MISSING,
integration_types: set[IntegrationType] | None = MISSING,
name: str | None = MISSING,
name_localizations: dict[str, str] | None = MISSING,
nsfw: bool = False,
Comment thread
ToothyDev marked this conversation as resolved.
Outdated
options: list[Option] | None = MISSING,
parent: SlashCommandGroup | None = MISSING,
**kwargs: Any,
) -> Callable[[...], SlashCommand]:
Comment thread
ToothyDev marked this conversation as resolved.
Outdated
"""A shortcut decorator for adding a slash command to the bot.
This is equivalent to using :meth:`application_command`, providing
the :class:`SlashCommand` class.
Expand All @@ -922,9 +943,39 @@ def slash_command(self, **kwargs):
A decorator that converts the provided function into a :class:`.SlashCommand`,
adds it to the bot, and returns it.
"""
return self.application_command(cls=SlashCommand, **kwargs)
return self.application_command(
cls=SlashCommand,
checks=checks,
cog=cog,
contexts=contexts,
cooldown=cooldown,
default_member_permissions=default_member_permissions,
description=description,
description_localizations=description_localizations,
guild_ids=guild_ids,
integration_types=integration_types,
name=name,
name_localizations=name_localizations,
nsfw=nsfw,
options=options,
parent=parent,
**kwargs,
)

def user_command(self, **kwargs):
def user_command(
self,
Comment thread
ToothyDev marked this conversation as resolved.
checks: list[Callable[[ApplicationContext], bool]] | None = MISSING,
cog: Cog | None = MISSING,
contexts: set[InteractionContextType] | None = MISSING,
cooldown: Cooldown | None = MISSING,
default_member_permissions: Permissions | None = MISSING,
guild_ids: list[int] | None = MISSING,
integration_types: set[IntegrationType] | None = MISSING,
name: str | None = MISSING,
name_localizations: dict[str, str] | None = MISSING,
nsfw: bool = False,
**kwargs: Any,
) -> Callable[..., UserCommand]:
"""A shortcut decorator for adding a user command to the bot.
This is equivalent to using :meth:`application_command`, providing
the :class:`UserCommand` class.
Expand All @@ -937,9 +988,35 @@ def user_command(self, **kwargs):
A decorator that converts the provided function into a :class:`.UserCommand`,
adds it to the bot, and returns it.
"""
return self.application_command(cls=UserCommand, **kwargs)
return self.application_command(
cls=UserCommand,
checks=checks,
cog=cog,
contexts=contexts,
cooldown=cooldown,
default_member_permissions=default_member_permissions,
guild_ids=guild_ids,
integration_types=integration_types,
name=name,
name_localizations=name_localizations,
nsfw=nsfw,
**kwargs,
)

def message_command(self, **kwargs):
def message_command(
self,
Comment thread
ToothyDev marked this conversation as resolved.
checks: list[Callable[[ApplicationContext], bool]] | None = MISSING,
cog: Cog | None = MISSING,
contexts: set[InteractionContextType] | None = MISSING,
cooldown: Cooldown | None = MISSING,
default_member_permissions: Permissions | None = MISSING,
guild_ids: list[int] | None = MISSING,
integration_types: set[IntegrationType] | None = MISSING,
name: str | None = MISSING,
name_localizations: dict[str, str] | None = MISSING,
nsfw: bool = False,
**kwargs: Any,
) -> Callable[..., MessageCommand]:
"""A shortcut decorator for adding a message command to the bot.
This is equivalent to using :meth:`application_command`, providing
the :class:`MessageCommand` class.
Expand All @@ -952,9 +1029,40 @@ def message_command(self, **kwargs):
A decorator that converts the provided function into a :class:`.MessageCommand`,
adds it to the bot, and returns it.
"""
return self.application_command(cls=MessageCommand, **kwargs)
return self.application_command(
cls=MessageCommand,
checks=checks,
cog=cog,
contexts=contexts,
cooldown=cooldown,
default_member_permissions=default_member_permissions,
guild_ids=guild_ids,
integration_types=integration_types,
name=name,
name_localizations=name_localizations,
nsfw=nsfw,
**kwargs,
)

def application_command(self, cls: type[C] = SlashCommand, **kwargs):
def application_command(
self,
Comment thread
ToothyDev marked this conversation as resolved.
cls: type[C] = SlashCommand,
checks: list[Callable[[ApplicationContext], bool]] | None = MISSING,
cog: Cog | None = MISSING,
contexts: set[InteractionContextType] | None = MISSING,
cooldown: Cooldown | None = MISSING,
default_member_permissions: Permissions | None = MISSING,
description: str | None = MISSING,
description_localizations: dict[str, str] | None = MISSING,
guild_ids: list[int] | None = MISSING,
integration_types: set[IntegrationType] | None = MISSING,
name: str | None = MISSING,
name_localizations: dict[str, str] | None = MISSING,
nsfw: bool = False,
options: list[Option] | None = MISSING,
parent: SlashCommandGroup | None = MISSING,
**kwargs: Any,
) -> Callable[..., C]:
"""A shortcut decorator that converts the provided function into
an application command via :func:`command` and adds it to
the internal command list via :meth:`~.Bot.add_application_command`.
Expand All @@ -976,6 +1084,25 @@ class be provided, it must be a subclass of either
adds it to the bot, and returns it.
"""

params = {
"checks": checks,
"cog": cog,
"contexts": contexts,
"cooldown": cooldown,
"default_member_permissions": default_member_permissions,
"description": description,
"description_localizations": description_localizations,
"guild_ids": guild_ids,
"integration_types": integration_types,
"name": name,
"name_localizations": name_localizations,
"nsfw": nsfw,
"options": options,
"parent": parent,
**kwargs,
}
kwargs = {k: v for k, v in params.items() if v is not MISSING}

def decorator(func) -> C:
result = command(cls=cls, **kwargs)(func)
self.add_application_command(result)
Expand Down
149 changes: 134 additions & 15 deletions discord/commands/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,9 @@
from typing_extensions import Concatenate, ParamSpec

from .. import Permissions
from ..bot import C
from ..cog import Cog
from ..ext.commands.cooldowns import CooldownMapping, MaxConcurrency
from ..ext.commands.cooldowns import Cooldown, CooldownMapping, MaxConcurrency

T = TypeVar("T")
CogT = TypeVar("CogT", bound="Cog")
Expand Down Expand Up @@ -1978,7 +1979,23 @@ def _update_copy(self, kwargs: dict[str, Any]):
return self.copy()


def slash_command(**kwargs):
def slash_command(
Comment thread
ToothyDev marked this conversation as resolved.
checks: list[Callable[[ApplicationContext], bool]] | None = MISSING,
cog: Cog | None = MISSING,
contexts: set[InteractionContextType] | None = MISSING,
cooldown: Cooldown | None = MISSING,
default_member_permissions: Permissions | None = MISSING,
description: str | None = MISSING,
description_localizations: dict[str, str] | None = MISSING,
guild_ids: list[int] | None = MISSING,
integration_types: set[IntegrationType] | None = MISSING,
name: str | None = MISSING,
name_localizations: dict[str, str] | None = MISSING,
nsfw: bool = False,
options: list[Option] | None = MISSING,
parent: SlashCommandGroup | None = MISSING,
**kwargs: Any,
Comment thread
ToothyDev marked this conversation as resolved.
Outdated
) -> Callable[[...], SlashCommand]:
Comment thread
ToothyDev marked this conversation as resolved.
Outdated
"""Decorator for slash commands that invokes :func:`application_command`.

.. versionadded:: 2.0
Expand All @@ -1988,10 +2005,39 @@ def slash_command(**kwargs):
Callable[..., :class:`.SlashCommand`]
A decorator that converts the provided method into a :class:`.SlashCommand`.
"""
return application_command(cls=SlashCommand, **kwargs)


def user_command(**kwargs):
return application_command(
cls=SlashCommand,
checks=checks,
cog=cog,
contexts=contexts,
cooldown=cooldown,
default_member_permissions=default_member_permissions,
description=description,
description_localizations=description_localizations,
guild_ids=guild_ids,
integration_types=integration_types,
name=name,
name_localizations=name_localizations,
nsfw=nsfw,
options=options,
parent=parent,
**kwargs,
)


def user_command(
Comment thread
ToothyDev marked this conversation as resolved.
checks: list[Callable[[ApplicationContext], bool]] | None = MISSING,
cog: Cog | None = MISSING,
contexts: set[InteractionContextType] | None = MISSING,
cooldown: Cooldown | None = MISSING,
default_member_permissions: Permissions | None = MISSING,
guild_ids: list[int] | None = MISSING,
integration_types: set[IntegrationType] | None = MISSING,
name: str | None = MISSING,
name_localizations: dict[str, str] | None = MISSING,
nsfw: bool = False,
**kwargs: Any,
) -> Callable[..., UserCommand]:
"""Decorator for user commands that invokes :func:`application_command`.

.. versionadded:: 2.0
Expand All @@ -2001,10 +2047,35 @@ def user_command(**kwargs):
Callable[..., :class:`.UserCommand`]
A decorator that converts the provided method into a :class:`.UserCommand`.
"""
return application_command(cls=UserCommand, **kwargs)


def message_command(**kwargs):
return application_command(
cls=UserCommand,
checks=checks,
cog=cog,
contexts=contexts,
cooldown=cooldown,
default_member_permissions=default_member_permissions,
guild_ids=guild_ids,
integration_types=integration_types,
name=name,
name_localizations=name_localizations,
nsfw=nsfw,
**kwargs,
)


def message_command(
Comment thread
ToothyDev marked this conversation as resolved.
checks: list[Callable[[ApplicationContext], bool]] | None = MISSING,
cog: Cog | None = MISSING,
contexts: set[InteractionContextType] | None = MISSING,
cooldown: Cooldown | None = MISSING,
default_member_permissions: Permissions | None = MISSING,
guild_ids: list[int] | None = MISSING,
integration_types: set[IntegrationType] | None = MISSING,
name: str | None = MISSING,
name_localizations: dict[str, str] | None = MISSING,
nsfw: bool = False,
**kwargs: Any,
) -> Callable[..., MessageCommand]:
"""Decorator for message commands that invokes :func:`application_command`.

.. versionadded:: 2.0
Expand All @@ -2014,10 +2085,40 @@ def message_command(**kwargs):
Callable[..., :class:`.MessageCommand`]
A decorator that converts the provided method into a :class:`.MessageCommand`.
"""
return application_command(cls=MessageCommand, **kwargs)


def application_command(cls=SlashCommand, **attrs):
return application_command(
cls=MessageCommand,
checks=checks,
cog=cog,
contexts=contexts,
cooldown=cooldown,
default_member_permissions=default_member_permissions,
guild_ids=guild_ids,
integration_types=integration_types,
name=name,
name_localizations=name_localizations,
nsfw=nsfw,
**kwargs,
)


def application_command(
Comment thread
ToothyDev marked this conversation as resolved.
cls=SlashCommand,
Comment thread
ToothyDev marked this conversation as resolved.
Outdated
checks: list[Callable[[ApplicationContext], bool]] | None = MISSING,
cog: Cog | None = MISSING,
contexts: set[InteractionContextType] | None = MISSING,
cooldown: Cooldown | None = MISSING,
default_member_permissions: Permissions | None = MISSING,
description: str | None = MISSING,
description_localizations: dict[str, str] | None = MISSING,
guild_ids: list[int] | None = MISSING,
integration_types: set[IntegrationType] | None = MISSING,
name: str | None = MISSING,
name_localizations: dict[str, str] | None = MISSING,
nsfw: bool = False,
options: list[Option] | None = MISSING,
parent: SlashCommandGroup | None = MISSING,
**kwargs: Any,
) -> Callable[..., C]:
"""A decorator that transforms a function into an :class:`.ApplicationCommand`. More specifically,
usually one of :class:`.SlashCommand`, :class:`.UserCommand`, or :class:`.MessageCommand`. The exact class
depends on the ``cls`` parameter.
Expand Down Expand Up @@ -2048,6 +2149,24 @@ def application_command(cls=SlashCommand, **attrs):
TypeError
If the function is not a coroutine or is already a command.
"""
params = {
"checks": checks,
"cog": cog,
"contexts": contexts,
"cooldown": cooldown,
"default_member_permissions": default_member_permissions,
"description": description,
"description_localizations": description_localizations,
"guild_ids": guild_ids,
"integration_types": integration_types,
"name": name,
"name_localizations": name_localizations,
"nsfw": nsfw,
"options": options,
"parent": parent,
**kwargs,
}
kwargs = {k: v for k, v in params.items() if v is not MISSING}

def decorator(func: Callable) -> cls:
if isinstance(func, ApplicationCommand):
Expand All @@ -2056,7 +2175,7 @@ def decorator(func: Callable) -> cls:
raise TypeError(
"func needs to be a callable or a subclass of ApplicationCommand."
)
return cls(func, **attrs)
return cls(func, **kwargs)

return decorator

Expand Down