aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--botcore/utils/caching.py2
-rw-r--r--botcore/utils/channel.py23
-rw-r--r--botcore/utils/logging.py2
-rw-r--r--botcore/utils/scheduling.py50
4 files changed, 49 insertions, 28 deletions
diff --git a/botcore/utils/caching.py b/botcore/utils/caching.py
index ea71ed1d..ac34bb9b 100644
--- a/botcore/utils/caching.py
+++ b/botcore/utils/caching.py
@@ -16,7 +16,7 @@ class AsyncCache:
def __init__(self, max_size: int = 128):
"""
- Initialise a new AsyncCache instance.
+ Initialise a new :obj:`AsyncCache` instance.
Args:
max_size: How many items to store in the cache.
diff --git a/botcore/utils/channel.py b/botcore/utils/channel.py
index db155911..17e70a2a 100644
--- a/botcore/utils/channel.py
+++ b/botcore/utils/channel.py
@@ -10,7 +10,7 @@ log = logging.get_logger(__name__)
def is_in_category(channel: discord.TextChannel, category_id: int) -> bool:
"""
- Return whether the given channel has the category_id.
+ Return whether the given ``channel`` in the the category with the id ``category_id``.
Args:
channel: The channel to check.
@@ -23,7 +23,26 @@ def is_in_category(channel: discord.TextChannel, category_id: int) -> bool:
async def get_or_fetch_channel(bot: Bot, channel_id: int) -> discord.abc.GuildChannel:
- """Attempt to get or fetch a channel and return it."""
+ """
+ Attempt to get or fetch the given ``channel_id`` from the bots cache, and return it.
+
+ Args:
+ bot: The :obj:`discord.ext.commands.Bot` instance to use for getting/fetching.
+ channel_id: The channel to get/fetch.
+
+ Raises:
+ :exc:`discord.InvalidData`
+ An unknown channel type was received from Discord.
+ :exc:`discord.HTTPException`
+ Retrieving the channel failed.
+ :exc:`discord.NotFound`
+ Invalid Channel ID.
+ :exc:`discord.Forbidden`
+ You do not have permission to fetch this channel.
+
+ Returns:
+ The channel from the ID.
+ """
log.trace(f"Getting the channel {channel_id}.")
channel = bot.get_channel(channel_id)
diff --git a/botcore/utils/logging.py b/botcore/utils/logging.py
index 740c20d4..71ce4e66 100644
--- a/botcore/utils/logging.py
+++ b/botcore/utils/logging.py
@@ -1,4 +1,4 @@
-"""Custom :obj:`logging.Logger` class that implements a new ``"TRACE"`` level."""
+"""Common logging related functions."""
import logging
import typing
diff --git a/botcore/utils/scheduling.py b/botcore/utils/scheduling.py
index e2952e6c..164f6b10 100644
--- a/botcore/utils/scheduling.py
+++ b/botcore/utils/scheduling.py
@@ -14,25 +14,26 @@ class Scheduler:
"""
Schedule the execution of coroutines and keep track of them.
- When instantiating a Scheduler, a name must be provided. This name is used to distinguish the
+ When instantiating a :obj:`Scheduler`, a name must be provided. This name is used to distinguish the
instance's log messages from other instances. Using the name of the class or module containing
the instance is suggested.
- Coroutines can be scheduled immediately with `schedule` or in the future with `schedule_at`
- or `schedule_later`. A unique ID is required to be given in order to keep track of the
- resulting Tasks. Any scheduled task can be cancelled prematurely using `cancel` by providing
- the same ID used to schedule it. The `in` operator is supported for checking if a task with a
- given ID is currently scheduled.
+ Coroutines can be scheduled immediately with :obj:`schedule` or in the future with :obj:`schedule_at`
+ or :obj:`schedule_later`. A unique ID is required to be given in order to keep track of the
+ resulting Tasks. Any scheduled task can be cancelled prematurely using :obj:`cancel` by providing
+ the same ID used to schedule it.
+
+ The ``in`` operator is supported for checking if a task with a given ID is currently scheduled.
Any exception raised in a scheduled task is logged when the task is done.
"""
def __init__(self, name: str):
"""
- Initialize a new Scheduler instance.
+ Initialize a new :obj:`Scheduler` instance.
Args:
- name: The name of the scheduler. Used in logging, and namespacing.
+ name: The name of the :obj:`Scheduler`. Used in logging, and namespacing.
"""
self.name = name
@@ -41,21 +42,21 @@ class Scheduler:
def __contains__(self, task_id: typing.Hashable) -> bool:
"""
- Return True if a task with the given `task_id` is currently scheduled.
+ Return :obj:`True` if a task with the given ``task_id`` is currently scheduled.
Args:
task_id: The task to look for.
Returns:
- True if the task was found.
+ :obj:`True` if the task was found.
"""
return task_id in self._scheduled_tasks
def schedule(self, task_id: typing.Hashable, coroutine: typing.Coroutine) -> None:
"""
- Schedule the execution of a `coroutine`.
+ Schedule the execution of a ``coroutine``.
- If a task with `task_id` already exists, close `coroutine` instead of scheduling it. This
+ If a task with ``task_id`` already exists, close ``coroutine`` instead of scheduling it. This
prevents unawaited coroutine warnings. Don't pass a coroutine that'll be re-used elsewhere.
Args:
@@ -80,14 +81,14 @@ class Scheduler:
def schedule_at(self, time: datetime, task_id: typing.Hashable, coroutine: typing.Coroutine) -> None:
"""
- Schedule `coroutine` to be executed at the given `time`.
+ Schedule ``coroutine`` to be executed at the given ``time``.
- If `time` is timezone aware, then use that timezone to calculate now() when subtracting.
- If `time` is naïve, then use UTC.
+ If ``time`` is timezone aware, then use that timezone to calculate now() when subtracting.
+ If ``time`` is naïve, then use UTC.
- If `time` is in the past, schedule `coroutine` immediately.
+ If ``time`` is in the past, schedule ``coroutine`` immediately.
- If a task with `task_id` already exists, close `coroutine` instead of scheduling it. This
+ If a task with ``task_id`` already exists, close ``coroutine`` instead of scheduling it. This
prevents unawaited coroutine warnings. Don't pass a coroutine that'll be re-used elsewhere.
Args:
@@ -109,9 +110,9 @@ class Scheduler:
coroutine: typing.Coroutine
) -> None:
"""
- Schedule `coroutine` to be executed after `delay` seconds.
+ Schedule ``coroutine`` to be executed after ``delay`` seconds.
- If a task with `task_id` already exists, close `coroutine` instead of scheduling it. This
+ If a task with ``task_id`` already exists, close ``coroutine`` instead of scheduling it. This
prevents unawaited coroutine warnings. Don't pass a coroutine that'll be re-used elsewhere.
Args:
@@ -123,7 +124,7 @@ class Scheduler:
def cancel(self, task_id: typing.Hashable) -> None:
"""
- Unschedule the task identified by `task_id`. Log a warning if the task doesn't exist.
+ Unschedule the task identified by ``task_id``. Log a warning if the task doesn't exist.
Args:
task_id: The task's unique ID.
@@ -152,7 +153,7 @@ class Scheduler:
task_id: typing.Hashable,
coroutine: typing.Coroutine
) -> None:
- """Await `coroutine` after `delay` seconds."""
+ """Await ``coroutine`` after ``delay`` seconds."""
try:
self._log.trace(f"Waiting {delay} seconds before awaiting coroutine for #{task_id}.")
await asyncio.sleep(delay)
@@ -176,7 +177,7 @@ class Scheduler:
"""
Delete the task and raise its exception if one exists.
- If `done_task` and the task associated with `task_id` are different, then the latter
+ If ``done_task`` and the task associated with ``task_id`` are different, then the latter
will not be deleted. In this case, a new task was likely rescheduled with the same ID.
"""
self._log.trace(f"Performing done callback for task #{task_id} {id(done_task)}.")
@@ -217,7 +218,8 @@ def create_task(
"""
Wrapper for creating an :obj:`asyncio.Task` which logs exceptions raised in the task.
- If the loop kwarg is provided, the task is created from that event loop, otherwise the running loop is used.
+ If the ``event_loop`` kwarg is provided, the task is created from that event loop,
+ otherwise the running loop is used.
Args:
coro: The function to call.
@@ -237,7 +239,7 @@ def create_task(
def _log_task_exception(task: asyncio.Task, *, suppressed_exceptions: typing.Tuple[typing.Type[Exception]]) -> None:
- """Retrieve and log the exception raised in `task` if one exists."""
+ """Retrieve and log the exception raised in ``task`` if one exists."""
with contextlib.suppress(asyncio.CancelledError):
exception = task.exception()
# Log the exception if one exists.