From 9d0cf91e237e7716c618014676a90ed4d780495a Mon Sep 17 00:00:00 2001 From: Hassan Abouelela Date: Sun, 26 Jun 2022 19:22:38 +0400 Subject: Add Typehints To Typing Patcher Signed-off-by: Hassan Abouelela --- botcore/utils/_monkey_patches.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'botcore/utils') diff --git a/botcore/utils/_monkey_patches.py b/botcore/utils/_monkey_patches.py index f2c6c100..c2f8aa10 100644 --- a/botcore/utils/_monkey_patches.py +++ b/botcore/utils/_monkey_patches.py @@ -1,6 +1,7 @@ """Contains all common monkey patches, used to alter discord to fit our needs.""" import logging +import typing from datetime import datetime, timedelta from functools import partial, partialmethod @@ -46,9 +47,9 @@ def _patch_typing() -> None: log.debug("Patching send_typing, which should fix things breaking when Discord disables typing events. Stay safe!") original = http.HTTPClient.send_typing - last_403 = None + last_403: typing.Optional[datetime] = None - async def honeybadger_type(self, channel_id: int) -> None: # noqa: ANN001 + async def honeybadger_type(self: http.HTTPClient, channel_id: int) -> None: nonlocal last_403 if last_403 and (datetime.utcnow() - last_403) < timedelta(minutes=5): log.warning("Not sending typing event, we got a 403 less than 5 minutes ago.") -- cgit v1.2.3 From a9966239af6edc1cd9b6133de41f03d15ceec285 Mon Sep 17 00:00:00 2001 From: Hassan Abouelela Date: Sun, 26 Jun 2022 19:23:14 +0400 Subject: Fix Docstring For Role Change Wrapper Util Signed-off-by: Hassan Abouelela --- botcore/utils/members.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'botcore/utils') diff --git a/botcore/utils/members.py b/botcore/utils/members.py index e89b4618..10513953 100644 --- a/botcore/utils/members.py +++ b/botcore/utils/members.py @@ -1,5 +1,4 @@ """Useful helper functions for interactin with :obj:`discord.Member` objects.""" - import typing import discord @@ -30,18 +29,19 @@ async def get_or_fetch_member(guild: discord.Guild, member_id: int) -> typing.Op async def handle_role_change( member: discord.Member, - coro: typing.Callable[..., typing.Coroutine], + coro: typing.Callable[[discord.Role], typing.Coroutine], role: discord.Role ) -> None: """ - Await the given ``coro`` with ``member`` as the sole argument. + Await the given ``coro`` with ``role`` as the sole argument. Handle errors that we expect to be raised from :obj:`discord.Member.add_roles` and :obj:`discord.Member.remove_roles`. Args: - member: The member to pass to ``coro``. + member: The member that is being modified for logging purposes. coro: This is intended to be :obj:`discord.Member.add_roles` or :obj:`discord.Member.remove_roles`. + role: The role to be passed to ``coro``. """ try: await coro(role) -- cgit v1.2.3 From f17f947006ae55f3baca2eeec7ce804dbfdac238 Mon Sep 17 00:00:00 2001 From: Hassan Abouelela Date: Sun, 26 Jun 2022 19:23:46 +0400 Subject: Fix Incorrect Typehints & Docstrings Signed-off-by: Hassan Abouelela --- botcore/site_api.py | 2 +- botcore/utils/scheduling.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'botcore/utils') diff --git a/botcore/site_api.py b/botcore/site_api.py index dbdf4f3b..d3a58b9c 100644 --- a/botcore/site_api.py +++ b/botcore/site_api.py @@ -26,7 +26,7 @@ class ResponseCodeError(ValueError): Args: response (:obj:`aiohttp.ClientResponse`): The response object from the request. response_json: The JSON response returned from the request, if any. - request_text: The text of the request, if any. + response_text: The text of the request, if any. """ self.status = response.status self.response_json = response_json or {} diff --git a/botcore/utils/scheduling.py b/botcore/utils/scheduling.py index 164f6b10..d9c3937a 100644 --- a/botcore/utils/scheduling.py +++ b/botcore/utils/scheduling.py @@ -209,7 +209,7 @@ class Scheduler: def create_task( - coro: typing.Awaitable, + coro: typing.Coroutine, *, suppressed_exceptions: tuple[typing.Type[Exception]] = (), event_loop: typing.Optional[asyncio.AbstractEventLoop] = None, -- cgit v1.2.3 From ecb9a7e4f6b1ddeecbf0e00af4a149a99b4fa4c9 Mon Sep 17 00:00:00 2001 From: Hassan Abouelela Date: Sun, 26 Jun 2022 21:18:30 +0400 Subject: Document Create Task Return Type Signed-off-by: Hassan Abouelela --- botcore/utils/scheduling.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'botcore/utils') diff --git a/botcore/utils/scheduling.py b/botcore/utils/scheduling.py index d9c3937a..8d2f875e 100644 --- a/botcore/utils/scheduling.py +++ b/botcore/utils/scheduling.py @@ -208,13 +208,16 @@ class Scheduler: self._log.error(f"Error in task #{task_id} {id(done_task)}!", exc_info=exception) +TASK_RETURN = typing.TypeVar("TASK_RETURN") + + def create_task( - coro: typing.Coroutine, + coro: typing.Coroutine[typing.Any, typing.Any, TASK_RETURN], *, suppressed_exceptions: tuple[typing.Type[Exception]] = (), event_loop: typing.Optional[asyncio.AbstractEventLoop] = None, **kwargs, -) -> asyncio.Task: +) -> asyncio.Task[TASK_RETURN]: """ Wrapper for creating an :obj:`asyncio.Task` which logs exceptions raised in the task. -- cgit v1.2.3 From 5efb69b2070ee972dd58401c06c0313513593a38 Mon Sep 17 00:00:00 2001 From: Hassan Abouelela Date: Sun, 26 Jun 2022 21:42:07 +0400 Subject: Replace Typing Generics Replaces all typing generics with collection equivalents as per PEP 585. `typing.Callable` was not included in this due to a sphinx-autodoc bug not handling it well. Signed-off-by: Hassan Abouelela --- botcore/utils/members.py | 3 ++- botcore/utils/scheduling.py | 15 ++++++++------- 2 files changed, 10 insertions(+), 8 deletions(-) (limited to 'botcore/utils') diff --git a/botcore/utils/members.py b/botcore/utils/members.py index 10513953..1536a8d1 100644 --- a/botcore/utils/members.py +++ b/botcore/utils/members.py @@ -1,5 +1,6 @@ """Useful helper functions for interactin with :obj:`discord.Member` objects.""" import typing +from collections import abc import discord @@ -29,7 +30,7 @@ async def get_or_fetch_member(guild: discord.Guild, member_id: int) -> typing.Op async def handle_role_change( member: discord.Member, - coro: typing.Callable[[discord.Role], typing.Coroutine], + coro: typing.Callable[[discord.Role], abc.Coroutine], role: discord.Role ) -> None: """ diff --git a/botcore/utils/scheduling.py b/botcore/utils/scheduling.py index 8d2f875e..8e30d63b 100644 --- a/botcore/utils/scheduling.py +++ b/botcore/utils/scheduling.py @@ -4,6 +4,7 @@ import asyncio import contextlib import inspect import typing +from collections import abc from datetime import datetime from functools import partial @@ -38,7 +39,7 @@ class Scheduler: self.name = name self._log = logging.get_logger(f"{__name__}.{name}") - self._scheduled_tasks: typing.Dict[typing.Hashable, asyncio.Task] = {} + self._scheduled_tasks: dict[typing.Hashable, asyncio.Task] = {} def __contains__(self, task_id: typing.Hashable) -> bool: """ @@ -52,7 +53,7 @@ class Scheduler: """ return task_id in self._scheduled_tasks - def schedule(self, task_id: typing.Hashable, coroutine: typing.Coroutine) -> None: + def schedule(self, task_id: typing.Hashable, coroutine: abc.Coroutine) -> None: """ Schedule the execution of a ``coroutine``. @@ -79,7 +80,7 @@ class Scheduler: self._scheduled_tasks[task_id] = task self._log.debug(f"Scheduled task #{task_id} {id(task)}.") - def schedule_at(self, time: datetime, task_id: typing.Hashable, coroutine: typing.Coroutine) -> None: + def schedule_at(self, time: datetime, task_id: typing.Hashable, coroutine: abc.Coroutine) -> None: """ Schedule ``coroutine`` to be executed at the given ``time``. @@ -107,7 +108,7 @@ class Scheduler: self, delay: typing.Union[int, float], task_id: typing.Hashable, - coroutine: typing.Coroutine + coroutine: abc.Coroutine ) -> None: """ Schedule ``coroutine`` to be executed after ``delay`` seconds. @@ -151,7 +152,7 @@ class Scheduler: self, delay: typing.Union[int, float], task_id: typing.Hashable, - coroutine: typing.Coroutine + coroutine: abc.Coroutine ) -> None: """Await ``coroutine`` after ``delay`` seconds.""" try: @@ -212,7 +213,7 @@ TASK_RETURN = typing.TypeVar("TASK_RETURN") def create_task( - coro: typing.Coroutine[typing.Any, typing.Any, TASK_RETURN], + coro: abc.Coroutine[typing.Any, typing.Any, TASK_RETURN], *, suppressed_exceptions: tuple[typing.Type[Exception]] = (), event_loop: typing.Optional[asyncio.AbstractEventLoop] = None, @@ -241,7 +242,7 @@ def create_task( return task -def _log_task_exception(task: asyncio.Task, *, suppressed_exceptions: typing.Tuple[typing.Type[Exception]]) -> None: +def _log_task_exception(task: asyncio.Task, *, suppressed_exceptions: tuple[type[Exception]]) -> None: """Retrieve and log the exception raised in ``task`` if one exists.""" with contextlib.suppress(asyncio.CancelledError): exception = task.exception() -- cgit v1.2.3 From 7913afabf954426119fe353485bdaaf4074a7e26 Mon Sep 17 00:00:00 2001 From: Hassan Abouelela Date: Wed, 29 Jun 2022 13:38:05 +0400 Subject: Switch `typing.Hashable` With `Collections.abc.Hashable` Switches out the Hashable type from the typing library for the generic from collections. Signed-off-by: Hassan Abouelela --- botcore/utils/scheduling.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'botcore/utils') diff --git a/botcore/utils/scheduling.py b/botcore/utils/scheduling.py index 8e30d63b..ebc42665 100644 --- a/botcore/utils/scheduling.py +++ b/botcore/utils/scheduling.py @@ -39,9 +39,9 @@ class Scheduler: self.name = name self._log = logging.get_logger(f"{__name__}.{name}") - self._scheduled_tasks: dict[typing.Hashable, asyncio.Task] = {} + self._scheduled_tasks: dict[abc.Hashable, asyncio.Task] = {} - def __contains__(self, task_id: typing.Hashable) -> bool: + def __contains__(self, task_id: abc.Hashable) -> bool: """ Return :obj:`True` if a task with the given ``task_id`` is currently scheduled. @@ -53,7 +53,7 @@ class Scheduler: """ return task_id in self._scheduled_tasks - def schedule(self, task_id: typing.Hashable, coroutine: abc.Coroutine) -> None: + def schedule(self, task_id: abc.Hashable, coroutine: abc.Coroutine) -> None: """ Schedule the execution of a ``coroutine``. @@ -80,7 +80,7 @@ class Scheduler: self._scheduled_tasks[task_id] = task self._log.debug(f"Scheduled task #{task_id} {id(task)}.") - def schedule_at(self, time: datetime, task_id: typing.Hashable, coroutine: abc.Coroutine) -> None: + def schedule_at(self, time: datetime, task_id: abc.Hashable, coroutine: abc.Coroutine) -> None: """ Schedule ``coroutine`` to be executed at the given ``time``. @@ -107,7 +107,7 @@ class Scheduler: def schedule_later( self, delay: typing.Union[int, float], - task_id: typing.Hashable, + task_id: abc.Hashable, coroutine: abc.Coroutine ) -> None: """ @@ -123,7 +123,7 @@ class Scheduler: """ self.schedule(task_id, self._await_later(delay, task_id, coroutine)) - def cancel(self, task_id: typing.Hashable) -> None: + def cancel(self, task_id: abc.Hashable) -> None: """ Unschedule the task identified by ``task_id``. Log a warning if the task doesn't exist. @@ -151,7 +151,7 @@ class Scheduler: async def _await_later( self, delay: typing.Union[int, float], - task_id: typing.Hashable, + task_id: abc.Hashable, coroutine: abc.Coroutine ) -> None: """Await ``coroutine`` after ``delay`` seconds.""" @@ -174,7 +174,7 @@ class Scheduler: else: self._log.debug(f"Finally block reached for #{task_id}; {state=}") - def _task_done_callback(self, task_id: typing.Hashable, done_task: asyncio.Task) -> None: + def _task_done_callback(self, task_id: abc.Hashable, done_task: asyncio.Task) -> None: """ Delete the task and raise its exception if one exists. @@ -215,7 +215,7 @@ TASK_RETURN = typing.TypeVar("TASK_RETURN") def create_task( coro: abc.Coroutine[typing.Any, typing.Any, TASK_RETURN], *, - suppressed_exceptions: tuple[typing.Type[Exception]] = (), + suppressed_exceptions: tuple[type[Exception]] = (), event_loop: typing.Optional[asyncio.AbstractEventLoop] = None, **kwargs, ) -> asyncio.Task[TASK_RETURN]: -- cgit v1.2.3