From ed4f2cf4660b5a823c33949f5a5358f6ee372acb Mon Sep 17 00:00:00 2001 From: jack1142 <6032823+jack1142@users.noreply.github.com> Date: Mon, 21 Mar 2022 17:24:46 +0100 Subject: [PATCH] Switch from low-level loop.create_task and asyncio.ensure_future (#5626) * Switch from low-level loop.create_task and asyncio.ensure_future * Patch vendored discord.ext.menus to use modern APIs as well That ext is no longer maintained by Danny anyway so... * black --- redbot/__main__.py | 2 +- redbot/cogs/admin/announcer.py | 2 +- redbot/cogs/audio/core/events/dpy.py | 10 +++------- redbot/cogs/audio/core/tasks/lavalink.py | 2 +- redbot/cogs/audio/core/tasks/startup.py | 6 ++---- redbot/cogs/audio/core/utilities/miscellaneous.py | 2 +- redbot/cogs/mod/mod.py | 8 +++----- redbot/cogs/mutes/mutes.py | 2 +- redbot/cogs/permissions/permissions.py | 2 +- redbot/cogs/streams/streams.py | 4 ++-- redbot/cogs/trivia/session.py | 3 +-- redbot/cogs/warnings/warnings.py | 2 +- redbot/core/bot.py | 4 ++-- redbot/core/utils/menus.py | 4 ++-- redbot/vendored/discord/ext/menus/__init__.py | 11 +++++------ 15 files changed, 27 insertions(+), 37 deletions(-) diff --git a/redbot/__main__.py b/redbot/__main__.py index 0eb499c90..7cfc7a9a2 100644 --- a/redbot/__main__.py +++ b/redbot/__main__.py @@ -493,7 +493,7 @@ def red_exception_handler(red, red_task: asyncio.Future): except Exception as exc: log.critical("The main bot task didn't handle an exception and has crashed", exc_info=exc) log.warning("Attempting to die as gracefully as possible...") - red.loop.create_task(shutdown_handler(red)) + asyncio.create_task(shutdown_handler(red)) def main(): diff --git a/redbot/cogs/admin/announcer.py b/redbot/cogs/admin/announcer.py index 220fffb26..60ba497f7 100644 --- a/redbot/cogs/admin/announcer.py +++ b/redbot/cogs/admin/announcer.py @@ -30,7 +30,7 @@ class Announcer: """ if self.active is None: self.active = True - self.ctx.bot.loop.create_task(self.announcer()) + asyncio.create_task(self.announcer()) def cancel(self): """ diff --git a/redbot/cogs/audio/core/events/dpy.py b/redbot/cogs/audio/core/events/dpy.py index c4d172c7e..bc4e0de52 100644 --- a/redbot/cogs/audio/core/events/dpy.py +++ b/redbot/cogs/audio/core/events/dpy.py @@ -230,9 +230,7 @@ class DpyEvents(MixinMeta, metaclass=CompositeMetaClass): if not self.cog_cleaned_up: self.bot.dispatch("red_audio_unload", self) self.session.detach() - self.bot.loop.create_task(self._close_database()).add_done_callback( - task_callback_trace - ) + asyncio.create_task(self._close_database()).add_done_callback(task_callback_trace) if self.player_automated_timer_task: self.player_automated_timer_task.cancel() @@ -247,11 +245,9 @@ class DpyEvents(MixinMeta, metaclass=CompositeMetaClass): lavalink.unregister_event_listener(self.lavalink_event_handler) lavalink.unregister_update_listener(self.lavalink_update_handler) - self.bot.loop.create_task(lavalink.close(self.bot)).add_done_callback( - task_callback_trace - ) + asyncio.create_task(lavalink.close(self.bot)).add_done_callback(task_callback_trace) if self.player_manager is not None: - self.bot.loop.create_task(self.player_manager.shutdown()).add_done_callback( + asyncio.create_task(self.player_manager.shutdown()).add_done_callback( task_callback_trace ) diff --git a/redbot/cogs/audio/core/tasks/lavalink.py b/redbot/cogs/audio/core/tasks/lavalink.py index 288eb7114..99670faa9 100644 --- a/redbot/cogs/audio/core/tasks/lavalink.py +++ b/redbot/cogs/audio/core/tasks/lavalink.py @@ -28,7 +28,7 @@ class LavalinkTasks(MixinMeta, metaclass=CompositeMetaClass): self._restore_task = None lavalink.register_event_listener(self.lavalink_event_handler) lavalink.register_update_listener(self.lavalink_update_handler) - self.lavalink_connect_task = self.bot.loop.create_task(self.lavalink_attempt_connect()) + self.lavalink_connect_task = asyncio.create_task(self.lavalink_attempt_connect()) self.lavalink_connect_task.add_done_callback(task_callback_debug) async def lavalink_attempt_connect(self, timeout: int = 50) -> None: diff --git a/redbot/cogs/audio/core/tasks/startup.py b/redbot/cogs/audio/core/tasks/startup.py index bd54e01da..e217d408b 100644 --- a/redbot/cogs/audio/core/tasks/startup.py +++ b/redbot/cogs/audio/core/tasks/startup.py @@ -29,7 +29,7 @@ class StartUpTasks(MixinMeta, metaclass=CompositeMetaClass): # If it waits for ready in startup, we cause a deadlock during initial load # as initial load happens before the bot can ever be ready. lavalink.set_logging_level(self.bot._cli_flags.logging_level) - self.cog_init_task = self.bot.loop.create_task(self.initialize()) + self.cog_init_task = asyncio.create_task(self.initialize()) self.cog_init_task.add_done_callback(task_callback_debug) async def initialize(self) -> None: @@ -53,9 +53,7 @@ class StartUpTasks(MixinMeta, metaclass=CompositeMetaClass): await self.api_interface.persistent_queue_api.delete_scheduled() await self._build_bundled_playlist() self.lavalink_restart_connect() - self.player_automated_timer_task = self.bot.loop.create_task( - self.player_automated_timer() - ) + self.player_automated_timer_task = asyncio.create_task(self.player_automated_timer()) self.player_automated_timer_task.add_done_callback(task_callback_debug) except Exception as exc: log.critical("Audio failed to start up, please report this issue.", exc_info=exc) diff --git a/redbot/cogs/audio/core/utilities/miscellaneous.py b/redbot/cogs/audio/core/utilities/miscellaneous.py index 39626d608..da0e1cd5a 100644 --- a/redbot/cogs/audio/core/utilities/miscellaneous.py +++ b/redbot/cogs/audio/core/utilities/miscellaneous.py @@ -35,7 +35,7 @@ class MiscellaneousUtilities(MixinMeta, metaclass=CompositeMetaClass): self, message: discord.Message, emoji: MutableMapping = None ) -> asyncio.Task: """Non blocking version of clear_react.""" - task = self.bot.loop.create_task(self.clear_react(message, emoji)) + task = asyncio.create_task(self.clear_react(message, emoji)) task.add_done_callback(task_callback_trace) return task diff --git a/redbot/cogs/mod/mod.py b/redbot/cogs/mod/mod.py index 8a8bd0555..cdc556fc4 100644 --- a/redbot/cogs/mod/mod.py +++ b/redbot/cogs/mod/mod.py @@ -144,7 +144,7 @@ class Mod( "Ignored guilds and channels have been moved. " "Please use {command} to migrate the old settings." ).format(command=inline("[p]moveignoredchannels")) - self.bot.loop.create_task(send_to_owners_with_prefix_replaced(self.bot, msg)) + asyncio.create_task(send_to_owners_with_prefix_replaced(self.bot, msg)) message_sent = True break if message_sent is False: @@ -154,9 +154,7 @@ class Mod( "Ignored guilds and channels have been moved. " "Please use {command} to migrate the old settings." ).format(command=inline("[p]moveignoredchannels")) - self.bot.loop.create_task( - send_to_owners_with_prefix_replaced(self.bot, msg) - ) + asyncio.create_task(send_to_owners_with_prefix_replaced(self.bot, msg)) break await self.config.version.set("1.1.0") if await self.config.version() < "1.2.0": @@ -166,7 +164,7 @@ class Mod( "Delete delay settings have been moved. " "Please use {command} to migrate the old settings." ).format(command=inline("[p]movedeletedelay")) - self.bot.loop.create_task(send_to_owners_with_prefix_replaced(self.bot, msg)) + asyncio.create_task(send_to_owners_with_prefix_replaced(self.bot, msg)) break await self.config.version.set("1.2.0") if await self.config.version() < "1.3.0": diff --git a/redbot/cogs/mutes/mutes.py b/redbot/cogs/mutes/mutes.py index 5ea54efd6..ca5478d3e 100644 --- a/redbot/cogs/mutes/mutes.py +++ b/redbot/cogs/mutes/mutes.py @@ -108,7 +108,7 @@ class Mutes(VoiceMutes, commands.Cog, metaclass=CompositeMetaClass): # to wait for a guild to finish channel unmutes before # checking for manual overwrites - self._init_task = self.bot.loop.create_task(self._initialize()) + self._init_task = asyncio.create_task(self._initialize()) async def red_delete_data_for_user( self, diff --git a/redbot/cogs/permissions/permissions.py b/redbot/cogs/permissions/permissions.py index afb3cb3d0..e9cf264ec 100644 --- a/redbot/cogs/permissions/permissions.py +++ b/redbot/cogs/permissions/permissions.py @@ -819,7 +819,7 @@ class Permissions(commands.Cog): cog_or_command.deny_to(model_id, guild_id=guild_id) def cog_unload(self) -> None: - self.bot.loop.create_task(self._unload_all_rules()) + asyncio.create_task(self._unload_all_rules()) async def _unload_all_rules(self) -> None: """Unload all rules set by this cog. diff --git a/redbot/cogs/streams/streams.py b/redbot/cogs/streams/streams.py index 2b5f9b803..b85a07742 100644 --- a/redbot/cogs/streams/streams.py +++ b/redbot/cogs/streams/streams.py @@ -80,7 +80,7 @@ class Streams(commands.Cog): self.yt_cid_pattern = re.compile("^UC[-_A-Za-z0-9]{21}[AQgw]$") self._ready_event: asyncio.Event = asyncio.Event() - self._init_task: asyncio.Task = self.bot.loop.create_task(self.initialize()) + self._init_task: asyncio.Task = asyncio.create_task(self.initialize()) async def red_delete_data_for_user(self, **kwargs): """ Nothing to delete """ @@ -100,7 +100,7 @@ class Streams(commands.Cog): await self.move_api_keys() await self.get_twitch_bearer_token() self.streams = await self.load_streams() - self.task = self.bot.loop.create_task(self._stream_alerts()) + self.task = asyncio.create_task(self._stream_alerts()) except Exception as error: log.exception("Failed to initialize Streams cog:", exc_info=error) diff --git a/redbot/cogs/trivia/session.py b/redbot/cogs/trivia/session.py index 53316d607..bd83627d9 100644 --- a/redbot/cogs/trivia/session.py +++ b/redbot/cogs/trivia/session.py @@ -103,8 +103,7 @@ class TriviaSession: """ session = cls(ctx, question_list, settings) - loop = ctx.bot.loop - session._task = loop.create_task(session.run()) + session._task = asyncio.create_task(session.run()) session._task.add_done_callback(session._error_handler) return session diff --git a/redbot/cogs/warnings/warnings.py b/redbot/cogs/warnings/warnings.py index f9570df1f..c5f420a99 100644 --- a/redbot/cogs/warnings/warnings.py +++ b/redbot/cogs/warnings/warnings.py @@ -47,7 +47,7 @@ class Warnings(commands.Cog): self.config.register_guild(**self.default_guild) self.config.register_member(**self.default_member) self.bot = bot - self.registration_task = self.bot.loop.create_task(self.register_warningtype()) + self.registration_task = asyncio.create_task(self.register_warningtype()) async def red_delete_data_for_user( self, diff --git a/redbot/core/bot.py b/redbot/core/bot.py index e99eecfa1..bd5e85991 100644 --- a/redbot/core/bot.py +++ b/redbot/core/bot.py @@ -1082,7 +1082,7 @@ class Red( if any(LIB_PATH.iterdir()): shutil.rmtree(str(LIB_PATH)) LIB_PATH.mkdir() - self.loop.create_task( + asyncio.create_task( send_to_owners_with_prefix_replaced( self, "We detected a change in minor Python version" @@ -1117,7 +1117,7 @@ class Red( system_changed = True if system_changed and not python_version_changed: - self.loop.create_task( + asyncio.create_task( send_to_owners_with_prefix_replaced( self, "We detected a possible change in machine's operating system" diff --git a/redbot/core/utils/menus.py b/redbot/core/utils/menus.py index b0cdf604c..ce9c44643 100644 --- a/redbot/core/utils/menus.py +++ b/redbot/core/utils/menus.py @@ -90,8 +90,8 @@ async def menu( try: predicates = ReactionPredicate.with_emojis(tuple(controls.keys()), message, ctx.author) tasks = [ - asyncio.ensure_future(ctx.bot.wait_for("reaction_add", check=predicates)), - asyncio.ensure_future(ctx.bot.wait_for("reaction_remove", check=predicates)), + asyncio.create_task(ctx.bot.wait_for("reaction_add", check=predicates)), + asyncio.create_task(ctx.bot.wait_for("reaction_remove", check=predicates)), ] done, pending = await asyncio.wait( tasks, timeout=timeout, return_when=asyncio.FIRST_COMPLETED diff --git a/redbot/vendored/discord/ext/menus/__init__.py b/redbot/vendored/discord/ext/menus/__init__.py index b45000434..0f6f16da1 100644 --- a/redbot/vendored/discord/ext/menus/__init__.py +++ b/redbot/vendored/discord/ext/menus/__init__.py @@ -553,13 +553,12 @@ class Menu(metaclass=_MenuMeta): async def _internal_loop(self): try: self.__timed_out = False - loop = self.bot.loop # Ensure the name exists for the cancellation handling tasks = [] while self._running: tasks = [ - asyncio.ensure_future(self.bot.wait_for('raw_reaction_add', check=self.reaction_check)), - asyncio.ensure_future(self.bot.wait_for('raw_reaction_remove', check=self.reaction_check)) + asyncio.create_task(self.bot.wait_for('raw_reaction_add', check=self.reaction_check)), + asyncio.create_task(self.bot.wait_for('raw_reaction_remove', check=self.reaction_check)) ] done, pending = await asyncio.wait(tasks, timeout=self.timeout, return_when=asyncio.FIRST_COMPLETED) for task in pending: @@ -570,7 +569,7 @@ class Menu(metaclass=_MenuMeta): # Exception will propagate if e.g. cancelled or timed out payload = done.pop().result() - loop.create_task(self.update(payload)) + asyncio.create_task(self.update(payload)) # NOTE: Removing the reaction ourselves after it's been done when # mixed with the checks above is incredibly racy. @@ -712,12 +711,12 @@ class Menu(metaclass=_MenuMeta): self.__tasks.clear() self._running = True - self.__tasks.append(bot.loop.create_task(self._internal_loop())) + self.__tasks.append(asyncio.create_task(self._internal_loop())) async def add_reactions_task(): for emoji in self.buttons: await msg.add_reaction(emoji) - self.__tasks.append(bot.loop.create_task(add_reactions_task())) + self.__tasks.append(asyncio.create_task(add_reactions_task())) if wait: await self._event.wait()