diff options
-rw-r--r-- | botcore/utils/caching.py | 2 | ||||
-rw-r--r-- | botcore/utils/channel.py | 23 | ||||
-rw-r--r-- | botcore/utils/logging.py | 2 | ||||
-rw-r--r-- | botcore/utils/scheduling.py | 50 |
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. |