Skip to content
Open
Show file tree
Hide file tree
Changes from 5 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
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ These changes are available on the `master` branch, but have not yet been releas
- Fix `TypeError` when accessing `ApplicationCommand.guild_only` or
`SlashCommandGroup.guild_only` when `contexts` is `None`.
([#3320](https://github.com/Pycord-Development/pycord/pull/3320))
- Fix AttributeError when setting `delete_existing=False` in `register_commands`.
Comment thread
Icebluewolf marked this conversation as resolved.
Outdated
([#3325](https://github.com/Pycord-Development/pycord/pull/3325))

### Deprecated

Expand Down
64 changes: 43 additions & 21 deletions discord/bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
TYPE_CHECKING,
Any,
Literal,
TypedDict,
TypeVar,
)

Expand All @@ -58,12 +59,12 @@
from .errors import CheckFailure, DiscordException
from .interactions import Interaction
from .shard import AutoShardedClient
from .types import interactions
from .types.interactions import ApplicationCommand as ApplicationCommandPayload
from .user import User
from .utils import MISSING, async_all, find, get

if TYPE_CHECKING:
from typing_extensions import Never
from typing_extensions import Never, NotRequired

from .cog import Cog
from .commands import Option
Expand Down Expand Up @@ -99,8 +100,8 @@ class ApplicationCommandMixin(ABC):

def __init__(self, *args, **kwargs) -> None:
super().__init__(*args, **kwargs)
self._pending_application_commands = []
self._application_commands = {}
self._pending_application_commands: list[ApplicationCommand] = []
self._application_commands: dict[str, ApplicationCommand] = {}

@property
def all_commands(self):
Expand Down Expand Up @@ -245,8 +246,8 @@ def get_application_command(
async def get_desynced_commands(
self,
guild_id: int | None = None,
prefetched: list[interactions.ApplicationCommand] | None = None,
) -> list[dict[str, Any]]:
prefetched: list[ApplicationCommandPayload] | None = None,
) -> list[_CommandSyncAction]:
"""|coro|

Gets the list of commands that are desynced from discord. If ``guild_id`` is specified, it will only return
Expand Down Expand Up @@ -350,7 +351,7 @@ def _check_command(cmd: ApplicationCommand, match: Mapping[str, Any]) -> bool:
return True
return False

return_value = []
return_value: list[_CommandSyncAction] = []
cmds = self.pending_application_commands.copy()

if guild_id is None:
Expand All @@ -362,7 +363,7 @@ def _check_command(cmd: ApplicationCommand, match: Mapping[str, Any]) -> bool:
if cmd.guild_ids is not None and guild_id in cmd.guild_ids
]

registered_commands: list[interactions.ApplicationCommand] = []
registered_commands: list[ApplicationCommandPayload] = []
if prefetched is not None:
registered_commands = prefetched
elif self._bot.user:
Expand Down Expand Up @@ -403,7 +404,7 @@ def _check_command(cmd: ApplicationCommand, match: Mapping[str, Any]) -> bool:
# We have this command registered but not in our list
return_value.append(
{
"command": registered_commands_dict[cmd]["name"],
"command": registered_commands_dict[cmd],
"id": int(value_["id"]),
"action": "delete",
}
Expand Down Expand Up @@ -450,7 +451,7 @@ async def register_commands(
method: Literal["individual", "bulk", "auto"] = "bulk",
force: bool = False,
delete_existing: bool = True,
) -> list[interactions.ApplicationCommand]:
) -> list[ApplicationCommandPayload]:
"""|coro|

Register a list of commands.
Expand Down Expand Up @@ -546,10 +547,10 @@ def register(
_log.debug(f"Deleting command {cmd_name} for guild {guild_id}") # type: ignore
return _register(method, *args, **kwargs)

pending_actions = []
pending_actions: list[_CommandSyncAction] = []

if not force:
prefetched_commands: list[interactions.ApplicationCommand] = []
prefetched_commands: list[ApplicationCommandPayload] = []
if self._bot.user:
if guild_id is None:
prefetched_commands = await self._bot.http.get_global_commands(
Expand All @@ -568,9 +569,7 @@ def register(
pending_actions.append(
{
"action": "delete" if delete_existing else None,
"command": collections.namedtuple("Command", ["name"])(
name=cmd["command"]
),
"command": cmd["command"],
"id": cmd["id"],
}
)
Expand Down Expand Up @@ -613,15 +612,29 @@ def register(
method == "auto" and len(filtered_deleted) == len(pending)
):
# Either the method is bulk or all the commands need to be modified, so we can just do a bulk upsert
data = [cmd["command"].to_dict() for cmd in filtered_deleted]
data = [
(
cmd["command"]
if isinstance(cmd["command"], dict)
else cmd["command"].to_dict()
)
for cmd in filtered_deleted
]
# If there's nothing to update, don't bother
if len(filtered_no_action) == 0:
_log.debug("Skipping bulk command update: Commands are up to date")
registered = prefetched_commands
else:
_log.debug(
"Bulk updating commands %s for guild %s",
{c["command"].name: c["action"] for c in pending_actions},
{
(
c["command"]["name"]
if isinstance(c["command"], dict)
else c["command"].name
): c["action"]
for c in pending_actions
},
guild_id,
)
registered = await register("bulk", data, _log=False)
Expand All @@ -633,7 +646,7 @@ def register(
await register(
"delete",
cmd["id"],
cmd_name=cmd["command"].name,
cmd_name=cmd["command"]["name"],
guild_id=guild_id,
)
continue
Expand Down Expand Up @@ -681,10 +694,11 @@ def register(
type=i.get("type"),
)
if not cmd:
raise ValueError(
_log.warning(
f"Registered command {i['name']}, type {i.get('type')} not found in"
" pending commands"
" pending commands. It's interactions will be ignored."
)
Comment thread
Icebluewolf marked this conversation as resolved.
Outdated
continue
cmd.id = i["id"]
self._application_commands[cmd.id] = cmd

Expand Down Expand Up @@ -765,7 +779,7 @@ async def on_connect():
global_commands, method=method, force=force, delete_existing=delete_existing
)

registered_guild_commands: dict[int, list[interactions.ApplicationCommand]] = {}
registered_guild_commands: dict[int, list[ApplicationCommandPayload]] = {}

if register_guild_commands:
cmd_guild_ids: list[int] = []
Expand Down Expand Up @@ -1313,6 +1327,14 @@ async def invoke_application_command(self, ctx: ApplicationContext) -> None:
def _bot(self) -> Bot | AutoShardedBot: ...


class _CommandSyncAction(TypedDict):
"""Used internally for passing metadata about the commands status for syncing with Discord."""

id: NotRequired[int]
action: Literal["upsert", "edit", "delete", None]
command: ApplicationCommand | ApplicationCommandPayload


class BotBase(ApplicationCommandMixin, CogMixin, ABC):
_supports_prefixed_commands = False

Expand Down