aboutsummaryrefslogtreecommitdiffstats
path: root/bot/exts/core
diff options
context:
space:
mode:
authorGravatar ChrisJL <[email protected]>2023-05-09 16:01:01 +0100
committerGravatar GitHub <[email protected]>2023-05-09 16:01:01 +0100
commitc3e23e60278d34658f801bd7d7ed721d5a272637 (patch)
treee159a0fae7850d706d713cf2b49dfed2140ce655 /bot/exts/core
parentBump sentry-sdk from 1.21.1 to 1.22.1 (#1273) (diff)
parentMove unshared contants inside modules (diff)
Merge pull request #1270 from python-discord/migrate-to-ruff
Migrate to ruff
Diffstat (limited to 'bot/exts/core')
-rw-r--r--bot/exts/core/error_handler.py10
-rw-r--r--bot/exts/core/extensions.py16
-rw-r--r--bot/exts/core/help.py27
-rw-r--r--bot/exts/core/internal_eval/_helpers.py10
-rw-r--r--bot/exts/core/internal_eval/_internal_eval.py3
-rw-r--r--bot/exts/core/source.py18
6 files changed, 41 insertions, 43 deletions
diff --git a/bot/exts/core/error_handler.py b/bot/exts/core/error_handler.py
index 04ab55d7..62dee53c 100644
--- a/bot/exts/core/error_handler.py
+++ b/bot/exts/core/error_handler.py
@@ -2,14 +2,13 @@ import logging
import math
import random
from collections.abc import Iterable
-from typing import Union
from discord import Embed, Message
from discord.ext import commands
from sentry_sdk import push_scope
from bot.bot import Bot
-from bot.constants import Channels, Colours, ERROR_REPLIES, NEGATIVE_REPLIES, RedirectOutput
+from bot.constants import Channels, Colours, ERROR_REPLIES, NEGATIVE_REPLIES
from bot.utils.commands import get_command_suggestions
from bot.utils.decorators import InChannelCheckFailure, InMonthCheckFailure
from bot.utils.exceptions import APIError, MovedCommandError, UserNotPlayingError
@@ -17,6 +16,7 @@ from bot.utils.exceptions import APIError, MovedCommandError, UserNotPlayingErro
log = logging.getLogger(__name__)
+DELETE_DELAY = 10
QUESTION_MARK_ICON = "https://cdn.discordapp.com/emojis/512367613339369475.png"
@@ -35,7 +35,7 @@ class CommandErrorHandler(commands.Cog):
logging.debug("Cooldown counter reverted as the command was not used correctly.")
@staticmethod
- def error_embed(message: str, title: Union[Iterable, str] = ERROR_REPLIES) -> Embed:
+ def error_embed(message: str, title: Iterable | str = ERROR_REPLIES) -> Embed:
"""Build a basic embed with red colour and either a random error title or a title provided."""
embed = Embed(colour=Colours.soft_red)
if isinstance(title, str):
@@ -71,7 +71,7 @@ class CommandErrorHandler(commands.Cog):
await self.send_command_suggestion(ctx, ctx.invoked_with)
return
- if isinstance(error, (InChannelCheckFailure, InMonthCheckFailure)):
+ if isinstance(error, InChannelCheckFailure | InMonthCheckFailure):
await ctx.send(embed=self.error_embed(str(error), NEGATIVE_REPLIES), delete_after=7.5)
return
@@ -185,7 +185,7 @@ class CommandErrorHandler(commands.Cog):
e.description = "\n".join(
misspelled_content.replace(command_name, cmd, 1) for cmd in command_suggestions
)
- await ctx.send(embed=e, delete_after=RedirectOutput.delete_delay)
+ await ctx.send(embed=e, delete_after=DELETE_DELAY)
async def setup(bot: Bot) -> None:
diff --git a/bot/exts/core/extensions.py b/bot/exts/core/extensions.py
index 1d22cf37..87ef2ed1 100644
--- a/bot/exts/core/extensions.py
+++ b/bot/exts/core/extensions.py
@@ -2,7 +2,6 @@ import functools
import logging
from collections.abc import Mapping
from enum import Enum
-from typing import Optional
from discord import Colour, Embed
from discord.ext import commands
@@ -48,7 +47,7 @@ class Extension(commands.Converter):
if argument in ctx.bot.all_extensions:
return argument
- elif (qualified_arg := f"{exts.__name__}.{argument}") in ctx.bot.all_extensions:
+ if (qualified_arg := f"{exts.__name__}.{argument}") in ctx.bot.all_extensions:
return qualified_arg
matches = []
@@ -63,10 +62,9 @@ class Extension(commands.Converter):
f":x: `{argument}` is an ambiguous extension name. "
f"Please use one of the following fully-qualified names.```\n{names}\n```"
)
- elif matches:
+ if matches:
return matches[0]
- else:
- raise commands.BadArgument(f":x: Could not find the extension `{argument}`.")
+ raise commands.BadArgument(f":x: Could not find the extension `{argument}`.")
class Extensions(commands.Cog):
@@ -86,7 +84,7 @@ class Extensions(commands.Cog):
Load extensions given their fully qualified or unqualified names.
If '\*' or '\*\*' is given as the name, all unloaded extensions will be loaded.
- """ # noqa: W605
+ """
if not extensions:
await self.bot.invoke_help_command(ctx)
return
@@ -103,7 +101,7 @@ class Extensions(commands.Cog):
Unload currently loaded extensions given their fully qualified or unqualified names.
If '\*' or '\*\*' is given as the name, all loaded extensions will be unloaded.
- """ # noqa: W605
+ """
if not extensions:
await self.bot.invoke_help_command(ctx)
return
@@ -129,7 +127,7 @@ class Extensions(commands.Cog):
If '\*' is given as the name, all currently loaded extensions will be reloaded.
If '\*\*' is given as the name, all extensions, including unloaded ones, will be reloaded.
- """ # noqa: W605
+ """
if not extensions:
await self.bot.invoke_help_command(ctx)
return
@@ -220,7 +218,7 @@ class Extensions(commands.Cog):
return msg
- async def manage(self, action: Action, ext: str) -> tuple[str, Optional[str]]:
+ async def manage(self, action: Action, ext: str) -> tuple[str, str | None]:
"""Apply an action to an extension and return the status message and any error message."""
verb = action.name.lower()
error_msg = None
diff --git a/bot/exts/core/help.py b/bot/exts/core/help.py
index f86eb636..9f96a333 100644
--- a/bot/exts/core/help.py
+++ b/bot/exts/core/help.py
@@ -3,7 +3,7 @@ import asyncio
import itertools
import logging
from contextlib import suppress
-from typing import NamedTuple, Optional, Union
+from typing import NamedTuple
from discord import Colour, Embed, HTTPException, Message, Reaction, User
from discord.ext import commands
@@ -38,7 +38,7 @@ class Cog(NamedTuple):
log = logging.getLogger(__name__)
-class HelpQueryNotFound(ValueError):
+class HelpQueryNotFoundError(ValueError):
"""
Raised when a HelpSession Query doesn't match a command or cog.
@@ -49,7 +49,7 @@ class HelpQueryNotFound(ValueError):
"""
def __init__(
- self, arg: str, possible_matches: Optional[list[str]] = None, *, parent_command: Optional[Command] = None
+ self, arg: str, possible_matches: list[str] | None = None, *, parent_command: Command | None = None
) -> None:
super().__init__(arg)
self.possible_matches = possible_matches
@@ -117,7 +117,7 @@ class HelpSession:
self._timeout_task = None
self.reset_timeout()
- def _get_query(self, query: str) -> Union[Command, Cog]:
+ def _get_query(self, query: str) -> Command | Cog | None:
"""Attempts to match the provided query with a valid command or cog."""
command = self._bot.get_command(query)
if command:
@@ -151,6 +151,7 @@ class HelpSession:
)
self._handle_not_found(query)
+ return None
def _handle_not_found(self, query: str) -> None:
"""
@@ -164,11 +165,11 @@ class HelpSession:
parent_command = self._bot.get_command(parent)
if parent_command:
- raise HelpQueryNotFound('Invalid Subcommand.', parent_command=parent_command)
+ raise HelpQueryNotFoundError("Invalid Subcommand.", parent_command=parent_command)
similar_commands = get_command_suggestions(list(self._bot.all_commands.keys()), query)
- raise HelpQueryNotFound(f'Query "{query}" not found.', similar_commands)
+ raise HelpQueryNotFoundError(f'Query "{query}" not found.', similar_commands)
async def timeout(self, seconds: int = 30) -> None:
"""Waits for a set number of seconds, then stops the help session."""
@@ -178,9 +179,8 @@ class HelpSession:
def reset_timeout(self) -> None:
"""Cancels the original timeout task and sets it again from the start."""
# cancel original if it exists
- if self._timeout_task:
- if not self._timeout_task.cancelled():
- self._timeout_task.cancel()
+ if self._timeout_task and not self._timeout_task.cancelled():
+ self._timeout_task.cancel()
# recreate the timeout task
self._timeout_task = self._bot.loop.create_task(self.timeout())
@@ -252,8 +252,7 @@ class HelpSession:
pass
return f"**{cmd.cog_name}**"
- else:
- return "**\u200bNo Category:**"
+ return "**\u200bNo Category:**"
def _get_command_params(self, cmd: Command) -> str:
"""
@@ -304,7 +303,7 @@ class HelpSession:
paginator.add_line(f"*{self.description}*")
# list all children commands of the queried object
- if isinstance(self.query, (commands.GroupMixin, Cog)):
+ if isinstance(self.query, commands.GroupMixin | Cog):
await self._list_child_commands(paginator)
self._pages = paginator.pages
@@ -417,7 +416,7 @@ class HelpSession:
"""Returns an Embed with the requested page formatted within."""
embed = Embed()
- if isinstance(self.query, (commands.Command, Cog)) and page_number > 0:
+ if isinstance(self.query, commands.Command | Cog) and page_number > 0:
title = f'Command Help | "{self.query.name}"'
else:
title = self.title
@@ -517,7 +516,7 @@ class Help(DiscordCog):
"""Shows Command Help."""
try:
await HelpSession.start(ctx, *commands)
- except HelpQueryNotFound as error:
+ except HelpQueryNotFoundError as error:
# Send help message of parent command if subcommand is invalid.
if cmd := error.parent_command:
diff --git a/bot/exts/core/internal_eval/_helpers.py b/bot/exts/core/internal_eval/_helpers.py
index 5b2f8f5d..34ef7fef 100644
--- a/bot/exts/core/internal_eval/_helpers.py
+++ b/bot/exts/core/internal_eval/_helpers.py
@@ -8,7 +8,7 @@ import logging
import sys
import traceback
import types
-from typing import Any, Optional, Union
+from typing import Any
log = logging.getLogger(__name__)
@@ -120,7 +120,7 @@ class EvalContext:
log.trace(f"Updating {self._locals} with {locals_}")
self._locals.update(locals_)
- def prepare_eval(self, code: str) -> Optional[str]:
+ def prepare_eval(self, code: str) -> str | None:
"""Prepare an evaluation by processing the code and setting up the context."""
self.code = code
@@ -149,7 +149,7 @@ class EvalContext:
compiled_code = compile(self.eval_tree, filename=INTERNAL_EVAL_FRAMENAME, mode="exec")
log.trace("Executing the compiled code with the desired namespace environment")
- exec(compiled_code, self.locals) # noqa: B102,S102
+ exec(compiled_code, self.locals) # noqa: S102
log.trace("Awaiting the created evaluation wrapper coroutine.")
await self.function()
@@ -212,7 +212,7 @@ class CaptureLastExpression(ast.NodeTransformer):
self.tree = tree
self.last_node = list(ast.iter_child_nodes(tree))[-1]
- def visit_Expr(self, node: ast.Expr) -> Union[ast.Expr, ast.Assign]: # noqa: N802
+ def visit_Expr(self, node: ast.Expr) -> ast.Expr | ast.Assign: # noqa: N802
"""
Replace the Expr node that is last child node of Module with an assignment.
@@ -230,7 +230,7 @@ class CaptureLastExpression(ast.NodeTransformer):
right_hand_side = list(ast.iter_child_nodes(node))[0]
assignment = ast.Assign(
- targets=[ast.Name(id='_value_last_expression', ctx=ast.Store())],
+ targets=[ast.Name(id="_value_last_expression", ctx=ast.Store())],
value=right_hand_side,
lineno=node.lineno,
col_offset=0,
diff --git a/bot/exts/core/internal_eval/_internal_eval.py b/bot/exts/core/internal_eval/_internal_eval.py
index 2daf8ef9..f5188c1f 100644
--- a/bot/exts/core/internal_eval/_internal_eval.py
+++ b/bot/exts/core/internal_eval/_internal_eval.py
@@ -1,7 +1,6 @@
import logging
import re
import textwrap
-from typing import Optional
import discord
from discord.ext import commands
@@ -84,7 +83,7 @@ class InternalEval(commands.Cog):
return shortened_output
- async def _upload_output(self, output: str) -> Optional[str]:
+ async def _upload_output(self, output: str) -> str | None:
"""Upload `internal eval` output to our pastebin and return the url."""
data = self.shorten_output(output, max_length=MAX_LENGTH)
try:
diff --git a/bot/exts/core/source.py b/bot/exts/core/source.py
index f771eaca..7c67bcb5 100644
--- a/bot/exts/core/source.py
+++ b/bot/exts/core/source.py
@@ -1,15 +1,17 @@
import inspect
from pathlib import Path
-from typing import Optional
from discord import Embed
from discord.ext import commands
from bot.bot import Bot
-from bot.constants import Channels, Source, WHITELISTED_CHANNELS
+from bot.constants import Channels, WHITELISTED_CHANNELS
from bot.utils.converters import SourceConverter, SourceType
from bot.utils.decorators import whitelist_override
+GITHUB_BOT_URL = "https://github.com/python-discord/sir-lancebot"
+BOT_AVATAR_URL = "https://avatars1.githubusercontent.com/u/9919"
+
class BotSource(commands.Cog):
"""Displays information about the bot's source code."""
@@ -20,15 +22,15 @@ class BotSource(commands.Cog):
"""Display information and a GitHub link to the source code of a command, tag, or cog."""
if not source_item:
embed = Embed(title="Sir Lancebot's GitHub Repository")
- embed.add_field(name="Repository", value=f"[Go to GitHub]({Source.github})")
- embed.set_thumbnail(url=Source.github_avatar_url)
+ embed.add_field(name="Repository", value=f"[Go to GitHub]({GITHUB_BOT_URL})")
+ embed.set_thumbnail(url=BOT_AVATAR_URL)
await ctx.send(embed=embed)
return
embed = await self.build_embed(source_item)
await ctx.send(embed=embed)
- def get_source_link(self, source_item: SourceType) -> tuple[str, str, Optional[int]]:
+ def get_source_link(self, source_item: SourceType) -> tuple[str, str, int | None]:
"""
Build GitHub link of source item, return this link, file location and first line number.
@@ -58,11 +60,11 @@ class BotSource(commands.Cog):
file_location = Path(filename).relative_to(Path.cwd()).as_posix()
- url = f"{Source.github}/blob/main/{file_location}{lines_extension}"
+ url = f"{GITHUB_BOT_URL}/blob/main/{file_location}{lines_extension}"
return url, file_location, first_line_no or None
- async def build_embed(self, source_object: SourceType) -> Optional[Embed]:
+ async def build_embed(self, source_object: SourceType) -> Embed | None:
"""Build embed based on source object."""
url, location, first_line = self.get_source_link(source_object)
@@ -74,7 +76,7 @@ class BotSource(commands.Cog):
description = source_object.description.splitlines()[0]
embed = Embed(title=title, description=description)
- embed.set_thumbnail(url=Source.github_avatar_url)
+ embed.set_thumbnail(url=BOT_AVATAR_URL)
embed.add_field(name="Source Code", value=f"[Go to GitHub]({url})")
line_text = f":{first_line}" if first_line else ""
embed.set_footer(text=f"{location}{line_text}")