diff options
| -rw-r--r-- | dev/bot/__init__.py | 2 | ||||
| -rw-r--r-- | dev/bot/__main__.py | 3 | ||||
| -rw-r--r-- | dev/bot/cog.py | 2 | ||||
| -rw-r--r-- | docs/conf.py | 8 | ||||
| -rw-r--r-- | docs/netlify_build.py | 4 | ||||
| -rw-r--r-- | docs/utils.py | 17 | ||||
| -rw-r--r-- | pydis_core/__init__.py | 2 | ||||
| -rw-r--r-- | pydis_core/_bot.py | 23 | ||||
| -rw-r--r-- | pydis_core/async_stats.py | 9 | ||||
| -rw-r--r-- | pydis_core/exts/__init__.py | 2 | ||||
| -rw-r--r-- | pydis_core/site_api.py | 19 | ||||
| -rw-r--r-- | pydis_core/utils/__init__.py | 14 | ||||
| -rw-r--r-- | pydis_core/utils/_monkey_patches.py | 11 | ||||
| -rw-r--r-- | pydis_core/utils/commands.py | 3 | ||||
| -rw-r--r-- | pydis_core/utils/cooldown.py | 3 | ||||
| -rw-r--r-- | pydis_core/utils/function.py | 2 | ||||
| -rw-r--r-- | pydis_core/utils/interactions.py | 9 | ||||
| -rw-r--r-- | pydis_core/utils/logging.py | 2 | ||||
| -rw-r--r-- | pydis_core/utils/members.py | 2 | ||||
| -rw-r--r-- | pydis_core/utils/scheduling.py | 13 | ||||
| -rw-r--r-- | tests/pydis_core/test_api.py | 8 | ||||
| -rw-r--r-- | tests/pydis_core/utils/test_regex.py | 5 | 
22 files changed, 75 insertions, 88 deletions
diff --git a/dev/bot/__init__.py b/dev/bot/__init__.py index 6ee1ae47..1c43b1a8 100644 --- a/dev/bot/__init__.py +++ b/dev/bot/__init__.py @@ -21,4 +21,4 @@ class Bot(pydis_core.BotBase):      async def setup_hook(self) -> None:          """Load extensions on startup."""          await super().setup_hook() -        asyncio.create_task(self.load_extensions(sys.modules[__name__])) +        await self.load_extensions(sys.modules[__name__]) diff --git a/dev/bot/__main__.py b/dev/bot/__main__.py index e28be36b..ea74649c 100644 --- a/dev/bot/__main__.py +++ b/dev/bot/__main__.py @@ -7,6 +7,7 @@ import dotenv  from discord.ext import commands  import pydis_core +  from . import Bot  dotenv.load_dotenv() @@ -17,7 +18,7 @@ roles = [int(role) for role in roles.split(",")] if roles else []  bot = Bot(      guild_id=int(os.getenv("GUILD_ID")), -    http_session=None,  # type: ignore # We need to instantiate the session in an async context +    http_session=None,  # type: ignore We need to instantiate the session in an async context      allowed_roles=roles,      command_prefix=commands.when_mentioned_or(os.getenv("PREFIX", "!")),      intents=discord.Intents.all(), diff --git a/dev/bot/cog.py b/dev/bot/cog.py index 7746c54e..0da950f9 100644 --- a/dev/bot/cog.py +++ b/dev/bot/cog.py @@ -12,7 +12,7 @@ class Cog(commands.Cog):      @commands.Cog.listener()      async def on_ready(self) -> None:          """Print a message when the client (re)connects.""" -        print("Client is ready.") +        print("Client is ready.")  # noqa: T201      @commands.command()      async def reload(self, ctx: commands.Context) -> None: diff --git a/docs/conf.py b/docs/conf.py index 2fea7264..23636774 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,6 +1,7 @@  # Configuration file for the Sphinx documentation builder.  # https://www.sphinx-doc.org/en/master/usage/configuration.html +import contextlib  import functools  import os.path  import shutil @@ -16,7 +17,7 @@ from sphinx.application import Sphinx  logger = sphinx.util.logging.getLogger(__name__)  # Handle the path not being set correctly in actions. -sys.path.insert(0, os.path.abspath('..')) +sys.path.insert(0, os.path.abspath(".."))  from docs import utils  # noqa: E402 @@ -209,10 +210,9 @@ smv_latest_version = "main"  smv_branch_whitelist = "main"  if os.getenv("BUILD_DOCS_FOR_HEAD", "False").lower() == "true":      if not (branch := os.getenv("BRANCH_NAME")): -        try: +        with contextlib.suppress(git.InvalidGitRepositoryError):              branch = git.Repo(PROJECT_ROOT).active_branch.name -        except git.InvalidGitRepositoryError: -            pass +      if branch:          logger.info(f"Adding branch {branch} to build whitelist.") diff --git a/docs/netlify_build.py b/docs/netlify_build.py index 1704eece..a6da74df 100644 --- a/docs/netlify_build.py +++ b/docs/netlify_build.py @@ -22,5 +22,5 @@ OUTPUT.write_text(build_script.text, encoding="utf-8")  if __name__ == "__main__":      # Run the build script -    print("Build started") -    subprocess.run([sys.executable, OUTPUT.absolute()]) +    print("Build started")  # noqa: T201 +    subprocess.run([sys.executable, OUTPUT.absolute()])  # noqa: S603 diff --git a/docs/utils.py b/docs/utils.py index 3f58e767..3a20b87f 100644 --- a/docs/utils.py +++ b/docs/utils.py @@ -30,16 +30,15 @@ def get_build_root() -> Path:  def is_attribute(module: types.ModuleType, parameter: str) -> bool:      """Returns true if `parameter` is an attribute of `module`."""      docs = docstring_parser.parse(inspect.getdoc(module), docstring_parser.DocstringStyle.GOOGLE) -    for param in docs.params: +    for param in docs.params:  # noqa: SIM110          # The docstring_parser library can mis-parse arguments like `arg (:obj:`str`)` as `arg (`          # which would create a false-negative below, so we just strip away the extra parenthesis.          if param.args[0] == "attribute" and param.arg_name.rstrip(" (") == parameter:              return True -      return False -def linkcode_resolve(repo_link: str, domain: str, info: dict[str, str]) -> typing.Optional[str]: +def linkcode_resolve(repo_link: str, domain: str, info: dict[str, str]) -> str | None:      """      Function called by linkcode to get the URL for a given resource. @@ -79,8 +78,7 @@ def linkcode_resolve(repo_link: str, domain: str, info: dict[str, str]) -> typin              # This could be caused by trying to link a class attribute              if is_attribute(symbol[-1], name):                  break -            else: -                raise e +            raise e          symbol_name = name @@ -97,8 +95,8 @@ def linkcode_resolve(repo_link: str, domain: str, info: dict[str, str]) -> typin          pos = _global_assign_pos(source, symbol_name)          if pos is None:              raise Exception(f"Could not find symbol `{symbol_name}` in {module.__name__}.") -        else: -            start, end = pos + +        start, end = pos          _, offset = inspect.getsourcelines(symbol[-2])          if offset != 0:              offset -= 1 @@ -126,7 +124,7 @@ class NodeWithBody(typing.Protocol):      body: list[ast.AST] -def _global_assign_pos(ast_: NodeWithBody, name: str) -> typing.Union[tuple[int, int], None]: +def _global_assign_pos(ast_: NodeWithBody, name: str) -> tuple[int, int] | None:      """      Find the first instance where the `name` global is defined in `ast_`. @@ -149,6 +147,7 @@ def _global_assign_pos(ast_: NodeWithBody, name: str) -> typing.Union[tuple[int,              pos_in_if = _global_assign_pos(ast_obj, name)              if pos_in_if is not None:                  return pos_in_if +    return None  def cleanup() -> None: @@ -200,7 +199,7 @@ def build_api_doc() -> None:          logger.info(f"Skipping api-doc for {output_folder.as_posix()} as it already exists.")          return -    result = subprocess.run(cmd, cwd=build_root, stdout=subprocess.PIPE, check=True, env=os.environ) +    result = subprocess.run(cmd, cwd=build_root, stdout=subprocess.PIPE, check=True, env=os.environ)  # noqa: S603      logger.debug("api-doc Output:\n" + result.stdout.decode(encoding="utf-8") + "\n")      cleanup() diff --git a/pydis_core/__init__.py b/pydis_core/__init__.py index a09feeaa..94f4ac10 100644 --- a/pydis_core/__init__.py +++ b/pydis_core/__init__.py @@ -12,4 +12,4 @@ __all__ = [      StartupError,  ] -__all__ = list(map(lambda module: module.__name__, __all__)) +__all__ = [module.__name__ for module in __all__] diff --git a/pydis_core/_bot.py b/pydis_core/_bot.py index b45647f3..57336460 100644 --- a/pydis_core/_bot.py +++ b/pydis_core/_bot.py @@ -3,7 +3,6 @@ import socket  import types  import warnings  from contextlib import suppress -from typing import Optional  import aiohttp  import discord @@ -19,7 +18,7 @@ try:      from async_rediscache import RedisSession      REDIS_AVAILABLE = True  except ImportError: -    RedisSession = None +    RedisSession = object      REDIS_AVAILABLE = False  log = get_logger() @@ -42,9 +41,9 @@ class BotBase(commands.Bot):          guild_id: int,          allowed_roles: list,          http_session: aiohttp.ClientSession, -        redis_session: Optional[RedisSession] = None, -        api_client: Optional[APIClient] = None, -        statsd_url: Optional[str] = None, +        redis_session: RedisSession | None = None, +        api_client: APIClient | None = None, +        statsd_url: str | None = None,          **kwargs,      ):          """ @@ -77,16 +76,16 @@ class BotBase(commands.Bot):          elif redis_session:              self.redis_session = redis_session -        self._resolver: Optional[aiohttp.AsyncResolver] = None -        self._connector: Optional[aiohttp.TCPConnector] = None +        self._resolver: aiohttp.AsyncResolver | None = None +        self._connector: aiohttp.TCPConnector | None = None -        self._statsd_timerhandle: Optional[asyncio.TimerHandle] = None -        self._guild_available: Optional[asyncio.Event] = None +        self._statsd_timerhandle: asyncio.TimerHandle | None = None +        self._guild_available: asyncio.Event | None = None          self._extension_loading_task: asyncio.Task | None = None -        self.stats: Optional[AsyncStatsClient] = None +        self.stats: AsyncStatsClient | None = None -        self.all_extensions: Optional[frozenset[str]] = None +        self.all_extensions: frozenset[str] | None = None      def _connect_statsd(          self, @@ -176,7 +175,7 @@ class BotBase(commands.Bot):          super().add_command(command)          self._add_root_aliases(command) -    def remove_command(self, name: str) -> Optional[commands.Command]: +    def remove_command(self, name: str) -> commands.Command | None:          """          Remove a command/alias as normal and then remove its root aliases from the bot. diff --git a/pydis_core/async_stats.py b/pydis_core/async_stats.py index 411325e3..ae409467 100644 --- a/pydis_core/async_stats.py +++ b/pydis_core/async_stats.py @@ -2,7 +2,6 @@  import asyncio  import socket -from typing import Optional  from statsd.client.base import StatsClientBase @@ -15,7 +14,7 @@ class AsyncStatsClient(StatsClientBase):      def __init__(          self,          loop: asyncio.AbstractEventLoop, -        host: str = 'localhost', +        host: str = "localhost",          port: int = 8125,          prefix: str = None      ): @@ -35,7 +34,7 @@ class AsyncStatsClient(StatsClientBase):          self._addr = addr          self._prefix = prefix          self._loop = loop -        self._transport: Optional[asyncio.DatagramTransport] = None +        self._transport: asyncio.DatagramTransport | None = None      async def create_socket(self) -> None:          """Use :obj:`asyncio.loop.create_datagram_endpoint` from the loop given on init to create a socket.""" @@ -51,7 +50,7 @@ class AsyncStatsClient(StatsClientBase):      async def _async_send(self, data: str) -> None:          """Send data to the statsd server using the async transport.""" -        self._transport.sendto(data.encode('ascii'), self._addr) +        self._transport.sendto(data.encode("ascii"), self._addr) -__all__ = ['AsyncStatsClient'] +__all__ = ["AsyncStatsClient"] diff --git a/pydis_core/exts/__init__.py b/pydis_core/exts/__init__.py index afd56166..9d59e8ad 100644 --- a/pydis_core/exts/__init__.py +++ b/pydis_core/exts/__init__.py @@ -1,4 +1,4 @@  """Reusable Discord cogs."""  __all__ = [] -__all__ = list(map(lambda module: module.__name__, __all__)) +__all__ = [module.__name__ for module in __all__] diff --git a/pydis_core/site_api.py b/pydis_core/site_api.py index c17d2642..80eeff2b 100644 --- a/pydis_core/site_api.py +++ b/pydis_core/site_api.py @@ -1,7 +1,6 @@  """An API wrapper around the Site API."""  import asyncio -from typing import Optional  from urllib.parse import quote as quote_url  import aiohttp @@ -17,8 +16,8 @@ class ResponseCodeError(ValueError):      def __init__(          self,          response: aiohttp.ClientResponse, -        response_json: Optional[dict] = None, -        response_text: Optional[str] = None +        response_json: dict | None = None, +        response_text: str | None = None      ):          """          Initialize a new :obj:`ResponseCodeError` instance. @@ -42,7 +41,7 @@ class ResponseCodeError(ValueError):  class APIClient:      """A wrapper for the Django Site API.""" -    session: Optional[aiohttp.ClientSession] = None +    session: aiohttp.ClientSession | None = None      loop: asyncio.AbstractEventLoop = None      def __init__(self, site_api_url: str, site_api_token: str, **session_kwargs): @@ -57,13 +56,13 @@ class APIClient:          self.site_api_url = site_api_url          auth_headers = { -            'Authorization': f"Token {site_api_token}" +            "Authorization": f"Token {site_api_token}"          } -        if 'headers' in session_kwargs: -            session_kwargs['headers'].update(auth_headers) +        if "headers" in session_kwargs: +            session_kwargs["headers"].update(auth_headers)          else: -            session_kwargs['headers'] = auth_headers +            session_kwargs["headers"] = auth_headers          # aiohttp will complain if APIClient gets instantiated outside a coroutine. Thankfully, we          # don't and shouldn't need to do that, so we can avoid scheduling a task to create it. @@ -134,7 +133,7 @@ class APIClient:          """Equivalent to :meth:`APIClient.request` with PUT passed as the method."""          return await self.request("PUT", endpoint, raise_for_status=raise_for_status, **kwargs) -    async def delete(self, endpoint: str, *, raise_for_status: bool = True, **kwargs) -> Optional[dict]: +    async def delete(self, endpoint: str, *, raise_for_status: bool = True, **kwargs) -> dict | None:          """          Send a DELETE request to the site API and return the JSON response. @@ -154,4 +153,4 @@ class APIClient:              return await resp.json() -__all__ = ['APIClient', 'ResponseCodeError'] +__all__ = ["APIClient", "ResponseCodeError"] diff --git a/pydis_core/utils/__init__.py b/pydis_core/utils/__init__.py index 0542231e..8a61082a 100644 --- a/pydis_core/utils/__init__.py +++ b/pydis_core/utils/__init__.py @@ -1,17 +1,7 @@  """Useful utilities and tools for Discord bot development."""  from pydis_core.utils import ( -    _monkey_patches, -    caching, -    channel, -    commands, -    cooldown, -    function, -    interactions, -    logging, -    members, -    regex, -    scheduling, +    _monkey_patches, caching, channel, commands, cooldown, function, interactions, logging, members, regex, scheduling  )  from pydis_core.utils._extensions import unqualify @@ -47,4 +37,4 @@ __all__ = [      unqualify,  ] -__all__ = list(map(lambda module: module.__name__, __all__)) +__all__ = [module.__name__ for module in __all__] diff --git a/pydis_core/utils/_monkey_patches.py b/pydis_core/utils/_monkey_patches.py index f0a8dc9c..2df56039 100644 --- a/pydis_core/utils/_monkey_patches.py +++ b/pydis_core/utils/_monkey_patches.py @@ -1,8 +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 datetime import datetime, timedelta, timezone  from functools import partial, partialmethod  from discord import Forbidden, http @@ -24,7 +23,7 @@ class _Command(commands.Command):          super().__init__(*args, **kwargs)          self.root_aliases = kwargs.get("root_aliases", []) -        if not isinstance(self.root_aliases, (list, tuple)): +        if not isinstance(self.root_aliases, list | tuple):              raise TypeError("Root aliases of a command must be a list or a tuple of strings.") @@ -47,17 +46,17 @@ 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: typing.Optional[datetime] = None +    last_403: datetime | None = None      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): +        if last_403 and (datetime.now(tz=timezone.utc) - last_403) < timedelta(minutes=5):              log.warning("Not sending typing event, we got a 403 less than 5 minutes ago.")              return          try:              await original(self, channel_id)          except Forbidden: -            last_403 = datetime.utcnow() +            last_403 = datetime.now(tz=timezone.utc)              log.warning("Got a 403 from typing event!")      http.HTTPClient.send_typing = honeybadger_type diff --git a/pydis_core/utils/commands.py b/pydis_core/utils/commands.py index 7afd8137..2bc5b668 100644 --- a/pydis_core/utils/commands.py +++ b/pydis_core/utils/commands.py @@ -1,10 +1,9 @@ -from typing import Optional  from discord import Message  from discord.ext.commands import BadArgument, Context, clean_content -async def clean_text_or_reply(ctx: Context, text: Optional[str] = None) -> str: +async def clean_text_or_reply(ctx: Context, text: str | None = None) -> str:      """      Cleans a text argument or replied message's content. diff --git a/pydis_core/utils/cooldown.py b/pydis_core/utils/cooldown.py index 5129befd..0fe7102a 100644 --- a/pydis_core/utils/cooldown.py +++ b/pydis_core/utils/cooldown.py @@ -26,6 +26,7 @@ _HashableArgsTuple = tuple[Hashable, ...]  if typing.TYPE_CHECKING:      import typing_extensions +      from pydis_core import BotBase  P = typing.ParamSpec("P") @@ -34,7 +35,7 @@ R = typing.TypeVar("R")  """The command's return value.""" -class CommandOnCooldown(CommandError, typing.Generic[P, R]): +class CommandOnCooldown(CommandError, typing.Generic[P, R]):  # noqa: N818      """Raised when a command is invoked while on cooldown."""      def __init__( diff --git a/pydis_core/utils/function.py b/pydis_core/utils/function.py index d89163ec..98737af0 100644 --- a/pydis_core/utils/function.py +++ b/pydis_core/utils/function.py @@ -99,7 +99,7 @@ def command_wraps(      Returns:          A decorator that behaves like :func:`functools.wraps`,          with the wrapper replaced with the function :func:`update_wrapper_globals` returned. -    """  # noqa: D200 +    """      def decorator(wrapper: Callable[_P, _R]) -> Callable[_P, _R]:          return functools.update_wrapper(              update_wrapper_globals(wrapper, wrapped, ignored_conflict_names=ignored_conflict_names), diff --git a/pydis_core/utils/interactions.py b/pydis_core/utils/interactions.py index a6746e1e..6e419342 100644 --- a/pydis_core/utils/interactions.py +++ b/pydis_core/utils/interactions.py @@ -1,4 +1,5 @@ -from typing import Literal, Optional, Sequence +from collections.abc import Sequence +from typing import Literal  from discord import ButtonStyle, HTTPException, Interaction, Message, NotFound, ui @@ -43,8 +44,8 @@ class ViewWithUserAndRoleCheck(ui.View):          *,          allowed_users: Sequence[int],          allowed_roles: Sequence[int], -        timeout: Optional[float] = 180.0, -        message: Optional[Message] = None +        timeout: float | None = 180.0, +        message: Message | None = None      ) -> None:          super().__init__(timeout=timeout)          self.allowed_users = allowed_users @@ -97,7 +98,7 @@ class DeleteMessageButton(ui.Button):          style (:literal-url:`ButtonStyle <https://discordpy.readthedocs.io/en/latest/interactions/api.html#discord.ButtonStyle>`):              The style of the button, set to ``ButtonStyle.secondary`` if not specified.          label: The label of the button, set to "Delete" if not specified. -    """  # noqa: E501 +    """      def __init__(          self, diff --git a/pydis_core/utils/logging.py b/pydis_core/utils/logging.py index 7814f348..ecccb91a 100644 --- a/pydis_core/utils/logging.py +++ b/pydis_core/utils/logging.py @@ -32,7 +32,7 @@ class CustomLogger(LoggerClass):              self.log(TRACE_LEVEL, msg, *args, **kwargs) -def get_logger(name: typing.Optional[str] = None) -> CustomLogger: +def get_logger(name: str | None = None) -> CustomLogger:      """      Utility to make mypy recognise that logger is of type :obj:`CustomLogger`. diff --git a/pydis_core/utils/members.py b/pydis_core/utils/members.py index fa8481cc..542f945f 100644 --- a/pydis_core/utils/members.py +++ b/pydis_core/utils/members.py @@ -9,7 +9,7 @@ from pydis_core.utils import logging  log = logging.get_logger(__name__) -async def get_or_fetch_member(guild: discord.Guild, member_id: int) -> typing.Optional[discord.Member]: +async def get_or_fetch_member(guild: discord.Guild, member_id: int) -> discord.Member | None:      """      Attempt to get a member from cache; on failure fetch from the API. diff --git a/pydis_core/utils/scheduling.py b/pydis_core/utils/scheduling.py index d4458bc1..1e2e25e7 100644 --- a/pydis_core/utils/scheduling.py +++ b/pydis_core/utils/scheduling.py @@ -5,7 +5,7 @@ import contextlib  import inspect  import typing  from collections import abc -from datetime import datetime +from datetime import datetime, timezone  from functools import partial  from pydis_core.utils import logging @@ -69,7 +69,8 @@ class Scheduler:          self._log.trace(f"Scheduling task #{task_id}...")          msg = f"Cannot schedule an already started coroutine for #{task_id}" -        assert inspect.getcoroutinestate(coroutine) == "CORO_CREATED", msg +        if inspect.getcoroutinestate(coroutine) != "CORO_CREATED": +            raise ValueError(msg)          if task_id in self._scheduled_tasks:              self._log.debug(f"Did not schedule task #{task_id}; task was already scheduled.") @@ -99,7 +100,7 @@ class Scheduler:              task_id: A unique ID to create the task with.              coroutine: The function to be called.          """ -        now_datetime = datetime.now(time.tzinfo) if time.tzinfo else datetime.utcnow() +        now_datetime = datetime.now(time.tzinfo) if time.tzinfo else datetime.now(tz=timezone.utc)          delay = (time - now_datetime).total_seconds()          if delay > 0:              coroutine = self._await_later(delay, task_id, coroutine) @@ -108,7 +109,7 @@ class Scheduler:      def schedule_later(          self, -        delay: typing.Union[int, float], +        delay: int | float,          task_id: abc.Hashable,          coroutine: abc.Coroutine      ) -> None: @@ -152,7 +153,7 @@ class Scheduler:      async def _await_later(          self, -        delay: typing.Union[int, float], +        delay: int | float,          task_id: abc.Hashable,          coroutine: abc.Coroutine      ) -> None: @@ -218,7 +219,7 @@ def create_task(      coro: abc.Coroutine[typing.Any, typing.Any, TASK_RETURN],      *,      suppressed_exceptions: tuple[type[Exception], ...] = (), -    event_loop: typing.Optional[asyncio.AbstractEventLoop] = None, +    event_loop: asyncio.AbstractEventLoop | None = None,      **kwargs,  ) -> asyncio.Task[TASK_RETURN]:      """ diff --git a/tests/pydis_core/test_api.py b/tests/pydis_core/test_api.py index 92444e19..56977f07 100644 --- a/tests/pydis_core/test_api.py +++ b/tests/pydis_core/test_api.py @@ -32,7 +32,7 @@ class APIClientTests(unittest.IsolatedAsyncioTestCase):      def test_response_code_error_initialization_with_json(self):          """Test the initialization of `ResponseCodeError` with json.""" -        json_data = {'hello': 'world'} +        json_data = {"hello": "world"}          error = site_api.ResponseCodeError(              response=self.error_api_response,              response_json=json_data, @@ -42,7 +42,7 @@ class APIClientTests(unittest.IsolatedAsyncioTestCase):      def test_response_code_error_string_representation_with_nonempty_response_json(self):          """Test the string representation of `ResponseCodeError` initialized with json.""" -        json_data = {'hello': 'world'} +        json_data = {"hello": "world"}          error = site_api.ResponseCodeError(              response=self.error_api_response,              response_json=json_data @@ -51,7 +51,7 @@ class APIClientTests(unittest.IsolatedAsyncioTestCase):      def test_response_code_error_initialization_with_text(self):          """Test the initialization of `ResponseCodeError` with text.""" -        text_data = 'Lemon will eat your soul' +        text_data = "Lemon will eat your soul"          error = site_api.ResponseCodeError(              response=self.error_api_response,              response_text=text_data, @@ -61,7 +61,7 @@ class APIClientTests(unittest.IsolatedAsyncioTestCase):      def test_response_code_error_string_representation_with_nonempty_response_text(self):          """Test the string representation of `ResponseCodeError` initialized with text.""" -        text_data = 'Lemon will eat your soul' +        text_data = "Lemon will eat your soul"          error = site_api.ResponseCodeError(              response=self.error_api_response,              response_text=text_data diff --git a/tests/pydis_core/utils/test_regex.py b/tests/pydis_core/utils/test_regex.py index 01a2412b..1cf90711 100644 --- a/tests/pydis_core/utils/test_regex.py +++ b/tests/pydis_core/utils/test_regex.py @@ -1,10 +1,9 @@  import unittest -from typing import Optional  from pydis_core.utils.regex import DISCORD_INVITE -def match_regex(s: str) -> Optional[str]: +def match_regex(s: str) -> str | None:      """Helper function to run re.match on a string.      Return the invite capture group, if the string matches the pattern @@ -14,7 +13,7 @@ def match_regex(s: str) -> Optional[str]:      return result if result is None else result.group("invite") -def search_regex(s: str) -> Optional[str]: +def search_regex(s: str) -> str | None:      """Helper function to run re.search on a string.      Return the invite capture group, if the string matches the pattern  |