diff --git a/.forgejo/workflows/config/.pylintrc b/.forgejo/workflows/config/.pylintrc new file mode 100644 index 0000000..18bfab4 --- /dev/null +++ b/.forgejo/workflows/config/.pylintrc @@ -0,0 +1,20 @@ + [MESSAGES CONTROL] + disable= + too-many-lines, + missing-module-docstring, + missing-function-docstring, + missing-class-docstring, + line-too-long, + too-many-arguments, + too-many-branches, + superfluous-parens, + invalid-name, + too-many-locals, + too-many-public-methods, + too-many-statements, + arguments-differ, + too-many-return-statements, + import-outside-toplevel, + import-self, + relative-beyond-top-level, + too-many-instance-attributes diff --git a/.forgejo/workflows/workflow.yaml b/.forgejo/workflows/workflow.yaml index a9f834b..a290194 100644 --- a/.forgejo/workflows/workflow.yaml +++ b/.forgejo/workflows/workflow.yaml @@ -6,7 +6,7 @@ on: pull_request: jobs: - Lint Code (Ruff): + Lint Code (Ruff & Pylint): runs-on: docker container: www.coastalcommits.com/seaswimmerthefsh/actionscontainers-seacogs:latest steps: @@ -19,6 +19,9 @@ jobs: - name: Analysing code with Ruff run: ruff check $(git ls-files '*.py') + - name: Analysing code with Pylint + run: pylint --rcfile=.forgejo/workflows/config/.pylintrc $(git ls-files '*.py') + Build Documentation (MkDocs): runs-on: docker container: www.coastalcommits.com/seaswimmerthefsh/actionscontainers-seacogs:latest diff --git a/aurora/importers/aurora.py b/aurora/importers/aurora.py index 337f5a4..a4857aa 100644 --- a/aurora/importers/aurora.py +++ b/aurora/importers/aurora.py @@ -1,3 +1,4 @@ +# pylint: disable=duplicate-code import json from datetime import timedelta from typing import Dict @@ -18,7 +19,7 @@ class ImportAuroraView(ui.View): @ui.button(label="Yes", style=ButtonStyle.success) async def import_button_y( self, interaction: Interaction, button: ui.Button - ): + ): # pylint: disable=unused-argument await self.message.delete() await interaction.response.send_message( "Deleting original table...", ephemeral=True @@ -107,7 +108,7 @@ class ImportAuroraView(ui.View): @ui.button(label="No", style=ButtonStyle.danger) async def import_button_n( self, interaction: Interaction, button: ui.Button - ): + ): # pylint: disable=unused-argument await self.message.edit(content="Import cancelled.", view=None) await self.message.delete(10) await self.ctx.message.delete(10) diff --git a/aurora/importers/galacticbot.py b/aurora/importers/galacticbot.py index d5cb66c..c6e0b99 100644 --- a/aurora/importers/galacticbot.py +++ b/aurora/importers/galacticbot.py @@ -1,3 +1,4 @@ +# pylint: disable=duplicate-code import json from datetime import timedelta @@ -17,7 +18,7 @@ class ImportGalacticBotView(ui.View): @ui.button(label="Yes", style=ButtonStyle.success) async def import_button_y( self, interaction: Interaction, button: ui.Button - ): + ): # pylint: disable=unused-argument await self.message.delete() await interaction.response.send_message( "Deleting original table...", ephemeral=True @@ -150,7 +151,7 @@ class ImportGalacticBotView(ui.View): @ui.button(label="No", style=ButtonStyle.danger) async def import_button_n( self, interaction: Interaction, button: ui.Button - ): + ): # pylint: disable=unused-argument await self.message.edit(content="Import cancelled.", view=None) await self.message.delete(10) await self.ctx.message.delete(10) diff --git a/aurora/menus/addrole.py b/aurora/menus/addrole.py index 75c8cce..c6bcc6b 100644 --- a/aurora/menus/addrole.py +++ b/aurora/menus/addrole.py @@ -6,7 +6,6 @@ from aurora.utilities.config import config from aurora.utilities.factory import addrole_embed - class Addrole(ui.View): def __init__(self, ctx: commands.Context): super().__init__() @@ -27,7 +26,7 @@ class Addrole(ui.View): await interaction.message.edit(embed=await addrole_embed(self.ctx)) @ui.button(label="Clear", style=ButtonStyle.red, row=1) - async def clear(self, interaction: Interaction, button: ui.Button): + async def clear(self, interaction: Interaction, button: ui.Button): # pylint: disable=unused-argument if not interaction.user.guild_permissions.manage_guild and not interaction.user.guild_permissions.administrator: await interaction.response.send_message(error("You must have the manage guild permission to clear the guild's addrole whitelist."), ephemeral=True) return @@ -36,7 +35,7 @@ class Addrole(ui.View): await interaction.message.edit(embed=await addrole_embed(self.ctx)) @ui.button(label="Close", style=ButtonStyle.gray) - async def close(self, interaction: Interaction, button: ui.Button): + async def close(self, interaction: Interaction, button: ui.Button): # pylint: disable=unused-argument if not interaction.user.guild_permissions.manage_guild and not interaction.user.guild_permissions.administrator: await interaction.response.send_message(error("You can't do that!"), ephemeral=True) return diff --git a/aurora/menus/guild.py b/aurora/menus/guild.py index 8a2e2c9..a7c78c7 100644 --- a/aurora/menus/guild.py +++ b/aurora/menus/guild.py @@ -6,14 +6,13 @@ from aurora.utilities.factory import guild_embed from aurora.utilities.utils import create_pagesize_options - class Guild(ui.View): def __init__(self, ctx: commands.Context): super().__init__() self.ctx = ctx @ui.button(label="Show Moderator", style=ButtonStyle.green, row=0) - async def show_moderator(self, interaction: Interaction, button: ui.Button): + async def show_moderator(self, interaction: Interaction, button: ui.Button): # pylint: disable=unused-argument if not interaction.user.guild_permissions.manage_guild and not interaction.user.guild_permissions.administrator: await interaction.response.send_message("You must have the manage guild permission to change this setting.", ephemeral=True) return @@ -23,7 +22,7 @@ class Guild(ui.View): await interaction.message.edit(embed=await guild_embed(self.ctx)) @ui.button(label="Use Discord Permissions", style=ButtonStyle.green, row=0) - async def use_discord_permissions(self, interaction: Interaction, button: ui.Button): + async def use_discord_permissions(self, interaction: Interaction, button: ui.Button): # pylint: disable=unused-argument if not interaction.user.guild_permissions.manage_guild and not interaction.user.guild_permissions.administrator: await interaction.response.send_message("You must have the manage guild permission to change this setting.", ephemeral=True) return @@ -33,7 +32,7 @@ class Guild(ui.View): await interaction.message.edit(embed=await guild_embed(self.ctx)) @ui.button(label="Ignore Modlog", style=ButtonStyle.green, row=0) - async def ignore_modlog(self, interaction: Interaction, button: ui.Button): + async def ignore_modlog(self, interaction: Interaction, button: ui.Button): # pylint: disable=unused-argument if not interaction.user.guild_permissions.manage_guild and not interaction.user.guild_permissions.administrator: await interaction.response.send_message("You must have the manage guild permission to change this setting.", ephemeral=True) return @@ -43,7 +42,7 @@ class Guild(ui.View): await interaction.message.edit(embed=await guild_embed(self.ctx)) @ui.button(label="Ignore Other Bots", style=ButtonStyle.green, row=0) - async def ignore_other_bots(self, interaction: Interaction, button: ui.Button): + async def ignore_other_bots(self, interaction: Interaction, button: ui.Button): # pylint: disable=unused-argument if not interaction.user.guild_permissions.manage_guild and not interaction.user.guild_permissions.administrator: await interaction.response.send_message("You must have the manage guild permission to change this setting.", ephemeral=True) return @@ -53,7 +52,7 @@ class Guild(ui.View): await interaction.message.edit(embed=await guild_embed(self.ctx)) @ui.button(label="DM Users", style=ButtonStyle.green, row=1) - async def dm_users(self, interaction: Interaction, button: ui.Button): + async def dm_users(self, interaction: Interaction, button: ui.Button): # pylint: disable=unused-argument if not interaction.user.guild_permissions.manage_guild and not interaction.user.guild_permissions.administrator: await interaction.response.send_message("You must have the manage guild permission to change this setting.", ephemeral=True) return @@ -63,7 +62,7 @@ class Guild(ui.View): await interaction.message.edit(embed=await guild_embed(self.ctx)) @ui.button(label="Auto Evidence Format", style=ButtonStyle.green, row=1) - async def auto_evidenceformat(self, interaction: Interaction, button: ui.Button): + async def auto_evidenceformat(self, interaction: Interaction, button: ui.Button): # pylint: disable=unused-argument if not interaction.user.guild_permissions.manage_guild and not interaction.user.guild_permissions.administrator: await interaction.response.send_message("You must have the manage guild permission to change this setting.", ephemeral=True) return @@ -73,7 +72,7 @@ class Guild(ui.View): await interaction.message.edit(embed=await guild_embed(self.ctx)) @ui.button(label="Ephemeral", style=ButtonStyle.green, row=1) - async def ephemeral(self, interaction: Interaction, button: ui.Button): + async def ephemeral(self, interaction: Interaction, button: ui.Button): # pylint: disable=unused-argument if not interaction.user.guild_permissions.manage_guild and not interaction.user.guild_permissions.administrator: await interaction.response.send_message("You must have the manage guild permission to change this setting.", ephemeral=True) return @@ -83,7 +82,7 @@ class Guild(ui.View): await interaction.message.edit(embed=await guild_embed(self.ctx)) @ui.button(label="History Inline", style=ButtonStyle.green, row=1) - async def inline(self, interaction: Interaction, button: ui.Button): + async def inline(self, interaction: Interaction, button: ui.Button): # pylint: disable=unused-argument if not interaction.user.guild_permissions.manage_guild and not interaction.user.guild_permissions.administrator: await interaction.response.send_message("You must have the manage guild permission to change this setting.", ephemeral=True) return diff --git a/aurora/menus/immune.py b/aurora/menus/immune.py index df509ef..b9697b6 100644 --- a/aurora/menus/immune.py +++ b/aurora/menus/immune.py @@ -6,7 +6,6 @@ from aurora.utilities.config import config from aurora.utilities.factory import immune_embed - class Immune(ui.View): def __init__(self, ctx: commands.Context): super().__init__() @@ -28,7 +27,7 @@ class Immune(ui.View): await interaction.message.edit(embed=await immune_embed(self.ctx)) @ui.button(label="Clear", style=ButtonStyle.red, row=1) - async def clear(self, interaction: Interaction, button: ui.Button): + async def clear(self, interaction: Interaction, button: ui.Button): # pylint: disable=unused-argument if not interaction.user.guild_permissions.manage_guild and not interaction.user.guild_permissions.administrator: await interaction.response.send_message(error("You must have the manage guild permission to clear the guild's immune roles."), ephemeral=True) return @@ -37,7 +36,7 @@ class Immune(ui.View): await interaction.message.edit(embed=await immune_embed(self.ctx)) @ui.button(label="Close", style=ButtonStyle.gray) - async def close(self, interaction: Interaction, button: ui.Button): + async def close(self, interaction: Interaction, button: ui.Button): # pylint: disable=unused-argument if not interaction.user.guild_permissions.manage_guild and not interaction.user.guild_permissions.administrator: await interaction.response.send_message(error("You can't do that!"), ephemeral=True) return diff --git a/aurora/menus/overrides.py b/aurora/menus/overrides.py index c0060ba..d98a208 100644 --- a/aurora/menus/overrides.py +++ b/aurora/menus/overrides.py @@ -6,14 +6,13 @@ from aurora.utilities.factory import overrides_embed from aurora.utilities.utils import create_pagesize_options - class Overrides(ui.View): def __init__(self, ctx: commands.Context): super().__init__() self.ctx = ctx @ui.button(label="Auto Evidence Format", style=ButtonStyle.green, row=0) - async def auto_evidenceformat(self, interaction: Interaction, button: ui.Button): + async def auto_evidenceformat(self, interaction: Interaction, button: ui.Button): # pylint: disable=unused-argument if self.ctx.author != interaction.user: await interaction.response.send_message("You cannot change this setting for other users.", ephemeral=True) return @@ -28,7 +27,7 @@ class Overrides(ui.View): await interaction.message.edit(embed=await overrides_embed(self.ctx)) @ui.button(label="Ephemeral", style=ButtonStyle.green, row=0) - async def ephemeral(self, interaction: Interaction, button: ui.Button): + async def ephemeral(self, interaction: Interaction, button: ui.Button): # pylint: disable=unused-argument if self.ctx.author != interaction.user: await interaction.response.send_message("You cannot change this setting for other users.", ephemeral=True) return @@ -43,7 +42,7 @@ class Overrides(ui.View): await interaction.message.edit(embed=await overrides_embed(self.ctx)) @ui.button(label="Inline", style=ButtonStyle.green, row=0) - async def inline(self, interaction: Interaction, button: ui.Button): + async def inline(self, interaction: Interaction, button: ui.Button): # pylint: disable=unused-argument if self.ctx.author != interaction.user: await interaction.response.send_message("You cannot change this setting for other users.", ephemeral=True) return diff --git a/aurora/utilities/database.py b/aurora/utilities/database.py index 689af67..a2bcb92 100644 --- a/aurora/utilities/database.py +++ b/aurora/utilities/database.py @@ -1,3 +1,4 @@ +# pylint: disable=cyclic-import import json import sqlite3 import time @@ -7,7 +8,8 @@ from discord import Guild from redbot.core import data_manager from .logger import logger -from .utils import convert_timedelta_to_str, generate_dict, get_next_case_number +from .utils import (convert_timedelta_to_str, generate_dict, + get_next_case_number) def connect() -> sqlite3.Connection: @@ -117,8 +119,8 @@ async def mysql_log( resolved_by: str = None, resolved_reason: str = None, expired: bool = None, - changes: list = [], - metadata: dict = {}, + changes: list = None, + metadata: dict = None, ) -> int: if not timestamp: timestamp = int(time.time()) @@ -168,8 +170,8 @@ async def mysql_log( resolved_by, resolved_reason, expired, - json.dumps(changes), - json.dumps(metadata), + json.dumps(changes if changes else []), + json.dumps(metadata if metadata else {}), ) cursor.execute(sql, val) diff --git a/aurora/utilities/factory.py b/aurora/utilities/factory.py index 18e5bd3..b7c414c 100644 --- a/aurora/utilities/factory.py +++ b/aurora/utilities/factory.py @@ -1,13 +1,17 @@ +# pylint: disable=cyclic-import from datetime import datetime, timedelta from typing import Union import humanize -from discord import Color, Embed, Guild, Interaction, InteractionMessage, Member, Role, User +from discord import (Color, Embed, Guild, Interaction, InteractionMessage, + Member, Role, User) from redbot.core import commands from redbot.core.utils.chat_formatting import bold, box, error, warning from aurora.utilities.config import config -from aurora.utilities.utils import fetch_channel_dict, fetch_user_dict, get_bool_emoji, get_next_case_number, get_pagesize_str +from aurora.utilities.utils import (fetch_channel_dict, fetch_user_dict, + get_bool_emoji, get_next_case_number, + get_pagesize_str) async def message_factory( diff --git a/aurora/utilities/utils.py b/aurora/utilities/utils.py index 24dbe34..12c8400 100644 --- a/aurora/utilities/utils.py +++ b/aurora/utilities/utils.py @@ -1,3 +1,4 @@ +# pylint: disable=cyclic-import import json from datetime import timedelta as td from typing import Union diff --git a/backup/backup.py b/backup/backup.py index 0592741..b973776 100644 --- a/backup/backup.py +++ b/backup/backup.py @@ -17,6 +17,8 @@ from redbot.core.bot import Red from redbot.core.utils.chat_formatting import error, text_to_file + +# pylint: disable=protected-access class Backup(commands.Cog): """A utility to make reinstalling repositories and cogs after migrating the bot far easier.""" diff --git a/poetry.lock b/poetry.lock index 5a03398..633ba32 100644 --- a/poetry.lock +++ b/poetry.lock @@ -211,6 +211,20 @@ files = [ {file = "apsw-3.43.1.0.tar.gz", hash = "sha256:7e2cbbb407b6d1146bbd966de5843688b4deaa2cb07d98690689a42d00363cdd"}, ] +[[package]] +name = "astroid" +version = "3.1.0" +description = "An abstract syntax tree for Python with inference support." +optional = false +python-versions = ">=3.8.0" +files = [ + {file = "astroid-3.1.0-py3-none-any.whl", hash = "sha256:951798f922990137ac090c53af473db7ab4e70c770e6d7fae0cec59f74411819"}, + {file = "astroid-3.1.0.tar.gz", hash = "sha256:ac248253bfa4bd924a0de213707e7ebeeb3138abeb48d798784ead1e56d419d4"}, +] + +[package.dependencies] +typing-extensions = {version = ">=4.0.0", markers = "python_version < \"3.11\""} + [[package]] name = "async-timeout" version = "4.0.3" @@ -621,6 +635,21 @@ files = [ {file = "defusedxml-0.7.1.tar.gz", hash = "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69"}, ] +[[package]] +name = "dill" +version = "0.3.8" +description = "serialize all of Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "dill-0.3.8-py3-none-any.whl", hash = "sha256:c36ca9ffb54365bdd2f8eb3eff7d2a21237f8452b57ace88b1ac615b7e815bd7"}, + {file = "dill-0.3.8.tar.gz", hash = "sha256:3ebe3c479ad625c4553aca177444d89b486b1d84982eeacded644afc0cf797ca"}, +] + +[package.extras] +graph = ["objgraph (>=1.7.2)"] +profile = ["gprof2dot (>=2022.7.29)"] + [[package]] name = "discord-py" version = "2.3.2" @@ -828,6 +857,20 @@ docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker perf = ["ipython"] testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)", "pytest-ruff"] +[[package]] +name = "isort" +version = "5.13.2" +description = "A Python utility / library to sort Python imports." +optional = false +python-versions = ">=3.8.0" +files = [ + {file = "isort-5.13.2-py3-none-any.whl", hash = "sha256:8ca5e72a8d85860d5a3fa69b8745237f2939afe12dbf656afbcb47fe72d947a6"}, + {file = "isort-5.13.2.tar.gz", hash = "sha256:48fdfcb9face5d58a4f6dde2e72a1fb8dcaf8ab26f95ab49fab84c2ddefb0109"}, +] + +[package.extras] +colors = ["colorama (>=0.4.6)"] + [[package]] name = "jinja2" version = "3.1.3" @@ -953,6 +996,17 @@ files = [ {file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b"}, ] +[[package]] +name = "mccabe" +version = "0.7.0" +description = "McCabe checker, plugin for flake8" +optional = false +python-versions = ">=3.6" +files = [ + {file = "mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"}, + {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"}, +] + [[package]] name = "mdurl" version = "0.1.2" @@ -1570,6 +1624,35 @@ files = [ [package.extras] plugins = ["importlib-metadata"] +[[package]] +name = "pylint" +version = "3.1.0" +description = "python code static checker" +optional = false +python-versions = ">=3.8.0" +files = [ + {file = "pylint-3.1.0-py3-none-any.whl", hash = "sha256:507a5b60953874766d8a366e8e8c7af63e058b26345cfcb5f91f89d987fd6b74"}, + {file = "pylint-3.1.0.tar.gz", hash = "sha256:6a69beb4a6f63debebaab0a3477ecd0f559aa726af4954fc948c51f7a2549e23"}, +] + +[package.dependencies] +astroid = ">=3.1.0,<=3.2.0-dev0" +colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""} +dill = [ + {version = ">=0.2", markers = "python_version < \"3.11\""}, + {version = ">=0.3.6", markers = "python_version >= \"3.11\""}, +] +isort = ">=4.2.5,<5.13.0 || >5.13.0,<6" +mccabe = ">=0.6,<0.8" +platformdirs = ">=2.2.0" +tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} +tomlkit = ">=0.10.1" +typing-extensions = {version = ">=3.10.0", markers = "python_version < \"3.10\""} + +[package.extras] +spelling = ["pyenchant (>=3.2,<4.0)"] +testutils = ["gitpython (>3)"] + [[package]] name = "pymdown-extensions" version = "10.4" @@ -2140,6 +2223,28 @@ webencodings = ">=0.4" doc = ["sphinx", "sphinx_rtd_theme"] test = ["flake8", "isort", "pytest"] +[[package]] +name = "tomli" +version = "2.0.1" +description = "A lil' TOML parser" +optional = false +python-versions = ">=3.7" +files = [ + {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, + {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, +] + +[[package]] +name = "tomlkit" +version = "0.12.4" +description = "Style preserving TOML library" +optional = false +python-versions = ">=3.7" +files = [ + {file = "tomlkit-0.12.4-py3-none-any.whl", hash = "sha256:5cd82d48a3dd89dee1f9d64420aa20ae65cfbd00668d6f094d7578a78efbb77b"}, + {file = "tomlkit-0.12.4.tar.gz", hash = "sha256:7ca1cfc12232806517a8515047ba66a19369e71edf2439d0f5824f91032b6cc3"}, +] + [[package]] name = "typing-extensions" version = "4.7.1" diff --git a/pyproject.toml b/pyproject.toml index 064de77..98be10a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -19,6 +19,7 @@ optional = true [tool.poetry.group.dev.dependencies] ruff = "^0.2.1" +pylint = "^3.1.0" [tool.poetry.group.docs] optional = true