aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bot/async_stats.py4
-rw-r--r--bot/exts/backend/branding/_cog.py3
-rw-r--r--bot/exts/backend/config_verifier.py4
-rw-r--r--bot/exts/backend/logging.py4
-rw-r--r--bot/exts/backend/sync/_cog.py3
-rw-r--r--bot/exts/filters/antispam.py6
-rw-r--r--bot/exts/filters/filter_lists.py3
-rw-r--r--bot/exts/filters/filtering.py6
-rw-r--r--bot/exts/fun/duck_pond.py3
-rw-r--r--bot/exts/fun/off_topic_names.py5
-rw-r--r--bot/exts/help_channels/_cog.py2
-rw-r--r--bot/exts/info/codeblock/_cog.py4
-rw-r--r--bot/exts/info/doc/_batch_parser.py5
-rw-r--r--bot/exts/info/doc/_cog.py6
-rw-r--r--bot/exts/info/pep.py3
-rw-r--r--bot/exts/info/python_news.py5
-rw-r--r--bot/exts/moderation/defcon.py3
-rw-r--r--bot/exts/moderation/incidents.py5
-rw-r--r--bot/exts/moderation/infraction/_scheduler.py2
-rw-r--r--bot/exts/moderation/metabase.py4
-rw-r--r--bot/exts/moderation/modpings.py7
-rw-r--r--bot/exts/moderation/silence.py3
-rw-r--r--bot/exts/moderation/stream.py6
-rw-r--r--bot/exts/moderation/watchchannels/_watchchannel.py11
-rw-r--r--bot/exts/utils/reminders.py3
-rw-r--r--bot/exts/utils/snekbox.py4
-rw-r--r--tests/bot/exts/backend/sync/test_cog.py7
-rw-r--r--tests/helpers.py5
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