Add client.setup and move readying commands to that

This commit is contained in:
Gnome 2021-08-31 19:13:32 +01:00
parent 7c83c335d1
commit 2cdf4b86c5
2 changed files with 31 additions and 13 deletions

View File

@ -595,7 +595,7 @@ class Client:
async def start(self, token: str, *, reconnect: bool = True) -> None: async def start(self, token: str, *, reconnect: bool = True) -> None:
"""|coro| """|coro|
A shorthand coroutine for :meth:`login` + :meth:`connect`. A shorthand coroutine for :meth:`login` + :meth:`setup` + :meth:`connect`.
Raises Raises
------- -------
@ -603,8 +603,19 @@ class Client:
An unexpected keyword argument was received. An unexpected keyword argument was received.
""" """
await self.login(token) await self.login(token)
await self.setup()
await self.connect(reconnect=reconnect) await self.connect(reconnect=reconnect)
async def setup(self) -> Any:
"""|coro|
A coroutine to be called to setup the bot, by default this is blank.
To perform asynchronous setup after the bot is logged in but before
it has connected to the Websocket, overwrite this coroutine.
"""
pass
def run(self, *args: Any, **kwargs: Any) -> None: def run(self, *args: Any, **kwargs: Any) -> None:
"""A blocking call that abstracts away the event loop """A blocking call that abstracts away the event loop
initialisation from you. initialisation from you.

View File

@ -28,6 +28,7 @@ from __future__ import annotations
import asyncio import asyncio
import collections import collections
import collections.abc import collections.abc
from discord.http import HTTPClient
import inspect import inspect
import importlib.util import importlib.util
@ -166,7 +167,7 @@ class BotBase(GroupMixin):
if not (message_commands or slash_commands): if not (message_commands or slash_commands):
raise TypeError("Both message_commands and slash_commands are disabled.") raise TypeError("Both message_commands and slash_commands are disabled.")
elif slash_commands: elif slash_commands:
self.slash_command_guild = options['slash_command_guild'] self.slash_command_guild = options.get('slash_command_guild', None)
if help_command is _default: if help_command is _default:
self.help_command = DefaultHelpCommand() self.help_command = DefaultHelpCommand()
@ -183,6 +184,15 @@ class BotBase(GroupMixin):
for event in self.extra_events.get(ev, []): for event in self.extra_events.get(ev, []):
self._schedule_event(event, ev, *args, **kwargs) # type: ignore self._schedule_event(event, ev, *args, **kwargs) # type: ignore
async def _create_application_commands(self, application_id: int, http: HTTPClient):
commands = [scmd for cmd in self.commands if not cmd.hidden and (scmd := cmd.to_application_command()) is not None]
if self.slash_command_guild is None:
await http.bulk_upsert_global_commands(application_id, payload=commands)
else:
await http.bulk_upsert_guild_commands(application_id, self.slash_command_guild, payload=commands)
@discord.utils.copy_doc(discord.Client.close) @discord.utils.copy_doc(discord.Client.close)
async def close(self) -> None: async def close(self) -> None:
for extension in tuple(self.__extensions): for extension in tuple(self.__extensions):
@ -1211,23 +1221,20 @@ class Bot(BotBase, discord.Client):
.. versionadded:: 1.7 .. versionadded:: 1.7
""" """
# Needs to be moved to somewhere else, preferably BotBase async def setup(self):
async def login(self, token: str) -> None:
await super().login(token=token)
await self._ready_commands()
async def _ready_commands(self):
if not self.slash_commands: if not self.slash_commands:
return return
application = self.application_id or (await self.application_info()).id application = self.application_id or (await self.application_info()).id
commands = [scmd for cmd in self.commands if not cmd.hidden and (scmd := cmd.to_application_command()) is not None] await self._create_application_commands(application, self.http)
await self.http.bulk_upsert_guild_commands(application, self.slash_command_guild, payload=commands)
class AutoShardedBot(BotBase, discord.AutoShardedClient): class AutoShardedBot(BotBase, discord.AutoShardedClient):
"""This is similar to :class:`.Bot` except that it is inherited from """This is similar to :class:`.Bot` except that it is inherited from
:class:`discord.AutoShardedClient` instead. :class:`discord.AutoShardedClient` instead.
""" """
pass async def setup(self):
if not self.slash_commands:
return
application = self.application_id or (await self.application_info()).id
await self._create_application_commands(application, self.http)