diff options
| author | 2021-09-11 19:06:13 +0200 | |
|---|---|---|
| committer | 2021-09-11 19:18:13 +0200 | |
| commit | 6fb6967783bff17f2b248098f803bb21b1f770d9 (patch) | |
| tree | bdc31eb566b0e691d9dd0c2dd454a54d617bcc1e | |
| parent | Merge pull request #1788 from python-discord/Only-check-domain-filters-agains... (diff) | |
Use scheduling create_task util instead of creating from loop directly
The util attaches an error logging callback instead of relying on python's
exception logging which only occurs when the task is destroyed
28 files changed, 79 insertions, 47 deletions
| diff --git a/bot/async_stats.py b/bot/async_stats.py index 58a80f528..2af832e5b 100644 --- a/bot/async_stats.py +++ b/bot/async_stats.py @@ -3,6 +3,8 @@ import socket  from statsd.client.base import StatsClientBase +from bot.utils import scheduling +  class AsyncStatsClient(StatsClientBase):      """An async transport method for statsd communication.""" @@ -32,7 +34,7 @@ class AsyncStatsClient(StatsClientBase):      def _send(self, data: str) -> None:          """Start an async task to send data to statsd.""" -        self._loop.create_task(self._async_send(data)) +        scheduling.create_task(self._async_send(data), event_loop=self._loop)      async def _async_send(self, data: str) -> None:          """Send data to the statsd server using the async transport.""" diff --git a/bot/exts/backend/branding/_cog.py b/bot/exts/backend/branding/_cog.py index 0ba146635..ab0a761ff 100644 --- a/bot/exts/backend/branding/_cog.py +++ b/bot/exts/backend/branding/_cog.py @@ -17,6 +17,7 @@ from bot.bot import Bot  from bot.constants import Branding as BrandingConfig, Channels, Colours, Guild, MODERATION_ROLES  from bot.decorators import mock_in_debug  from bot.exts.backend.branding._repository import BrandingRepository, Event, RemoteObject +from bot.utils import scheduling  log = logging.getLogger(__name__) @@ -126,7 +127,7 @@ class Branding(commands.Cog):          self.bot = bot          self.repository = BrandingRepository(bot) -        self.bot.loop.create_task(self.maybe_start_daemon())  # Start depending on cache. +        scheduling.create_task(self.maybe_start_daemon(), event_loop=self.bot.loop)  # Start depending on cache.      # region: Internal logic & state management diff --git a/bot/exts/backend/config_verifier.py b/bot/exts/backend/config_verifier.py index d72c6c22e..c24cb324f 100644 --- a/bot/exts/backend/config_verifier.py +++ b/bot/exts/backend/config_verifier.py @@ -4,7 +4,7 @@ from discord.ext.commands import Cog  from bot import constants  from bot.bot import Bot - +from bot.utils import scheduling  log = logging.getLogger(__name__) @@ -14,7 +14,7 @@ class ConfigVerifier(Cog):      def __init__(self, bot: Bot):          self.bot = bot -        self.channel_verify_task = self.bot.loop.create_task(self.verify_channels()) +        self.channel_verify_task = scheduling.create_task(self.verify_channels(), event_loop=self.bot.loop)      async def verify_channels(self) -> None:          """ diff --git a/bot/exts/backend/logging.py b/bot/exts/backend/logging.py index 823f14ea4..8f1b8026f 100644 --- a/bot/exts/backend/logging.py +++ b/bot/exts/backend/logging.py @@ -5,7 +5,7 @@ from discord.ext.commands import Cog  from bot.bot import Bot  from bot.constants import Channels, DEBUG_MODE - +from bot.utils import scheduling  log = logging.getLogger(__name__) @@ -16,7 +16,7 @@ class Logging(Cog):      def __init__(self, bot: Bot):          self.bot = bot -        self.bot.loop.create_task(self.startup_greeting()) +        scheduling.create_task(self.startup_greeting(), event_loop=self.bot.loop)      async def startup_greeting(self) -> None:          """Announce our presence to the configured devlog channel.""" diff --git a/bot/exts/backend/sync/_cog.py b/bot/exts/backend/sync/_cog.py index 48d2b6f02..f88dcf538 100644 --- a/bot/exts/backend/sync/_cog.py +++ b/bot/exts/backend/sync/_cog.py @@ -9,6 +9,7 @@ from bot import constants  from bot.api import ResponseCodeError  from bot.bot import Bot  from bot.exts.backend.sync import _syncers +from bot.utils import scheduling  log = logging.getLogger(__name__) @@ -18,7 +19,7 @@ class Sync(Cog):      def __init__(self, bot: Bot) -> None:          self.bot = bot -        self.bot.loop.create_task(self.sync_guild()) +        scheduling.create_task(self.sync_guild(), event_loop=self.bot.loop)      async def sync_guild(self) -> None:          """Syncs the roles/users of the guild with the database.""" diff --git a/bot/exts/filters/antispam.py b/bot/exts/filters/antispam.py index 8c075fa95..6808bfa03 100644 --- a/bot/exts/filters/antispam.py +++ b/bot/exts/filters/antispam.py @@ -129,7 +129,11 @@ class AntiSpam(Cog):          self.max_interval = max_interval_config['interval']          self.cache = MessageCache(AntiSpamConfig.cache_size, newest_first=True) -        self.bot.loop.create_task(self.alert_on_validation_error(), name="AntiSpam.alert_on_validation_error") +        scheduling.create_task( +            self.alert_on_validation_error(), +            name="AntiSpam.alert_on_validation_error", +            event_loop=self.bot.loop, +        )      @property      def mod_log(self) -> ModLog: diff --git a/bot/exts/filters/filter_lists.py b/bot/exts/filters/filter_lists.py index 232c1e48b..a06437f3d 100644 --- a/bot/exts/filters/filter_lists.py +++ b/bot/exts/filters/filter_lists.py @@ -9,6 +9,7 @@ from bot.api import ResponseCodeError  from bot.bot import Bot  from bot.converters import ValidDiscordServerInvite, ValidFilterListType  from bot.pagination import LinePaginator +from bot.utils import scheduling  log = logging.getLogger(__name__) @@ -27,7 +28,7 @@ class FilterLists(Cog):      def __init__(self, bot: Bot) -> None:          self.bot = bot -        self.bot.loop.create_task(self._amend_docstrings()) +        scheduling.create_task(self._amend_docstrings(), event_loop=self.bot.loop)      async def _amend_docstrings(self) -> None:          """Add the valid FilterList types to the docstrings, so they'll appear in !help invocations.""" diff --git a/bot/exts/filters/filtering.py b/bot/exts/filters/filtering.py index 7e698880f..64f3b82af 100644 --- a/bot/exts/filters/filtering.py +++ b/bot/exts/filters/filtering.py @@ -21,9 +21,9 @@ from bot.constants import (  )  from bot.exts.events.code_jams._channels import CATEGORY_NAME as JAM_CATEGORY_NAME  from bot.exts.moderation.modlog import ModLog +from bot.utils import scheduling  from bot.utils.messages import format_user  from bot.utils.regex import INVITE_RE -from bot.utils.scheduling import Scheduler  log = logging.getLogger(__name__) @@ -64,7 +64,7 @@ class Filtering(Cog):      def __init__(self, bot: Bot):          self.bot = bot -        self.scheduler = Scheduler(self.__class__.__name__) +        self.scheduler = scheduling.Scheduler(self.__class__.__name__)          self.name_lock = asyncio.Lock()          staff_mistake_str = "If you believe this was a mistake, please let staff know!" @@ -133,7 +133,7 @@ class Filtering(Cog):              },          } -        self.bot.loop.create_task(self.reschedule_offensive_msg_deletion()) +        scheduling.create_task(self.reschedule_offensive_msg_deletion(), event_loop=self.bot.loop)      def cog_unload(self) -> None:          """Cancel scheduled tasks.""" diff --git a/bot/exts/fun/duck_pond.py b/bot/exts/fun/duck_pond.py index 7f7e4585c..8ced6922c 100644 --- a/bot/exts/fun/duck_pond.py +++ b/bot/exts/fun/duck_pond.py @@ -9,6 +9,7 @@ from discord.ext.commands import Cog, Context, command  from bot import constants  from bot.bot import Bot  from bot.converters import MemberOrUser +from bot.utils import scheduling  from bot.utils.checks import has_any_role  from bot.utils.messages import count_unique_users_reaction, send_attachments  from bot.utils.webhooks import send_webhook @@ -24,7 +25,7 @@ class DuckPond(Cog):          self.webhook_id = constants.Webhooks.duck_pond          self.webhook = None          self.ducked_messages = [] -        self.bot.loop.create_task(self.fetch_webhook()) +        scheduling.create_task(self.fetch_webhook(), event_loop=self.bot.loop)          self.relay_lock = None      async def fetch_webhook(self) -> None: diff --git a/bot/exts/fun/off_topic_names.py b/bot/exts/fun/off_topic_names.py index 845b8175c..2f56aa5ba 100644 --- a/bot/exts/fun/off_topic_names.py +++ b/bot/exts/fun/off_topic_names.py @@ -11,6 +11,7 @@ from bot.bot import Bot  from bot.constants import Channels, MODERATION_ROLES  from bot.converters import OffTopicName  from bot.pagination import LinePaginator +from bot.utils import scheduling  CHANNELS = (Channels.off_topic_0, Channels.off_topic_1, Channels.off_topic_2)  log = logging.getLogger(__name__) @@ -50,7 +51,7 @@ class OffTopicNames(Cog):          self.bot = bot          self.updater_task = None -        self.bot.loop.create_task(self.init_offtopic_updater()) +        scheduling.create_task(self.init_offtopic_updater(), event_loop=self.bot.loop)      def cog_unload(self) -> None:          """Cancel any running updater tasks on cog unload.""" @@ -62,7 +63,7 @@ class OffTopicNames(Cog):          await self.bot.wait_until_guild_available()          if self.updater_task is None:              coro = update_names(self.bot) -            self.updater_task = self.bot.loop.create_task(coro) +            self.updater_task = scheduling.create_task(coro, event_loop=self.bot.loop)      @group(name='otname', aliases=('otnames', 'otn'), invoke_without_command=True)      @has_any_role(*MODERATION_ROLES) diff --git a/bot/exts/help_channels/_cog.py b/bot/exts/help_channels/_cog.py index cfc9cf477..40fb9429c 100644 --- a/bot/exts/help_channels/_cog.py +++ b/bot/exts/help_channels/_cog.py @@ -82,7 +82,7 @@ class HelpChannels(commands.Cog):          # Asyncio stuff          self.queue_tasks: t.List[asyncio.Task] = [] -        self.init_task = self.bot.loop.create_task(self.init_cog()) +        self.init_task = scheduling.create_task(self.init_cog(), event_loop=self.bot.loop)      def cog_unload(self) -> None:          """Cancel the init task and scheduled tasks when the cog unloads.""" diff --git a/bot/exts/info/codeblock/_cog.py b/bot/exts/info/codeblock/_cog.py index 9a0705d2b..f63a459ff 100644 --- a/bot/exts/info/codeblock/_cog.py +++ b/bot/exts/info/codeblock/_cog.py @@ -11,7 +11,7 @@ from bot.bot import Bot  from bot.exts.filters.token_remover import TokenRemover  from bot.exts.filters.webhook_remover import WEBHOOK_URL_RE  from bot.exts.info.codeblock._instructions import get_instructions -from bot.utils import has_lines +from bot.utils import has_lines, scheduling  from bot.utils.channel import is_help_channel  from bot.utils.messages import wait_for_deletion @@ -114,7 +114,7 @@ class CodeBlockCog(Cog, name="Code Block"):          bot_message = await message.channel.send(f"Hey {message.author.mention}!", embed=embed)          self.codeblock_message_ids[message.id] = bot_message.id -        self.bot.loop.create_task(wait_for_deletion(bot_message, (message.author.id,))) +        scheduling.create_task(wait_for_deletion(bot_message, (message.author.id,)), event_loop=self.bot.loop)          # Increase amount of codeblock correction in stats          self.bot.stats.incr("codeblock_corrections") diff --git a/bot/exts/info/doc/_batch_parser.py b/bot/exts/info/doc/_batch_parser.py index 369bb462c..51ee29b68 100644 --- a/bot/exts/info/doc/_batch_parser.py +++ b/bot/exts/info/doc/_batch_parser.py @@ -24,9 +24,10 @@ class StaleInventoryNotifier:      """Handle sending notifications about stale inventories through `DocItem`s to dev log."""      def __init__(self): -        self._init_task = bot.instance.loop.create_task( +        self._init_task = scheduling.create_task(              self._init_channel(), -            name="StaleInventoryNotifier channel init" +            name="StaleInventoryNotifier channel init", +            event_loop=bot.instance.loop,          )          self._warned_urls = set() diff --git a/bot/exts/info/doc/_cog.py b/bot/exts/info/doc/_cog.py index a2119a53d..6cc1723cd 100644 --- a/bot/exts/info/doc/_cog.py +++ b/bot/exts/info/doc/_cog.py @@ -17,6 +17,7 @@ from bot.bot import Bot  from bot.constants import MODERATION_ROLES, RedirectOutput  from bot.converters import Inventory, PackageName, ValidURL, allowed_strings  from bot.pagination import LinePaginator +from bot.utils import scheduling  from bot.utils.lock import SharedEvent, lock  from bot.utils.messages import send_denial, wait_for_deletion  from bot.utils.scheduling import Scheduler @@ -75,9 +76,10 @@ class DocCog(commands.Cog):          self.refresh_event.set()          self.symbol_get_event = SharedEvent() -        self.init_refresh_task = self.bot.loop.create_task( +        self.init_refresh_task = scheduling.create_task(              self.init_refresh_inventory(), -            name="Doc inventory init" +            name="Doc inventory init", +            event_loop=self.bot.loop,          )      @lock(NAMESPACE, COMMAND_LOCK_SINGLETON, raise_error=True) diff --git a/bot/exts/info/pep.py b/bot/exts/info/pep.py index b11b34db0..bbd112911 100644 --- a/bot/exts/info/pep.py +++ b/bot/exts/info/pep.py @@ -9,6 +9,7 @@ from discord.ext.commands import Cog, Context, command  from bot.bot import Bot  from bot.constants import Keys +from bot.utils import scheduling  from bot.utils.caching import AsyncCache  log = logging.getLogger(__name__) @@ -32,7 +33,7 @@ class PythonEnhancementProposals(Cog):          self.peps: Dict[int, str] = {}          # To avoid situations where we don't have last datetime, set this to now.          self.last_refreshed_peps: datetime = datetime.now() -        self.bot.loop.create_task(self.refresh_peps_urls()) +        scheduling.create_task(self.refresh_peps_urls(), event_loop=self.bot.loop)      async def refresh_peps_urls(self) -> None:          """Refresh PEP URLs listing in every 3 hours.""" diff --git a/bot/exts/info/python_news.py b/bot/exts/info/python_news.py index 63eb4ac17..58dcd3a02 100644 --- a/bot/exts/info/python_news.py +++ b/bot/exts/info/python_news.py @@ -11,6 +11,7 @@ from discord.ext.tasks import loop  from bot import constants  from bot.bot import Bot +from bot.utils import scheduling  from bot.utils.webhooks import send_webhook  PEPS_RSS_URL = "https://www.python.org/dev/peps/peps.rss/" @@ -33,8 +34,8 @@ class PythonNews(Cog):          self.webhook_names = {}          self.webhook: t.Optional[discord.Webhook] = None -        self.bot.loop.create_task(self.get_webhook_names()) -        self.bot.loop.create_task(self.get_webhook_and_channel()) +        scheduling.create_task(self.get_webhook_names(), event_loop=self.bot.loop) +        scheduling.create_task(self.get_webhook_and_channel(), event_loop=self.bot.loop)      async def start_tasks(self) -> None:          """Start the tasks for fetching new PEPs and mailing list messages.""" diff --git a/bot/exts/moderation/defcon.py b/bot/exts/moderation/defcon.py index 6ac077b93..053e8ae57 100644 --- a/bot/exts/moderation/defcon.py +++ b/bot/exts/moderation/defcon.py @@ -17,6 +17,7 @@ from bot.bot import Bot  from bot.constants import Channels, Colours, Emojis, Event, Icons, MODERATION_ROLES, Roles  from bot.converters import DurationDelta, Expiry  from bot.exts.moderation.modlog import ModLog +from bot.utils import scheduling  from bot.utils.messages import format_user  from bot.utils.scheduling import Scheduler  from bot.utils.time import ( @@ -69,7 +70,7 @@ class Defcon(Cog):          self.scheduler = Scheduler(self.__class__.__name__) -        self.bot.loop.create_task(self._sync_settings()) +        scheduling.create_task(self._sync_settings(), event_loop=self.bot.loop)      @property      def mod_log(self) -> ModLog: diff --git a/bot/exts/moderation/incidents.py b/bot/exts/moderation/incidents.py index 561e0251e..a3d90e3fe 100644 --- a/bot/exts/moderation/incidents.py +++ b/bot/exts/moderation/incidents.py @@ -9,6 +9,7 @@ from discord.ext.commands import Cog  from bot.bot import Bot  from bot.constants import Channels, Colours, Emojis, Guild, Webhooks +from bot.utils import scheduling  from bot.utils.messages import sub_clyde  log = logging.getLogger(__name__) @@ -190,7 +191,7 @@ class Incidents(Cog):          self.bot = bot          self.event_lock = asyncio.Lock() -        self.crawl_task = self.bot.loop.create_task(self.crawl_incidents()) +        self.crawl_task = scheduling.create_task(self.crawl_incidents(), event_loop=self.bot.loop)      async def crawl_incidents(self) -> None:          """ @@ -275,7 +276,7 @@ class Incidents(Cog):              return payload.message_id == incident.id          coroutine = self.bot.wait_for(event="raw_message_delete", check=check, timeout=timeout) -        return self.bot.loop.create_task(coroutine) +        return scheduling.create_task(coroutine, event_loop=self.bot.loop)      async def process_event(self, reaction: str, incident: discord.Message, member: discord.Member) -> None:          """ diff --git a/bot/exts/moderation/infraction/_scheduler.py b/bot/exts/moderation/infraction/_scheduler.py index 6ba4e74e9..8e844822d 100644 --- a/bot/exts/moderation/infraction/_scheduler.py +++ b/bot/exts/moderation/infraction/_scheduler.py @@ -29,7 +29,7 @@ class InfractionScheduler:          self.bot = bot          self.scheduler = scheduling.Scheduler(self.__class__.__name__) -        self.bot.loop.create_task(self.reschedule_infractions(supported_infractions)) +        scheduling.create_task(self.reschedule_infractions(supported_infractions), event_loop=self.bot.loop)      def cog_unload(self) -> None:          """Cancel scheduled tasks.""" diff --git a/bot/exts/moderation/metabase.py b/bot/exts/moderation/metabase.py index 9eeeec074..6eadd4bad 100644 --- a/bot/exts/moderation/metabase.py +++ b/bot/exts/moderation/metabase.py @@ -14,7 +14,7 @@ from discord.ext.commands import Cog, Context, group, has_any_role  from bot.bot import Bot  from bot.constants import Metabase as MetabaseConfig, Roles  from bot.converters import allowed_strings -from bot.utils import send_to_paste_service +from bot.utils import scheduling, send_to_paste_service  from bot.utils.channel import is_mod_channel  from bot.utils.scheduling import Scheduler @@ -40,7 +40,7 @@ class Metabase(Cog):          self.exports: Dict[int, List[Dict]] = {}  # Saves the output of each question, so internal eval can access it -        self.init_task = self.bot.loop.create_task(self.init_cog()) +        self.init_task = scheduling.create_task(self.init_cog(), event_loop=self.bot.loop)      async def cog_command_error(self, ctx: Context, error: Exception) -> None:          """Handle ClientResponseError errors locally to invalidate token if needed.""" diff --git a/bot/exts/moderation/modpings.py b/bot/exts/moderation/modpings.py index 80c9f0c38..d775cdedf 100644 --- a/bot/exts/moderation/modpings.py +++ b/bot/exts/moderation/modpings.py @@ -9,6 +9,7 @@ from discord.ext.commands import Cog, Context, group, has_any_role  from bot.bot import Bot  from bot.constants import Colours, Emojis, Guild, Icons, MODERATION_ROLES, Roles  from bot.converters import Expiry +from bot.utils import scheduling  from bot.utils.scheduling import Scheduler  log = logging.getLogger(__name__) @@ -29,7 +30,11 @@ class ModPings(Cog):          self.guild = None          self.moderators_role = None -        self.reschedule_task = self.bot.loop.create_task(self.reschedule_roles(), name="mod-pings-reschedule") +        self.reschedule_task = scheduling.create_task( +            self.reschedule_roles(), +            name="mod-pings-reschedule", +            event_loop=self.bot.loop, +        )      async def reschedule_roles(self) -> None:          """Reschedule moderators role re-apply times.""" diff --git a/bot/exts/moderation/silence.py b/bot/exts/moderation/silence.py index 95e2792c3..2ee6496df 100644 --- a/bot/exts/moderation/silence.py +++ b/bot/exts/moderation/silence.py @@ -13,6 +13,7 @@ from discord.ext.commands import Context  from bot import constants  from bot.bot import Bot  from bot.converters import HushDurationConverter +from bot.utils import scheduling  from bot.utils.lock import LockedResourceError, lock, lock_arg  from bot.utils.scheduling import Scheduler @@ -104,7 +105,7 @@ class Silence(commands.Cog):          self.bot = bot          self.scheduler = Scheduler(self.__class__.__name__) -        self._init_task = self.bot.loop.create_task(self._async_init()) +        self._init_task = scheduling.create_task(self._async_init(), event_loop=self.bot.loop)      async def _async_init(self) -> None:          """Set instance attributes once the guild is available and reschedule unsilences.""" diff --git a/bot/exts/moderation/stream.py b/bot/exts/moderation/stream.py index 01d2614b0..b5bd62a71 100644 --- a/bot/exts/moderation/stream.py +++ b/bot/exts/moderation/stream.py @@ -15,7 +15,7 @@ from bot.constants import (  )  from bot.converters import Expiry  from bot.pagination import LinePaginator -from bot.utils.scheduling import Scheduler +from bot.utils import scheduling  from bot.utils.time import discord_timestamp, format_infraction_with_duration  log = logging.getLogger(__name__) @@ -30,8 +30,8 @@ class Stream(commands.Cog):      def __init__(self, bot: Bot):          self.bot = bot -        self.scheduler = Scheduler(self.__class__.__name__) -        self.reload_task = self.bot.loop.create_task(self._reload_tasks_from_redis()) +        self.scheduler = scheduling.Scheduler(self.__class__.__name__) +        self.reload_task = scheduling.create_task(self._reload_tasks_from_redis(), event_loop=self.bot.loop)      def cog_unload(self) -> None:          """Cancel all scheduled tasks.""" diff --git a/bot/exts/moderation/watchchannels/_watchchannel.py b/bot/exts/moderation/watchchannels/_watchchannel.py index 146426569..a42e1f518 100644 --- a/bot/exts/moderation/watchchannels/_watchchannel.py +++ b/bot/exts/moderation/watchchannels/_watchchannel.py @@ -18,7 +18,7 @@ from bot.exts.filters.token_remover import TokenRemover  from bot.exts.filters.webhook_remover import WEBHOOK_URL_RE  from bot.exts.moderation.modlog import ModLog  from bot.pagination import LinePaginator -from bot.utils import CogABCMeta, messages +from bot.utils import CogABCMeta, messages, scheduling  from bot.utils.time import get_time_delta  log = logging.getLogger(__name__) @@ -69,7 +69,7 @@ class WatchChannel(metaclass=CogABCMeta):          self.message_history = MessageHistory()          self.disable_header = disable_header -        self._start = self.bot.loop.create_task(self.start_watchchannel()) +        self._start = scheduling.create_task(self.start_watchchannel(), event_loop=self.bot.loop)      @property      def modlog(self) -> ModLog: @@ -169,7 +169,7 @@ class WatchChannel(metaclass=CogABCMeta):          """Queues up messages sent by watched users."""          if msg.author.id in self.watched_users:              if not self.consuming_messages: -                self._consume_task = self.bot.loop.create_task(self.consume_messages()) +                self._consume_task = scheduling.create_task(self.consume_messages(), event_loop=self.bot.loop)              self.log.trace(f"Received message: {msg.content} ({len(msg.attachments)} attachments)")              self.message_queue[msg.author.id][msg.channel.id].append(msg) @@ -199,7 +199,10 @@ class WatchChannel(metaclass=CogABCMeta):          if self.message_queue:              self.log.trace("Channel queue not empty: Continuing consuming queues") -            self._consume_task = self.bot.loop.create_task(self.consume_messages(delay_consumption=False)) +            self._consume_task = scheduling.create_task( +                self.consume_messages(delay_consumption=False), +                event_loop=self.bot.loop, +            )          else:              self.log.trace("Done consuming messages.") diff --git a/bot/exts/utils/reminders.py b/bot/exts/utils/reminders.py index 41b6cac5c..00eb930b5 100644 --- a/bot/exts/utils/reminders.py +++ b/bot/exts/utils/reminders.py @@ -17,6 +17,7 @@ from bot.constants import (  )  from bot.converters import Duration, UnambiguousUser  from bot.pagination import LinePaginator +from bot.utils import scheduling  from bot.utils.checks import has_any_role_check, has_no_roles_check  from bot.utils.lock import lock_arg  from bot.utils.messages import send_denial @@ -40,7 +41,7 @@ class Reminders(Cog):          self.bot = bot          self.scheduler = Scheduler(self.__class__.__name__) -        self.bot.loop.create_task(self.reschedule_reminders()) +        scheduling.create_task(self.reschedule_reminders(), event_loop=self.bot.loop)      def cog_unload(self) -> None:          """Cancel scheduled tasks.""" diff --git a/bot/exts/utils/snekbox.py b/bot/exts/utils/snekbox.py index b1f1ba6a8..5fb10a25b 100644 --- a/bot/exts/utils/snekbox.py +++ b/bot/exts/utils/snekbox.py @@ -14,7 +14,7 @@ from discord.ext.commands import Cog, Context, command, guild_only  from bot.bot import Bot  from bot.constants import Categories, Channels, Roles, URLs  from bot.decorators import redirect_output -from bot.utils import send_to_paste_service +from bot.utils import scheduling, send_to_paste_service  from bot.utils.messages import wait_for_deletion  log = logging.getLogger(__name__) @@ -219,7 +219,7 @@ class Snekbox(Cog):                  response = await ctx.send("Attempt to circumvent filter detected. Moderator team has been alerted.")              else:                  response = await ctx.send(msg) -            self.bot.loop.create_task(wait_for_deletion(response, (ctx.author.id,))) +            scheduling.create_task(wait_for_deletion(response, (ctx.author.id,)), event_loop=self.bot.loop)              log.info(f"{ctx.author}'s job had a return code of {results['returncode']}")          return response diff --git a/tests/bot/exts/backend/sync/test_cog.py b/tests/bot/exts/backend/sync/test_cog.py index 22a07313e..fdd0ab74a 100644 --- a/tests/bot/exts/backend/sync/test_cog.py +++ b/tests/bot/exts/backend/sync/test_cog.py @@ -60,13 +60,13 @@ class SyncCogTestCase(unittest.IsolatedAsyncioTestCase):  class SyncCogTests(SyncCogTestCase):      """Tests for the Sync cog.""" +    @mock.patch("bot.utils.scheduling.create_task")      @mock.patch.object(Sync, "sync_guild", new_callable=mock.MagicMock) -    def test_sync_cog_init(self, sync_guild): +    def test_sync_cog_init(self, sync_guild, create_task):          """Should instantiate syncers and run a sync for the guild."""          # Reset because a Sync cog was already instantiated in setUp.          self.RoleSyncer.reset_mock()          self.UserSyncer.reset_mock() -        self.bot.loop.create_task = mock.MagicMock()          mock_sync_guild_coro = mock.MagicMock()          sync_guild.return_value = mock_sync_guild_coro @@ -74,7 +74,8 @@ class SyncCogTests(SyncCogTestCase):          Sync(self.bot)          sync_guild.assert_called_once_with() -        self.bot.loop.create_task.assert_called_once_with(mock_sync_guild_coro) +        create_task.assert_called_once() +        self.assertEqual(create_task.call_args.args[0], mock_sync_guild_coro)      async def test_sync_cog_sync_guild(self):          """Roles and users should be synced only if a guild is successfully retrieved.""" diff --git a/tests/helpers.py b/tests/helpers.py index 3978076ed..47f06f292 100644 --- a/tests/helpers.py +++ b/tests/helpers.py @@ -278,7 +278,10 @@ def _get_mock_loop() -> unittest.mock.Mock:      # Since calling `create_task` on our MockBot does not actually schedule the coroutine object      # as a task in the asyncio loop, this `side_effect` calls `close()` on the coroutine object      # to prevent "has not been awaited"-warnings. -    loop.create_task.side_effect = lambda coroutine: coroutine.close() +    def mock_create_task(coroutine, **kwargs): +        coroutine.close() +        return unittest.mock.Mock() +    loop.create_task.side_effect = mock_create_task      return loop | 
