diff options
Diffstat (limited to 'bot/exts/core')
-rw-r--r-- | bot/exts/core/error_handler.py | 10 | ||||
-rw-r--r-- | bot/exts/core/extensions.py | 16 | ||||
-rw-r--r-- | bot/exts/core/help.py | 27 | ||||
-rw-r--r-- | bot/exts/core/internal_eval/_helpers.py | 10 | ||||
-rw-r--r-- | bot/exts/core/internal_eval/_internal_eval.py | 3 | ||||
-rw-r--r-- | bot/exts/core/source.py | 18 |
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}") |