From 06e678f26fbda03eaf702c362e8f9684b28bc492 Mon Sep 17 00:00:00 2001 From: cswimr Date: Sun, 26 Jan 2025 01:52:46 +0000 Subject: [PATCH 01/53] style(repo): enable some more linting rules --- pyproject.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index ccf98da..d38352f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -84,8 +84,8 @@ target-version = "py311" # Enable Pyflakes (`F`) and a subset of the pycodestyle (`E`) codes by default. # Unlike Flake8, Ruff doesn't enable pycodestyle warnings (`W`) or # McCabe complexity (`C901`) by default. -select = ["F", "W", "E", "C901"] -ignore = ["C901"] +select = ["I", "N", "F", "W", "E", "G", "INP", "T20", "PLC", "PLE", "PLW", "PLR"] +ignore = ["PLR0912", "PLR0915", "PLR2004"] # Allow fix for all enabled rules (when `--fix`) is provided. fixable = ["ALL"] From 6ffa81fdeeb96259c8067c4b45e94d8bb587096b Mon Sep 17 00:00:00 2001 From: cswimr Date: Sun, 26 Jan 2025 01:53:09 +0000 Subject: [PATCH 02/53] fix(bible): fix ruff errors --- bible/bible.py | 34 +++++++++++++++++----------------- bible/errors.py | 6 +++--- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/bible/bible.py b/bible/bible.py index 9cf520b..a1da890 100644 --- a/bible/bible.py +++ b/bible/bible.py @@ -91,11 +91,11 @@ class Bible(commands.Cog): response.status, ) if response.status == 401: - raise bible.errors.Unauthorized() + raise bible.errors.UnauthorizedError() if response.status == 403: raise bible.errors.BibleAccessError() if response.status == 503: - raise bible.errors.ServiceUnavailable() + raise bible.errors.ServiceUnavailableError() return Version( bible_id, data["data"]["abbreviation"], @@ -137,13 +137,13 @@ class Bible(commands.Cog): if response.status == 400: raise bible.errors.InexplicableError() if response.status == 401: - raise bible.errors.Unauthorized() + raise bible.errors.UnauthorizedError() if response.status == 403: raise bible.errors.BibleAccessError() if response.status == 404: - raise bible.errors.NotFound() + raise bible.errors.NotFoundError() if response.status == 503: - raise bible.errors.ServiceUnavailable() + raise bible.errors.ServiceUnavailableError() fums_url = "https://fums.api.bible/f3" fums_params = { @@ -176,11 +176,11 @@ class Bible(commands.Cog): response.status, ) if response.status == 401: - raise bible.errors.Unauthorized() + raise bible.errors.UnauthorizedError() if response.status == 403: raise bible.errors.BibleAccessError() if response.status == 503: - raise bible.errors.ServiceUnavailable() + raise bible.errors.ServiceUnavailableError() return data["data"] async def _get_chapters(self, bible_id: str, book_id: str) -> dict: @@ -195,11 +195,11 @@ class Bible(commands.Cog): response.status, ) if response.status == 401: - raise bible.errors.Unauthorized() + raise bible.errors.UnauthorizedError() if response.status == 403: raise bible.errors.BibleAccessError() if response.status == 503: - raise bible.errors.ServiceUnavailable() + raise bible.errors.ServiceUnavailableError() return data["data"] async def _get_verses(self, bible_id: str, book_id: str, chapter: int) -> dict: @@ -214,11 +214,11 @@ class Bible(commands.Cog): response.status, ) if response.status == 401: - raise bible.errors.Unauthorized() + raise bible.errors.UnauthorizedError() if response.status == 403: raise bible.errors.BibleAccessError() if response.status == 503: - raise bible.errors.ServiceUnavailable() + raise bible.errors.ServiceUnavailableError() return data["data"] @commands.group(autohelp=True) @@ -251,10 +251,10 @@ class Bible(commands.Cog): passage = await self._get_passage(ctx, bible_id, f"{book_id}.{passage.replace(':', '.')}", False) except ( bible.errors.BibleAccessError, - bible.errors.NotFound, + bible.errors.NotFoundError, bible.errors.InexplicableError, - bible.errors.ServiceUnavailable, - bible.errors.Unauthorized, + bible.errors.ServiceUnavailableError, + bible.errors.UnauthorizedError, ) as e: await ctx.send(e.message) return @@ -294,10 +294,10 @@ class Bible(commands.Cog): passage = await self._get_passage(ctx, bible_id, verse, False) except ( bible.errors.BibleAccessError, - bible.errors.NotFound, + bible.errors.NotFoundError, bible.errors.InexplicableError, - bible.errors.ServiceUnavailable, - bible.errors.Unauthorized, + bible.errors.ServiceUnavailableError, + bible.errors.UnauthorizedError, ) as e: await ctx.send(e.message) return diff --git a/bible/errors.py b/bible/errors.py index 708ca86..954e92d 100644 --- a/bible/errors.py +++ b/bible/errors.py @@ -10,7 +10,7 @@ class BibleAccessError(Exception): self.message = message -class Unauthorized(Exception): +class UnauthorizedError(Exception): def __init__( self, message: str = error("The API key for API.Bible is missing or invalid. Please report this to the bot owner.\nIf you are the bot owner, please check the documentation [here]()."), @@ -19,7 +19,7 @@ class Unauthorized(Exception): self.message = message -class NotFound(Exception): +class NotFoundError(Exception): def __init__( self, message: str = error("The requested passage was not found."), @@ -28,7 +28,7 @@ class NotFound(Exception): self.message = message -class ServiceUnavailable(Exception): +class ServiceUnavailableError(Exception): def __init__( self, message: str = error("The API.Bible service is currently unavailable."), From 6c25d61dfd38fc596bebbcce3918e882154f6db5 Mon Sep 17 00:00:00 2001 From: cswimr Date: Sun, 26 Jan 2025 01:53:40 +0000 Subject: [PATCH 03/53] fix(hotreload): use %s formatting in logging strings --- hotreload/hotreload.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/hotreload/hotreload.py b/hotreload/hotreload.py index d039a8a..8a48501 100644 --- a/hotreload/hotreload.py +++ b/hotreload/hotreload.py @@ -97,13 +97,13 @@ class HotReloadHandler(RegexMatchingEventHandler): else: dest = "" - self.logger.info(f"File {event.src_path} has been {event.event_type}{dest}.") + self.logger.info("File %s has been %s%s.", event.src_path, event.event_type, dest) run_coroutine_threadsafe(self.reload_cogs(cogs_to_reload), loop=self.bot.loop) async def reload_cogs(self, cog_names: Sequence[str]) -> None: """Reload modified cog.""" core_logic = CoreLogic(bot=self.bot) - self.logger.info(f"Reloading cogs: {humanize_list(cog_names, style='unit')}") + self.logger.info("Reloading cogs: %s", humanize_list(cog_names, style="unit")) await core_logic._reload(pkg_names=cog_names) - self.logger.info(f"Reloaded cogs: {humanize_list(cog_names, style='unit')}") + self.logger.info("Reloaded cogs: %s", humanize_list(cog_names, style="unit")) From 3d882625d28367251fec7293f0384a658717e6b0 Mon Sep 17 00:00:00 2001 From: cswimr Date: Sun, 26 Jan 2025 01:54:02 +0000 Subject: [PATCH 04/53] style(seautils): reformat --- seautils/seautils.py | 102 +++++++++++++++++-------------------------- 1 file changed, 40 insertions(+), 62 deletions(-) diff --git a/seautils/seautils.py b/seautils/seautils.py index a895c35..272112d 100644 --- a/seautils/seautils.py +++ b/seautils/seautils.py @@ -29,12 +29,14 @@ from redbot.core.utils.views import SimpleMenu def md(soup: BeautifulSoup, **options) -> Any | str: return MarkdownConverter(**options).convert_soup(soup=soup) + def format_rfc_text(text: str, number: int) -> str: one: str = re.sub(r"\(\.\/rfc(\d+)", r"(https://www.rfc-editor.org/rfc/rfc\1.html", text) two: str = re.sub(r"\((#(?:section|page)-\d+(?:.\d+)?)\)", f"(https://www.rfc-editor.org/rfc/rfc{number}.html\1)", one) three: str = re.sub(r"\n{3,}", "\n\n", two) return three + class SeaUtils(commands.Cog): """A collection of random utilities.""" @@ -57,7 +59,6 @@ class SeaUtils(commands.Cog): ] return "\n".join(text) - def format_src(self, obj: Any) -> str: """A large portion of this code is repurposed from Zephyrkul's RTFS cog. https://github.com/Zephyrkul/FluffyCogs/blob/master/rtfs/rtfs.py""" @@ -75,7 +76,7 @@ class SeaUtils(commands.Cog): @commands.command(aliases=["source", "src", "code", "showsource"]) @commands.is_owner() - async def showcode(self, ctx: commands.Context, *, object: str) -> None: # pylint: disable=redefined-builtin + async def showcode(self, ctx: commands.Context, *, object: str) -> None: # pylint: disable=redefined-builtin """Show the code for a particular object.""" try: if object.startswith("/") and (obj := ctx.bot.tree.get_command(object[1:])): @@ -86,11 +87,7 @@ class SeaUtils(commands.Cog): text = self.format_src(obj) else: raise AttributeError - temp_content = cf.pagify( - text=cleanup_code(text), - escape_mass_mentions=True, - page_length = 1977 - ) + temp_content = cf.pagify(text=cleanup_code(text), escape_mass_mentions=True, page_length=1977) content = [] max_i = operator.length_hint(temp_content) i = 1 @@ -105,7 +102,7 @@ class SeaUtils(commands.Cog): else: await ctx.send(content="Object not found!", reference=ctx.message.to_reference(fail_if_not_exists=False)) - @commands.command(name='dig', aliases=['dnslookup', 'nslookup']) + @commands.command(name="dig", aliases=["dnslookup", "nslookup"]) @commands.is_owner() async def dig(self, ctx: commands.Context, name: str, record_type: str | None = None, server: str | None = None, port: int = 53) -> None: """Retrieve DNS information for a domain. @@ -113,13 +110,13 @@ class SeaUtils(commands.Cog): Uses `dig` to perform a DNS query. Will fall back to `nslookup` if `dig` is not installed on the system. `nslookup` does not provide as much information as `dig`, so only the `name` parameter will be used if `nslookup` is used. Will return the A, AAAA, and CNAME records for a domain by default. You can specify a different record type with the `type` parameter.""" - command_opts: list[str | int] = ['dig'] - query_types: list[str] = [record_type] if record_type else ['A', 'AAAA', 'CNAME'] + command_opts: list[str | int] = ["dig"] + query_types: list[str] = [record_type] if record_type else ["A", "AAAA", "CNAME"] if server: - command_opts.extend(['@', server]) + command_opts.extend(["@", server]) for query_type in query_types: command_opts.extend([name, query_type]) - command_opts.extend(['-p', str(port), '+yaml']) + command_opts.extend(["-p", str(port), "+yaml"]) try: process: Process = await asyncio.create_subprocess_exec(*command_opts, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE) @@ -128,22 +125,18 @@ class SeaUtils(commands.Cog): await ctx.maybe_send_embed(message="An error was encountered!\n" + cf.box(text=stderr.decode())) else: data = yaml.safe_load(stdout.decode()) - message_data: dict = data[0]['message'] - response_data: dict = message_data['response_message_data'] + message_data: dict = data[0]["message"] + response_data: dict = message_data["response_message_data"] if ctx.embed_requested(): - embed = Embed( - title="DNS Query Result", - color=await ctx.embed_color(), - timestamp=message_data['response_time'] - ) - embed.add_field(name="Response Address", value=message_data['response_address'], inline=True) - embed.add_field(name="Response Port", value=message_data['response_port'], inline=True) - embed.add_field(name="Query Address", value=message_data['query_address'], inline=True) - embed.add_field(name="Query Port", value=message_data['query_port'], inline=True) - embed.add_field(name="Status", value=response_data['status'], inline=True) - embed.add_field(name="Flags", value=response_data['flags'], inline=True) + embed = Embed(title="DNS Query Result", color=await ctx.embed_color(), timestamp=message_data["response_time"]) + embed.add_field(name="Response Address", value=message_data["response_address"], inline=True) + embed.add_field(name="Response Port", value=message_data["response_port"], inline=True) + embed.add_field(name="Query Address", value=message_data["query_address"], inline=True) + embed.add_field(name="Query Port", value=message_data["query_port"], inline=True) + embed.add_field(name="Status", value=response_data["status"], inline=True) + embed.add_field(name="Flags", value=response_data["flags"], inline=True) - if response_data.get('status') != 'NOERROR': + if response_data.get("status") != "NOERROR": embed.colour = Color.red() embed.description = cf.error("Dig query did not return `NOERROR` status.") @@ -151,19 +144,19 @@ class SeaUtils(commands.Cog): answers = [] authorities = [] for m in data: - response = m['message']['response_message_data'] - if 'QUESTION_SECTION' in response: - for question in response['QUESTION_SECTION']: + response = m["message"]["response_message_data"] + if "QUESTION_SECTION" in response: + for question in response["QUESTION_SECTION"]: if question not in questions: questions.append(question) - if 'ANSWER_SECTION' in response: - for answer in response['ANSWER_SECTION']: + if "ANSWER_SECTION" in response: + for answer in response["ANSWER_SECTION"]: if answer not in answers: answers.append(answer) - if 'AUTHORITY_SECTION' in response: - for authority in response['AUTHORITY_SECTION']: + if "AUTHORITY_SECTION" in response: + for authority in response["AUTHORITY_SECTION"]: if authority not in authorities: authorities.append(authority) @@ -183,26 +176,22 @@ class SeaUtils(commands.Cog): embed.add_field(name="Authority Section", value=f"{cf.box(text=authority_section, lang='prolog')}", inline=False) await ctx.send(embed=embed) else: - await ctx.send(content=cf.box(text=stdout, lang='yaml')) - except (FileNotFoundError): + await ctx.send(content=cf.box(text=stdout, lang="yaml")) + except FileNotFoundError: try: - ns_process = await asyncio.create_subprocess_exec('nslookup', name, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE) + ns_process = await asyncio.create_subprocess_exec("nslookup", name, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE) ns_stdout, ns_stderr = await ns_process.communicate() if ns_stderr: await ctx.maybe_send_embed(message="An error was encountered!\n" + cf.box(text=ns_stderr.decode())) else: warning = cf.warning("`dig` is not installed! Defaulting to `nslookup`.\nThis command provides more information when `dig` is installed on the system.\n") if await ctx.embed_requested(): - embed = Embed( - title="DNS Query Result", - color=await ctx.embed_color(), - timestamp=ctx.message.created_at - ) + embed = Embed(title="DNS Query Result", color=await ctx.embed_color(), timestamp=ctx.message.created_at) embed.description = warning + cf.box(text=ns_stdout.decode()) await ctx.send(embed=embed) else: - await ctx.send(content = warning + cf.box(text=ns_stdout.decode())) - except (FileNotFoundError): + await ctx.send(content=warning + cf.box(text=ns_stdout.decode())) + except FileNotFoundError: await ctx.maybe_send_embed(message=cf.error("Neither `dig` nor `nslookup` are installed on the system. Unable to resolve DNS query.")) @commands.command() @@ -210,15 +199,15 @@ class SeaUtils(commands.Cog): """Retrieve the text of an RFC document. This command uses the [RFC Editor website](https://www.rfc-editor.org/) to fetch the text of an RFC document. - A [Request for Comments (RFC)](https://en.wikipedia.org/wiki/Request_for_Comments) is a publication in a series from the principal technical development and standards-setting bodies for the [Internet](https://en.wikipedia.org/wiki/Internet), most prominently the [Internet Engineering Task Force](https://en.wikipedia.org/wiki/Internet_Engineering_Task_Force). An RFC is authored by individuals or groups of engineers and [computer scientists](https://en.wikipedia.org/wiki/Computer_scientist) in the form of a [memorandum](https://en.wikipedia.org/wiki/Memorandum) describing methods, behaviors, research, or innovations applicable to the working of the Internet and Internet-connected systems. It is submitted either for [peer review](https://en.wikipedia.org/wiki/Peer_review) or to convey new concepts, information, or, occasionally, engineering humor.""" # noqa: E501 + A [Request for Comments (RFC)](https://en.wikipedia.org/wiki/Request_for_Comments) is a publication in a series from the principal technical development and standards-setting bodies for the [Internet](https://en.wikipedia.org/wiki/Internet), most prominently the [Internet Engineering Task Force](https://en.wikipedia.org/wiki/Internet_Engineering_Task_Force). An RFC is authored by individuals or groups of engineers and [computer scientists](https://en.wikipedia.org/wiki/Computer_scientist) in the form of a [memorandum](https://en.wikipedia.org/wiki/Memorandum) describing methods, behaviors, research, or innovations applicable to the working of the Internet and Internet-connected systems. It is submitted either for [peer review](https://en.wikipedia.org/wiki/Peer_review) or to convey new concepts, information, or, occasionally, engineering humor.""" # noqa: E501 url = f"https://www.rfc-editor.org/rfc/rfc{number}.html" datatracker_url = f"https://datatracker.ietf.org/doc/rfc{number}" async with aiohttp.ClientSession() as session: async with session.get(url=url) as response: if response.status == 200: html = await response.text() - soup = BeautifulSoup(html, 'html.parser') - pre_tags = soup.find_all('pre') + soup = BeautifulSoup(html, "html.parser") + pre_tags = soup.find_all("pre") content: list[Embed | str] = [] for pre_tag in pre_tags: text = format_rfc_text(md(pre_tag), number) @@ -226,26 +215,15 @@ class SeaUtils(commands.Cog): pagified_text = cf.pagify(text, delims=["\n\n"], page_length=4096) for page in pagified_text: if await ctx.embed_requested(): - embed = Embed( - title=f"RFC Document {number}", - url=datatracker_url, - description=page, - color=await ctx.embed_color() - ) + embed = Embed(title=f"RFC Document {number}", url=datatracker_url, description=page, color=await ctx.embed_color()) content.append(embed) else: content.append(page) + elif await ctx.embed_requested(): + embed = Embed(title=f"RFC Document {number}", url=datatracker_url, description=text, color=await ctx.embed_color()) + content.append(embed) else: - if await ctx.embed_requested(): - embed = Embed( - title=f"RFC Document {number}", - url=datatracker_url, - description=text, - color=await ctx.embed_color() - ) - content.append(embed) - else: - content.append(text) + content.append(text) if await ctx.embed_requested(): for embed in content: embed.set_footer(text=f"Page {content.index(embed) + 1}/{len(content)}") From 3063721b8d174161b6ce0b59e2342eaeeff7463e Mon Sep 17 00:00:00 2001 From: cswimr Date: Sun, 26 Jan 2025 13:07:46 +0000 Subject: [PATCH 05/53] chore(vscode): add some settings overrides --- .vscode/settings.json | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 6808e51..9b76a06 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,6 +1,5 @@ { "[python]": { - "editor.formatOnSave": true, "editor.codeActionsOnSave": { "source.fixAll": "explicit" }, @@ -8,5 +7,15 @@ }, "[json]": { "editor.defaultFormatter": "vscode.json-language-features" + }, + "[jsonc]": { + "editor.defaultFormatter": "vscode.json-language-features" + }, + "editor.formatOnSave": true, + "files.exclude": { + "**/.git": true, + "**/__pycache__": true, + "**/.ruff_cache": true, + "**/.mypy_cache": true } } From 0492b30662fb6162e65127b7f7a58404da3561f3 Mon Sep 17 00:00:00 2001 From: cswimr Date: Sun, 26 Jan 2025 13:08:02 +0000 Subject: [PATCH 06/53] chore(repo): add two paths to gitignore --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index d937fba..b56a839 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,5 @@ site .venv .data __pycache__ +.mypy_cache/ +.ruff_cache/ From 41678ef3edf8fcdf2065e5cb4b0737924ac91dcd Mon Sep 17 00:00:00 2001 From: cswimr Date: Sun, 26 Jan 2025 13:08:28 +0000 Subject: [PATCH 07/53] chore(repo): enable more ruff linting rules --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index d38352f..160f994 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -84,7 +84,7 @@ target-version = "py311" # Enable Pyflakes (`F`) and a subset of the pycodestyle (`E`) codes by default. # Unlike Flake8, Ruff doesn't enable pycodestyle warnings (`W`) or # McCabe complexity (`C901`) by default. -select = ["I", "N", "F", "W", "E", "G", "INP", "T20", "PLC", "PLE", "PLW", "PLR"] +select = ["I", "N", "F", "W", "E", "G", "INP", "T20", "PLC", "PLE", "PLW", "PLR", "LOG"] ignore = ["PLR0912", "PLR0915", "PLR2004"] # Allow fix for all enabled rules (when `--fix`) is provided. From 5decc51a36934295208df3912117aa2e4a907b27 Mon Sep 17 00:00:00 2001 From: cswimr Date: Sun, 26 Jan 2025 13:08:33 +0000 Subject: [PATCH 08/53] chore(deps): update --- uv.lock | 743 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 372 insertions(+), 371 deletions(-) diff --git a/uv.lock b/uv.lock index a029a28..28ccf8f 100644 --- a/uv.lock +++ b/uv.lock @@ -1,9 +1,8 @@ version = 1 requires-python = ">=3.11" resolution-markers = [ + "python_full_version >= '3.12'", "python_full_version < '3.12'", - "python_full_version == '3.12.*'", - "python_full_version >= '3.13'", ] [[package]] @@ -136,11 +135,11 @@ wheels = [ [[package]] name = "astroid" -version = "3.3.5" +version = "3.3.8" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/38/1e/326fb1d3d83a3bb77c9f9be29d31f2901e35acb94b0605c3f2e5085047f9/astroid-3.3.5.tar.gz", hash = "sha256:5cfc40ae9f68311075d27ef68a4841bdc5cc7f6cf86671b49f00607d30188e2d", size = 397229 } +sdist = { url = "https://files.pythonhosted.org/packages/80/c5/5c83c48bbf547f3dd8b587529db7cf5a265a3368b33e85e76af8ff6061d3/astroid-3.3.8.tar.gz", hash = "sha256:a88c7994f914a4ea8572fac479459f4955eeccc877be3f2d959a33273b0cf40b", size = 398196 } wheels = [ - { url = "https://files.pythonhosted.org/packages/41/30/624365383fa4a40329c0f0bbbc151abc4a64e30dfc110fc8f6e2afcd02bb/astroid-3.3.5-py3-none-any.whl", hash = "sha256:a9d1c946ada25098d790e079ba2a1b112157278f3fb7e718ae6a9252f5835dc8", size = 274586 }, + { url = "https://files.pythonhosted.org/packages/07/28/0bc8a17d6cd4cc3c79ae41b7105a2b9a327c110e5ddd37a8a27b29a5c8a2/astroid-3.3.8-py3-none-any.whl", hash = "sha256:187ccc0c248bfbba564826c26f070494f7bc964fd286b6d9fff4420e55de828c", size = 275153 }, ] [[package]] @@ -184,11 +183,11 @@ wheels = [ [[package]] name = "blinker" -version = "1.8.2" +version = "1.9.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/1e/57/a6a1721eff09598fb01f3c7cda070c1b6a0f12d63c83236edf79a440abcc/blinker-1.8.2.tar.gz", hash = "sha256:8f77b09d3bf7c795e969e9486f39c2c5e9c39d4ee07424be2bc594ece9642d83", size = 23161 } +sdist = { url = "https://files.pythonhosted.org/packages/21/28/9b3f50ce0e048515135495f198351908d99540d69bfdc8c1d15b73dc55ce/blinker-1.9.0.tar.gz", hash = "sha256:b4ce2265a7abece45e7cc896e98dbebe6cead56bcf805a3d23136d145f5445bf", size = 22460 } wheels = [ - { url = "https://files.pythonhosted.org/packages/bb/2a/10164ed1f31196a2f7f3799368a821765c62851ead0e630ab52b8e14b4d0/blinker-1.8.2-py3-none-any.whl", hash = "sha256:1779309f71bf239144b9399d06ae925637cf6634cf6bd131104184531bf67c01", size = 9456 }, + { url = "https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl", hash = "sha256:ba0efaa9080b619ff2f3459d1d500c57bddea4a6b424b60a91141db6fd2f08bc", size = 8458 }, ] [[package]] @@ -275,11 +274,11 @@ wheels = [ [[package]] name = "certifi" -version = "2024.8.30" +version = "2024.12.14" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b0/ee/9b19140fe824b367c04c5e1b369942dd754c4c5462d5674002f75c4dedc1/certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9", size = 168507 } +sdist = { url = "https://files.pythonhosted.org/packages/0f/bd/1d41ee578ce09523c81a15426705dd20969f5abf006d1afe8aeff0dd776a/certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db", size = 166010 } wheels = [ - { url = "https://files.pythonhosted.org/packages/12/90/3c9ff0512038035f59d279fddeb79f5f1eccd8859f06d6163c58798b9487/certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8", size = 167321 }, + { url = "https://files.pythonhosted.org/packages/a5/32/8f6669fc4798494966bf446c8c4a162e0b5d893dff088afddf76414f70e1/certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56", size = 164927 }, ] [[package]] @@ -329,56 +328,50 @@ wheels = [ [[package]] name = "charset-normalizer" -version = "3.4.0" +version = "3.4.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f2/4f/e1808dc01273379acc506d18f1504eb2d299bd4131743b9fc54d7be4df1e/charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e", size = 106620 } +sdist = { url = "https://files.pythonhosted.org/packages/16/b0/572805e227f01586461c80e0fd25d65a2115599cc9dad142fee4b747c357/charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3", size = 123188 } wheels = [ - { url = "https://files.pythonhosted.org/packages/9c/61/73589dcc7a719582bf56aae309b6103d2762b526bffe189d635a7fcfd998/charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c", size = 193339 }, - { url = "https://files.pythonhosted.org/packages/77/d5/8c982d58144de49f59571f940e329ad6e8615e1e82ef84584c5eeb5e1d72/charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944", size = 124366 }, - { url = "https://files.pythonhosted.org/packages/bf/19/411a64f01ee971bed3231111b69eb56f9331a769072de479eae7de52296d/charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee", size = 118874 }, - { url = "https://files.pythonhosted.org/packages/4c/92/97509850f0d00e9f14a46bc751daabd0ad7765cff29cdfb66c68b6dad57f/charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c", size = 138243 }, - { url = "https://files.pythonhosted.org/packages/e2/29/d227805bff72ed6d6cb1ce08eec707f7cfbd9868044893617eb331f16295/charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6", size = 148676 }, - { url = "https://files.pythonhosted.org/packages/13/bc/87c2c9f2c144bedfa62f894c3007cd4530ba4b5351acb10dc786428a50f0/charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea", size = 141289 }, - { url = "https://files.pythonhosted.org/packages/eb/5b/6f10bad0f6461fa272bfbbdf5d0023b5fb9bc6217c92bf068fa5a99820f5/charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc", size = 142585 }, - { url = "https://files.pythonhosted.org/packages/3b/a0/a68980ab8a1f45a36d9745d35049c1af57d27255eff8c907e3add84cf68f/charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5", size = 144408 }, - { url = "https://files.pythonhosted.org/packages/d7/a1/493919799446464ed0299c8eef3c3fad0daf1c3cd48bff9263c731b0d9e2/charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594", size = 139076 }, - { url = "https://files.pythonhosted.org/packages/fb/9d/9c13753a5a6e0db4a0a6edb1cef7aee39859177b64e1a1e748a6e3ba62c2/charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c", size = 146874 }, - { url = "https://files.pythonhosted.org/packages/75/d2/0ab54463d3410709c09266dfb416d032a08f97fd7d60e94b8c6ef54ae14b/charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365", size = 150871 }, - { url = "https://files.pythonhosted.org/packages/8d/c9/27e41d481557be53d51e60750b85aa40eaf52b841946b3cdeff363105737/charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129", size = 148546 }, - { url = "https://files.pythonhosted.org/packages/ee/44/4f62042ca8cdc0cabf87c0fc00ae27cd8b53ab68be3605ba6d071f742ad3/charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236", size = 143048 }, - { url = "https://files.pythonhosted.org/packages/01/f8/38842422988b795220eb8038745d27a675ce066e2ada79516c118f291f07/charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99", size = 94389 }, - { url = "https://files.pythonhosted.org/packages/0b/6e/b13bd47fa9023b3699e94abf565b5a2f0b0be6e9ddac9812182596ee62e4/charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27", size = 101752 }, - { url = "https://files.pythonhosted.org/packages/d3/0b/4b7a70987abf9b8196845806198975b6aab4ce016632f817ad758a5aa056/charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6", size = 194445 }, - { url = "https://files.pythonhosted.org/packages/50/89/354cc56cf4dd2449715bc9a0f54f3aef3dc700d2d62d1fa5bbea53b13426/charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf", size = 125275 }, - { url = "https://files.pythonhosted.org/packages/fa/44/b730e2a2580110ced837ac083d8ad222343c96bb6b66e9e4e706e4d0b6df/charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db", size = 119020 }, - { url = "https://files.pythonhosted.org/packages/9d/e4/9263b8240ed9472a2ae7ddc3e516e71ef46617fe40eaa51221ccd4ad9a27/charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1", size = 139128 }, - { url = "https://files.pythonhosted.org/packages/6b/e3/9f73e779315a54334240353eaea75854a9a690f3f580e4bd85d977cb2204/charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03", size = 149277 }, - { url = "https://files.pythonhosted.org/packages/1a/cf/f1f50c2f295312edb8a548d3fa56a5c923b146cd3f24114d5adb7e7be558/charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284", size = 142174 }, - { url = "https://files.pythonhosted.org/packages/16/92/92a76dc2ff3a12e69ba94e7e05168d37d0345fa08c87e1fe24d0c2a42223/charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15", size = 143838 }, - { url = "https://files.pythonhosted.org/packages/a4/01/2117ff2b1dfc61695daf2babe4a874bca328489afa85952440b59819e9d7/charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8", size = 146149 }, - { url = "https://files.pythonhosted.org/packages/f6/9b/93a332b8d25b347f6839ca0a61b7f0287b0930216994e8bf67a75d050255/charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2", size = 140043 }, - { url = "https://files.pythonhosted.org/packages/ab/f6/7ac4a01adcdecbc7a7587767c776d53d369b8b971382b91211489535acf0/charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719", size = 148229 }, - { url = "https://files.pythonhosted.org/packages/9d/be/5708ad18161dee7dc6a0f7e6cf3a88ea6279c3e8484844c0590e50e803ef/charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631", size = 151556 }, - { url = "https://files.pythonhosted.org/packages/5a/bb/3d8bc22bacb9eb89785e83e6723f9888265f3a0de3b9ce724d66bd49884e/charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b", size = 149772 }, - { url = "https://files.pythonhosted.org/packages/f7/fa/d3fc622de05a86f30beea5fc4e9ac46aead4731e73fd9055496732bcc0a4/charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565", size = 144800 }, - { url = "https://files.pythonhosted.org/packages/9a/65/bdb9bc496d7d190d725e96816e20e2ae3a6fa42a5cac99c3c3d6ff884118/charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7", size = 94836 }, - { url = "https://files.pythonhosted.org/packages/3e/67/7b72b69d25b89c0b3cea583ee372c43aa24df15f0e0f8d3982c57804984b/charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9", size = 102187 }, - { url = "https://files.pythonhosted.org/packages/f3/89/68a4c86f1a0002810a27f12e9a7b22feb198c59b2f05231349fbce5c06f4/charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114", size = 194617 }, - { url = "https://files.pythonhosted.org/packages/4f/cd/8947fe425e2ab0aa57aceb7807af13a0e4162cd21eee42ef5b053447edf5/charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed", size = 125310 }, - { url = "https://files.pythonhosted.org/packages/5b/f0/b5263e8668a4ee9becc2b451ed909e9c27058337fda5b8c49588183c267a/charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250", size = 119126 }, - { url = "https://files.pythonhosted.org/packages/ff/6e/e445afe4f7fda27a533f3234b627b3e515a1b9429bc981c9a5e2aa5d97b6/charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920", size = 139342 }, - { url = "https://files.pythonhosted.org/packages/a1/b2/4af9993b532d93270538ad4926c8e37dc29f2111c36f9c629840c57cd9b3/charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64", size = 149383 }, - { url = "https://files.pythonhosted.org/packages/fb/6f/4e78c3b97686b871db9be6f31d64e9264e889f8c9d7ab33c771f847f79b7/charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23", size = 142214 }, - { url = "https://files.pythonhosted.org/packages/2b/c9/1c8fe3ce05d30c87eff498592c89015b19fade13df42850aafae09e94f35/charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc", size = 144104 }, - { url = "https://files.pythonhosted.org/packages/ee/68/efad5dcb306bf37db7db338338e7bb8ebd8cf38ee5bbd5ceaaaa46f257e6/charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d", size = 146255 }, - { url = "https://files.pythonhosted.org/packages/0c/75/1ed813c3ffd200b1f3e71121c95da3f79e6d2a96120163443b3ad1057505/charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88", size = 140251 }, - { url = "https://files.pythonhosted.org/packages/7d/0d/6f32255c1979653b448d3c709583557a4d24ff97ac4f3a5be156b2e6a210/charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90", size = 148474 }, - { url = "https://files.pythonhosted.org/packages/ac/a0/c1b5298de4670d997101fef95b97ac440e8c8d8b4efa5a4d1ef44af82f0d/charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b", size = 151849 }, - { url = "https://files.pythonhosted.org/packages/04/4f/b3961ba0c664989ba63e30595a3ed0875d6790ff26671e2aae2fdc28a399/charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d", size = 149781 }, - { url = "https://files.pythonhosted.org/packages/d8/90/6af4cd042066a4adad58ae25648a12c09c879efa4849c705719ba1b23d8c/charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482", size = 144970 }, - { url = "https://files.pythonhosted.org/packages/cc/67/e5e7e0cbfefc4ca79025238b43cdf8a2037854195b37d6417f3d0895c4c2/charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67", size = 94973 }, - { url = "https://files.pythonhosted.org/packages/65/97/fc9bbc54ee13d33dc54a7fcf17b26368b18505500fc01e228c27b5222d80/charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b", size = 102308 }, - { url = "https://files.pythonhosted.org/packages/bf/9b/08c0432272d77b04803958a4598a51e2a4b51c06640af8b8f0f908c18bf2/charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079", size = 49446 }, + { url = "https://files.pythonhosted.org/packages/72/80/41ef5d5a7935d2d3a773e3eaebf0a9350542f2cab4eac59a7a4741fbbbbe/charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125", size = 194995 }, + { url = "https://files.pythonhosted.org/packages/7a/28/0b9fefa7b8b080ec492110af6d88aa3dea91c464b17d53474b6e9ba5d2c5/charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1", size = 139471 }, + { url = "https://files.pythonhosted.org/packages/71/64/d24ab1a997efb06402e3fc07317e94da358e2585165930d9d59ad45fcae2/charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3", size = 149831 }, + { url = "https://files.pythonhosted.org/packages/37/ed/be39e5258e198655240db5e19e0b11379163ad7070962d6b0c87ed2c4d39/charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd", size = 142335 }, + { url = "https://files.pythonhosted.org/packages/88/83/489e9504711fa05d8dde1574996408026bdbdbd938f23be67deebb5eca92/charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00", size = 143862 }, + { url = "https://files.pythonhosted.org/packages/c6/c7/32da20821cf387b759ad24627a9aca289d2822de929b8a41b6241767b461/charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12", size = 145673 }, + { url = "https://files.pythonhosted.org/packages/68/85/f4288e96039abdd5aeb5c546fa20a37b50da71b5cf01e75e87f16cd43304/charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77", size = 140211 }, + { url = "https://files.pythonhosted.org/packages/28/a3/a42e70d03cbdabc18997baf4f0227c73591a08041c149e710045c281f97b/charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146", size = 148039 }, + { url = "https://files.pythonhosted.org/packages/85/e4/65699e8ab3014ecbe6f5c71d1a55d810fb716bbfd74f6283d5c2aa87febf/charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd", size = 151939 }, + { url = "https://files.pythonhosted.org/packages/b1/82/8e9fe624cc5374193de6860aba3ea8070f584c8565ee77c168ec13274bd2/charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6", size = 149075 }, + { url = "https://files.pythonhosted.org/packages/3d/7b/82865ba54c765560c8433f65e8acb9217cb839a9e32b42af4aa8e945870f/charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8", size = 144340 }, + { url = "https://files.pythonhosted.org/packages/b5/b6/9674a4b7d4d99a0d2df9b215da766ee682718f88055751e1e5e753c82db0/charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b", size = 95205 }, + { url = "https://files.pythonhosted.org/packages/1e/ab/45b180e175de4402dcf7547e4fb617283bae54ce35c27930a6f35b6bef15/charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76", size = 102441 }, + { url = "https://files.pythonhosted.org/packages/0a/9a/dd1e1cdceb841925b7798369a09279bd1cf183cef0f9ddf15a3a6502ee45/charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545", size = 196105 }, + { url = "https://files.pythonhosted.org/packages/d3/8c/90bfabf8c4809ecb648f39794cf2a84ff2e7d2a6cf159fe68d9a26160467/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7", size = 140404 }, + { url = "https://files.pythonhosted.org/packages/ad/8f/e410d57c721945ea3b4f1a04b74f70ce8fa800d393d72899f0a40526401f/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757", size = 150423 }, + { url = "https://files.pythonhosted.org/packages/f0/b8/e6825e25deb691ff98cf5c9072ee0605dc2acfca98af70c2d1b1bc75190d/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa", size = 143184 }, + { url = "https://files.pythonhosted.org/packages/3e/a2/513f6cbe752421f16d969e32f3583762bfd583848b763913ddab8d9bfd4f/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d", size = 145268 }, + { url = "https://files.pythonhosted.org/packages/74/94/8a5277664f27c3c438546f3eb53b33f5b19568eb7424736bdc440a88a31f/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616", size = 147601 }, + { url = "https://files.pythonhosted.org/packages/7c/5f/6d352c51ee763623a98e31194823518e09bfa48be2a7e8383cf691bbb3d0/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b", size = 141098 }, + { url = "https://files.pythonhosted.org/packages/78/d4/f5704cb629ba5ab16d1d3d741396aec6dc3ca2b67757c45b0599bb010478/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d", size = 149520 }, + { url = "https://files.pythonhosted.org/packages/c5/96/64120b1d02b81785f222b976c0fb79a35875457fa9bb40827678e54d1bc8/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a", size = 152852 }, + { url = "https://files.pythonhosted.org/packages/84/c9/98e3732278a99f47d487fd3468bc60b882920cef29d1fa6ca460a1fdf4e6/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9", size = 150488 }, + { url = "https://files.pythonhosted.org/packages/13/0e/9c8d4cb99c98c1007cc11eda969ebfe837bbbd0acdb4736d228ccaabcd22/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1", size = 146192 }, + { url = "https://files.pythonhosted.org/packages/b2/21/2b6b5b860781a0b49427309cb8670785aa543fb2178de875b87b9cc97746/charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35", size = 95550 }, + { url = "https://files.pythonhosted.org/packages/21/5b/1b390b03b1d16c7e382b561c5329f83cc06623916aab983e8ab9239c7d5c/charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f", size = 102785 }, + { url = "https://files.pythonhosted.org/packages/38/94/ce8e6f63d18049672c76d07d119304e1e2d7c6098f0841b51c666e9f44a0/charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda", size = 195698 }, + { url = "https://files.pythonhosted.org/packages/24/2e/dfdd9770664aae179a96561cc6952ff08f9a8cd09a908f259a9dfa063568/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313", size = 140162 }, + { url = "https://files.pythonhosted.org/packages/24/4e/f646b9093cff8fc86f2d60af2de4dc17c759de9d554f130b140ea4738ca6/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9", size = 150263 }, + { url = "https://files.pythonhosted.org/packages/5e/67/2937f8d548c3ef6e2f9aab0f6e21001056f692d43282b165e7c56023e6dd/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b", size = 142966 }, + { url = "https://files.pythonhosted.org/packages/52/ed/b7f4f07de100bdb95c1756d3a4d17b90c1a3c53715c1a476f8738058e0fa/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11", size = 144992 }, + { url = "https://files.pythonhosted.org/packages/96/2c/d49710a6dbcd3776265f4c923bb73ebe83933dfbaa841c5da850fe0fd20b/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f", size = 147162 }, + { url = "https://files.pythonhosted.org/packages/b4/41/35ff1f9a6bd380303dea55e44c4933b4cc3c4850988927d4082ada230273/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd", size = 140972 }, + { url = "https://files.pythonhosted.org/packages/fb/43/c6a0b685fe6910d08ba971f62cd9c3e862a85770395ba5d9cad4fede33ab/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2", size = 149095 }, + { url = "https://files.pythonhosted.org/packages/4c/ff/a9a504662452e2d2878512115638966e75633519ec11f25fca3d2049a94a/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886", size = 152668 }, + { url = "https://files.pythonhosted.org/packages/6c/71/189996b6d9a4b932564701628af5cee6716733e9165af1d5e1b285c530ed/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601", size = 150073 }, + { url = "https://files.pythonhosted.org/packages/e4/93/946a86ce20790e11312c87c75ba68d5f6ad2208cfb52b2d6a2c32840d922/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd", size = 145732 }, + { url = "https://files.pythonhosted.org/packages/cd/e5/131d2fb1b0dddafc37be4f3a2fa79aa4c037368be9423061dccadfd90091/charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407", size = 95391 }, + { url = "https://files.pythonhosted.org/packages/27/f2/4f9a69cc7712b9b5ad8fdb87039fd89abba997ad5cbe690d1835d40405b0/charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971", size = 102702 }, + { url = "https://files.pythonhosted.org/packages/0e/f6/65ecc6878a89bb1c23a086ea335ad4bf21a588990c3f535a227b9eea9108/charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85", size = 49767 }, ] [[package]] @@ -468,7 +461,7 @@ wheels = [ [[package]] name = "flask" -version = "3.0.3" +version = "3.1.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "blinker" }, @@ -477,9 +470,9 @@ dependencies = [ { name = "jinja2" }, { name = "werkzeug" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/41/e1/d104c83026f8d35dfd2c261df7d64738341067526406b40190bc063e829a/flask-3.0.3.tar.gz", hash = "sha256:ceb27b0af3823ea2737928a4d99d125a06175b8512c445cbd9a9ce200ef76842", size = 676315 } +sdist = { url = "https://files.pythonhosted.org/packages/89/50/dff6380f1c7f84135484e176e0cac8690af72fa90e932ad2a0a60e28c69b/flask-3.1.0.tar.gz", hash = "sha256:5f873c5184c897c8d9d1b05df1e3d01b14910ce69607a117bd3277098a5836ac", size = 680824 } wheels = [ - { url = "https://files.pythonhosted.org/packages/61/80/ffe1da13ad9300f87c93af113edd0638c75138c42a0994becfacac078c06/flask-3.0.3-py3-none-any.whl", hash = "sha256:34e815dfaa43340d1d15a5c3a02b8476004037eb4840b34910c6e21679d288f3", size = 101735 }, + { url = "https://files.pythonhosted.org/packages/af/47/93213ee66ef8fae3b93b3e29206f6b251e65c97bd91d8e1c5596ef15af0a/flask-3.1.0-py3-none-any.whl", hash = "sha256:d667207822eb83f1c4b50949b1623c8fc8d51f2341d65f72e1a1815397551136", size = 102979 }, ] [[package]] @@ -550,38 +543,38 @@ wheels = [ [[package]] name = "gitdb" -version = "4.0.11" +version = "4.0.12" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "smmap" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/19/0d/bbb5b5ee188dec84647a4664f3e11b06ade2bde568dbd489d9d64adef8ed/gitdb-4.0.11.tar.gz", hash = "sha256:bf5421126136d6d0af55bc1e7c1af1c397a34f5b7bd79e776cd3e89785c2b04b", size = 394469 } +sdist = { url = "https://files.pythonhosted.org/packages/72/94/63b0fc47eb32792c7ba1fe1b694daec9a63620db1e313033d18140c2320a/gitdb-4.0.12.tar.gz", hash = "sha256:5ef71f855d191a3326fcfbc0d5da835f26b13fbcba60c32c21091c349ffdb571", size = 394684 } wheels = [ - { url = "https://files.pythonhosted.org/packages/fd/5b/8f0c4a5bb9fd491c277c21eff7ccae71b47d43c4446c9d0c6cff2fe8c2c4/gitdb-4.0.11-py3-none-any.whl", hash = "sha256:81a3407ddd2ee8df444cbacea00e2d038e40150acfa3001696fe0dcf1d3adfa4", size = 62721 }, + { url = "https://files.pythonhosted.org/packages/a0/61/5c78b91c3143ed5c14207f463aecfc8f9dbb5092fb2869baf37c273b2705/gitdb-4.0.12-py3-none-any.whl", hash = "sha256:67073e15955400952c6565cc3e707c554a4eea2e428946f7a4c162fab9bd9bcf", size = 62794 }, ] [[package]] name = "gitpython" -version = "3.1.43" +version = "3.1.44" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "gitdb" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/b6/a1/106fd9fa2dd989b6fb36e5893961f82992cf676381707253e0bf93eb1662/GitPython-3.1.43.tar.gz", hash = "sha256:35f314a9f878467f5453cc1fee295c3e18e52f1b99f10f6cf5b1682e968a9e7c", size = 214149 } +sdist = { url = "https://files.pythonhosted.org/packages/c0/89/37df0b71473153574a5cdef8f242de422a0f5d26d7a9e231e6f169b4ad14/gitpython-3.1.44.tar.gz", hash = "sha256:c87e30b26253bf5418b01b0660f818967f3c503193838337fe5e573331249269", size = 214196 } wheels = [ - { url = "https://files.pythonhosted.org/packages/e9/bd/cc3a402a6439c15c3d4294333e13042b915bbeab54edc457c723931fed3f/GitPython-3.1.43-py3-none-any.whl", hash = "sha256:eec7ec56b92aad751f9912a73404bc02ba212a23adb2c7098ee668417051a1ff", size = 207337 }, + { url = "https://files.pythonhosted.org/packages/1d/9a/4114a9057db2f1462d5c8f8390ab7383925fe1ac012eaa42402ad65c2963/GitPython-3.1.44-py3-none-any.whl", hash = "sha256:9e0e10cda9bed1ee64bc9a6de50e7e38a9c9943241cd7f585f6df3ed28011110", size = 207599 }, ] [[package]] name = "griffe" -version = "1.3.2" +version = "1.5.5" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/c2/37/813e72a3458fa3d996cf6bcc6a0caa919d16540f873366b0d328d51d684a/griffe-1.3.2.tar.gz", hash = "sha256:1ec50335aa507ed2445f2dd45a15c9fa3a45f52c9527e880571dfc61912fd60c", size = 382540 } +sdist = { url = "https://files.pythonhosted.org/packages/5c/74/cd35a98cb11f79de0581e8e1e6fbd738aeeed1f2d90e9b5106728b63f5f7/griffe-1.5.5.tar.gz", hash = "sha256:35ee5b38b93d6a839098aad0f92207e6ad6b70c3e8866c08ca669275b8cba585", size = 391124 } wheels = [ - { url = "https://files.pythonhosted.org/packages/2a/49/39967633dd3c5f06fde83fec140228671a7344289ece0cfdd3cbe4798d69/griffe-1.3.2-py3-none-any.whl", hash = "sha256:2e34b5e46507d615915c8e6288bb1a2234bd35dee44d01e40a2bc2f25bd4d10c", size = 126992 }, + { url = "https://files.pythonhosted.org/packages/1f/88/52c9422bc853cd7c2b6122090e887d17b5fad29b67f930e4277c9c557357/griffe-1.5.5-py3-none-any.whl", hash = "sha256:2761b1e8876c6f1f9ab1af274df93ea6bbadd65090de5f38f4cb5cc84897c7dd", size = 128221 }, ] [[package]] @@ -598,7 +591,7 @@ name = "importlib-metadata" version = "8.5.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "zipp", marker = "python_full_version >= '3.12'" }, + { name = "zipp" }, ] sdist = { url = "https://files.pythonhosted.org/packages/cd/12/33e59336dca5be0c398a7482335911a33aa0e20776128f038019f1a95f1b/importlib_metadata-8.5.0.tar.gz", hash = "sha256:71522656f0abace1d072b9e5481a48f07c138e00f079c38c8f883823f9c26bd7", size = 55304 } wheels = [ @@ -625,14 +618,14 @@ wheels = [ [[package]] name = "jinja2" -version = "3.1.4" +version = "3.1.5" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "markupsafe" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ed/55/39036716d19cab0747a5020fc7e907f362fbf48c984b14e62127f7e68e5d/jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369", size = 240245 } +sdist = { url = "https://files.pythonhosted.org/packages/af/92/b3130cbbf5591acf9ade8708c365f3238046ac7cb8ccba6e81abccb0ccff/jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb", size = 244674 } wheels = [ - { url = "https://files.pythonhosted.org/packages/31/80/3a54838c3fb461f6fec263ebf3a3a41771bd05190238de3486aae8540c36/jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d", size = 133271 }, + { url = "https://files.pythonhosted.org/packages/bd/0f/2ba5fbcd631e3e88689309dbe978c5769e883e4b84ebfe7da30b43275c5a/jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb", size = 134596 }, ] [[package]] @@ -658,63 +651,63 @@ wheels = [ [[package]] name = "markdownify" -version = "0.13.1" +version = "0.14.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "beautifulsoup4" }, { name = "six" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/19/5a/bd1b685ee9efbfb0b22774a30188dfb4048c64e8a6c80a65a7f207af4ea1/markdownify-0.13.1.tar.gz", hash = "sha256:ab257f9e6bd4075118828a28c9d02f8a4bfeb7421f558834aa79b2dfeb32a098", size = 13609 } +sdist = { url = "https://files.pythonhosted.org/packages/1b/75/483a4bcca436fe88d02dc7686c372631d833848951b368700bdc0c770bb7/markdownify-0.14.1.tar.gz", hash = "sha256:a62a7a216947ed0b8dafb95b99b2ef4a0edd1e18d5653c656f68f03db2bfb2f1", size = 14332 } wheels = [ - { url = "https://files.pythonhosted.org/packages/6c/e9/6e2757a670b8c48bc48eff1c20cb9d71f1476e844038bdbdb76f17e6a12b/markdownify-0.13.1-py3-none-any.whl", hash = "sha256:1d181d43d20902bcc69d7be85b5316ed174d0dda72ff56e14ae4c95a4a407d22", size = 10800 }, + { url = "https://files.pythonhosted.org/packages/65/0b/74cec93a7b05edf4fc3ea1c899fe8a37f041d7b9d303c75abf7a162924e0/markdownify-0.14.1-py3-none-any.whl", hash = "sha256:4c46a6c0c12c6005ddcd49b45a5a890398b002ef51380cd319db62df5e09bc2a", size = 11530 }, ] [[package]] name = "markupsafe" -version = "3.0.1" +version = "3.0.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b4/d2/38ff920762f2247c3af5cbbbbc40756f575d9692d381d7c520f45deb9b8f/markupsafe-3.0.1.tar.gz", hash = "sha256:3e683ee4f5d0fa2dde4db77ed8dd8a876686e3fc417655c2ece9a90576905344", size = 20249 } +sdist = { url = "https://files.pythonhosted.org/packages/b2/97/5d42485e71dfc078108a86d6de8fa46db44a1a9295e89c5d6d4a06e23a62/markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0", size = 20537 } wheels = [ - { url = "https://files.pythonhosted.org/packages/ce/af/2f5d88a7fc7226bd34c6e15f6061246ad8cff979da9f19d11bdd0addd8e2/MarkupSafe-3.0.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:26627785a54a947f6d7336ce5963569b5d75614619e75193bdb4e06e21d447ad", size = 14387 }, - { url = "https://files.pythonhosted.org/packages/8d/43/fd588ef5d192308c5e05974bac659bf6ae29c202b7ea2c4194bcf01eacee/MarkupSafe-3.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b954093679d5750495725ea6f88409946d69cfb25ea7b4c846eef5044194f583", size = 12410 }, - { url = "https://files.pythonhosted.org/packages/58/26/78f161d602fb03804118905e5faacafc0ec592bbad71aaee62537529813a/MarkupSafe-3.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:973a371a55ce9ed333a3a0f8e0bcfae9e0d637711534bcb11e130af2ab9334e7", size = 24006 }, - { url = "https://files.pythonhosted.org/packages/ae/1d/7d5ec8bcfd9c2db235d720fa51d818b7e2abc45250ce5f53dd6cb60409ca/MarkupSafe-3.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:244dbe463d5fb6d7ce161301a03a6fe744dac9072328ba9fc82289238582697b", size = 23303 }, - { url = "https://files.pythonhosted.org/packages/26/ce/703ca3b03a709e3bd1fbffa407789e56b9fa664456538092617dd665fc1d/MarkupSafe-3.0.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d98e66a24497637dd31ccab090b34392dddb1f2f811c4b4cd80c230205c074a3", size = 23205 }, - { url = "https://files.pythonhosted.org/packages/88/60/40be0493decabc2344b12d3a709fd6ccdd15a5ebaee1e8d878315d107ad3/MarkupSafe-3.0.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ad91738f14eb8da0ff82f2acd0098b6257621410dcbd4df20aaa5b4233d75a50", size = 23684 }, - { url = "https://files.pythonhosted.org/packages/6d/f8/8fd52a66e8f62a9add62b4a0b5a3ab4092027437f2ef027f812d94ae91cf/MarkupSafe-3.0.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:7044312a928a66a4c2a22644147bc61a199c1709712069a344a3fb5cfcf16915", size = 23472 }, - { url = "https://files.pythonhosted.org/packages/d4/0b/998b17b9e06ea45ad1646fea586f1b83d02dfdb14d47dd2fd81fba5a08c9/MarkupSafe-3.0.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a4792d3b3a6dfafefdf8e937f14906a51bd27025a36f4b188728a73382231d91", size = 23388 }, - { url = "https://files.pythonhosted.org/packages/5a/57/b6b7aa23b2e26d68d601718f8ce3161fbdaf967b31752c7dec52bef828c9/MarkupSafe-3.0.1-cp311-cp311-win32.whl", hash = "sha256:fa7d686ed9883f3d664d39d5a8e74d3c5f63e603c2e3ff0abcba23eac6542635", size = 15106 }, - { url = "https://files.pythonhosted.org/packages/fc/b5/20cb1d714596acb553c810009c8004c809823947da63e13c19a7decfcb6c/MarkupSafe-3.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:9ba25a71ebf05b9bb0e2ae99f8bc08a07ee8e98c612175087112656ca0f5c8bf", size = 15542 }, - { url = "https://files.pythonhosted.org/packages/45/6d/72ed58d42a12bd9fc288dbff6dd8d03ea973a232ac0538d7f88d105b5251/MarkupSafe-3.0.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:8ae369e84466aa70f3154ee23c1451fda10a8ee1b63923ce76667e3077f2b0c4", size = 14322 }, - { url = "https://files.pythonhosted.org/packages/86/f5/241238f89cdd6461ac9f521af8389f9a48fab97e4f315c69e9e0d52bc919/MarkupSafe-3.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40f1e10d51c92859765522cbd79c5c8989f40f0419614bcdc5015e7b6bf97fc5", size = 12380 }, - { url = "https://files.pythonhosted.org/packages/27/94/79751928bca5841416d8ca02e22198672e021d5c7120338e2a6e3771f8fc/MarkupSafe-3.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5a4cb365cb49b750bdb60b846b0c0bc49ed62e59a76635095a179d440540c346", size = 24099 }, - { url = "https://files.pythonhosted.org/packages/10/6e/1b8070bbfc467429c7983cd5ffd4ec57e1d501763d974c7caaa0a9a79f4c/MarkupSafe-3.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ee3941769bd2522fe39222206f6dd97ae83c442a94c90f2b7a25d847d40f4729", size = 23249 }, - { url = "https://files.pythonhosted.org/packages/66/50/9389ae6cdff78d7481a2a2641830b5eb1d1f62177550e73355a810a889c9/MarkupSafe-3.0.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:62fada2c942702ef8952754abfc1a9f7658a4d5460fabe95ac7ec2cbe0d02abc", size = 23149 }, - { url = "https://files.pythonhosted.org/packages/16/02/5dddff5366fde47133186efb847fa88bddef85914bbe623e25cfeccb3517/MarkupSafe-3.0.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:4c2d64fdba74ad16138300815cfdc6ab2f4647e23ced81f59e940d7d4a1469d9", size = 23864 }, - { url = "https://files.pythonhosted.org/packages/f3/f1/700ee6655561cfda986e03f7afc309e3738918551afa7dedd99225586227/MarkupSafe-3.0.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:fb532dd9900381d2e8f48172ddc5a59db4c445a11b9fab40b3b786da40d3b56b", size = 23440 }, - { url = "https://files.pythonhosted.org/packages/fb/3e/d26623ac7f16709823b4c80e0b4a1c9196eeb46182a6c1d47b5e0c8434f4/MarkupSafe-3.0.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0f84af7e813784feb4d5e4ff7db633aba6c8ca64a833f61d8e4eade234ef0c38", size = 23610 }, - { url = "https://files.pythonhosted.org/packages/51/04/1f8da0810c39cb9fcff96b6baed62272c97065e9cf11471965a161439e20/MarkupSafe-3.0.1-cp312-cp312-win32.whl", hash = "sha256:cbf445eb5628981a80f54087f9acdbf84f9b7d862756110d172993b9a5ae81aa", size = 15113 }, - { url = "https://files.pythonhosted.org/packages/eb/24/a36dc37365bdd358b1e583cc40475593e36ab02cb7da6b3d0b9c05b0da7a/MarkupSafe-3.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:a10860e00ded1dd0a65b83e717af28845bb7bd16d8ace40fe5531491de76b79f", size = 15611 }, - { url = "https://files.pythonhosted.org/packages/b1/60/4572a8aa1beccbc24b133aa0670781a5d2697f4fa3fecf0a87b46383174b/MarkupSafe-3.0.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:e81c52638315ff4ac1b533d427f50bc0afc746deb949210bc85f05d4f15fd772", size = 14325 }, - { url = "https://files.pythonhosted.org/packages/38/42/849915b99a765ec104bfd07ee933de5fc9c58fa9570efa7db81717f495d8/MarkupSafe-3.0.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:312387403cd40699ab91d50735ea7a507b788091c416dd007eac54434aee51da", size = 12373 }, - { url = "https://files.pythonhosted.org/packages/ef/82/4caaebd963c6d60b28e4445f38841d24f8b49bc10594a09956c9d73bfc08/MarkupSafe-3.0.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2ae99f31f47d849758a687102afdd05bd3d3ff7dbab0a8f1587981b58a76152a", size = 24059 }, - { url = "https://files.pythonhosted.org/packages/20/15/6b319be2f79fcfa3173f479d69f4e950b5c9b642db4f22cf73ae5ade745f/MarkupSafe-3.0.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c97ff7fedf56d86bae92fa0a646ce1a0ec7509a7578e1ed238731ba13aabcd1c", size = 23211 }, - { url = "https://files.pythonhosted.org/packages/9d/3f/8963bdf4962feb2154475acb7dc350f04217b5e0be7763a39b432291e229/MarkupSafe-3.0.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a7420ceda262dbb4b8d839a4ec63d61c261e4e77677ed7c66c99f4e7cb5030dd", size = 23095 }, - { url = "https://files.pythonhosted.org/packages/af/93/f770bc70953d32de0c6ce4bcb76271512123a1ead91aaef625a020c5bfaf/MarkupSafe-3.0.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:45d42d132cff577c92bfba536aefcfea7e26efb975bd455db4e6602f5c9f45e7", size = 23901 }, - { url = "https://files.pythonhosted.org/packages/11/92/1e5a33aa0a1190161238628fb68eb1bc5e67b56a5c89f0636328704b463a/MarkupSafe-3.0.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:4c8817557d0de9349109acb38b9dd570b03cc5014e8aabf1cbddc6e81005becd", size = 23463 }, - { url = "https://files.pythonhosted.org/packages/0d/fe/657efdfe385d2a3a701f2c4fcc9577c63c438aeefdd642d0d956c4ecd225/MarkupSafe-3.0.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6a54c43d3ec4cf2a39f4387ad044221c66a376e58c0d0e971d47c475ba79c6b5", size = 23569 }, - { url = "https://files.pythonhosted.org/packages/cf/24/587dea40304046ace60f846cedaebc0d33d967a3ce46c11395a10e7a78ba/MarkupSafe-3.0.1-cp313-cp313-win32.whl", hash = "sha256:c91b394f7601438ff79a4b93d16be92f216adb57d813a78be4446fe0f6bc2d8c", size = 15117 }, - { url = "https://files.pythonhosted.org/packages/32/8f/d8961d633f26a011b4fe054f3bfff52f673423b8c431553268741dfb089e/MarkupSafe-3.0.1-cp313-cp313-win_amd64.whl", hash = "sha256:fe32482b37b4b00c7a52a07211b479653b7fe4f22b2e481b9a9b099d8a430f2f", size = 15613 }, - { url = "https://files.pythonhosted.org/packages/9e/93/d6367ffbcd0c5c371370767f768eaa32af60bc411245b8517e383c6a2b12/MarkupSafe-3.0.1-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:17b2aea42a7280db02ac644db1d634ad47dcc96faf38ab304fe26ba2680d359a", size = 14563 }, - { url = "https://files.pythonhosted.org/packages/4a/37/f813c3835747dec08fe19ac9b9eced01fdf93a4b3e626521675dc7f423a9/MarkupSafe-3.0.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:852dc840f6d7c985603e60b5deaae1d89c56cb038b577f6b5b8c808c97580f1d", size = 12505 }, - { url = "https://files.pythonhosted.org/packages/72/bf/800b4d1580298ca91ccd6c95915bbd147142dad1b8cf91d57b93b28670dd/MarkupSafe-3.0.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0778de17cff1acaeccc3ff30cd99a3fd5c50fc58ad3d6c0e0c4c58092b859396", size = 25358 }, - { url = "https://files.pythonhosted.org/packages/fd/78/26e209abc8f0a379f031f0acc151231974e5b153d7eda5759d17d8f329f2/MarkupSafe-3.0.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:800100d45176652ded796134277ecb13640c1a537cad3b8b53da45aa96330453", size = 23797 }, - { url = "https://files.pythonhosted.org/packages/09/e1/918496a9390891756efee818880e71c1bbaf587f4dc8ede3f3852357310a/MarkupSafe-3.0.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d06b24c686a34c86c8c1fba923181eae6b10565e4d80bdd7bc1c8e2f11247aa4", size = 23743 }, - { url = "https://files.pythonhosted.org/packages/cd/c6/26f576cd58d6c2decd9045e4e3f3c5dbc01ea6cb710916e7bbb6ebd95b6b/MarkupSafe-3.0.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:33d1c36b90e570ba7785dacd1faaf091203d9942bc036118fab8110a401eb1a8", size = 25076 }, - { url = "https://files.pythonhosted.org/packages/b5/fa/10b24fb3b0e15fe5389dc88ecc6226ede08297e0ba7130610efbe0cdfb27/MarkupSafe-3.0.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:beeebf760a9c1f4c07ef6a53465e8cfa776ea6a2021eda0d0417ec41043fe984", size = 24037 }, - { url = "https://files.pythonhosted.org/packages/c8/81/4b3f5537d9f6cc4f5c80d6c4b78af9a5247fd37b5aba95807b2cbc336b9a/MarkupSafe-3.0.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:bbde71a705f8e9e4c3e9e33db69341d040c827c7afa6789b14c6e16776074f5a", size = 24015 }, - { url = "https://files.pythonhosted.org/packages/5f/07/8e8dcecd53216c5e01a51e84c32a2bce166690ed19c184774b38cd41921d/MarkupSafe-3.0.1-cp313-cp313t-win32.whl", hash = "sha256:82b5dba6eb1bcc29cc305a18a3c5365d2af06ee71b123216416f7e20d2a84e5b", size = 15213 }, - { url = "https://files.pythonhosted.org/packages/0d/87/4c364e0f109eea2402079abecbe33fef4f347b551a11423d1f4e187ea497/MarkupSafe-3.0.1-cp313-cp313t-win_amd64.whl", hash = "sha256:730d86af59e0e43ce277bb83970530dd223bf7f2a838e086b50affa6ec5f9295", size = 15741 }, + { url = "https://files.pythonhosted.org/packages/6b/28/bbf83e3f76936960b850435576dd5e67034e200469571be53f69174a2dfd/MarkupSafe-3.0.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9025b4018f3a1314059769c7bf15441064b2207cb3f065e6ea1e7359cb46db9d", size = 14353 }, + { url = "https://files.pythonhosted.org/packages/6c/30/316d194b093cde57d448a4c3209f22e3046c5bb2fb0820b118292b334be7/MarkupSafe-3.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:93335ca3812df2f366e80509ae119189886b0f3c2b81325d39efdb84a1e2ae93", size = 12392 }, + { url = "https://files.pythonhosted.org/packages/f2/96/9cdafba8445d3a53cae530aaf83c38ec64c4d5427d975c974084af5bc5d2/MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2cb8438c3cbb25e220c2ab33bb226559e7afb3baec11c4f218ffa7308603c832", size = 23984 }, + { url = "https://files.pythonhosted.org/packages/f1/a4/aefb044a2cd8d7334c8a47d3fb2c9f328ac48cb349468cc31c20b539305f/MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a123e330ef0853c6e822384873bef7507557d8e4a082961e1defa947aa59ba84", size = 23120 }, + { url = "https://files.pythonhosted.org/packages/8d/21/5e4851379f88f3fad1de30361db501300d4f07bcad047d3cb0449fc51f8c/MarkupSafe-3.0.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e084f686b92e5b83186b07e8a17fc09e38fff551f3602b249881fec658d3eca", size = 23032 }, + { url = "https://files.pythonhosted.org/packages/00/7b/e92c64e079b2d0d7ddf69899c98842f3f9a60a1ae72657c89ce2655c999d/MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d8213e09c917a951de9d09ecee036d5c7d36cb6cb7dbaece4c71a60d79fb9798", size = 24057 }, + { url = "https://files.pythonhosted.org/packages/f9/ac/46f960ca323037caa0a10662ef97d0a4728e890334fc156b9f9e52bcc4ca/MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:5b02fb34468b6aaa40dfc198d813a641e3a63b98c2b05a16b9f80b7ec314185e", size = 23359 }, + { url = "https://files.pythonhosted.org/packages/69/84/83439e16197337b8b14b6a5b9c2105fff81d42c2a7c5b58ac7b62ee2c3b1/MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0bff5e0ae4ef2e1ae4fdf2dfd5b76c75e5c2fa4132d05fc1b0dabcd20c7e28c4", size = 23306 }, + { url = "https://files.pythonhosted.org/packages/9a/34/a15aa69f01e2181ed8d2b685c0d2f6655d5cca2c4db0ddea775e631918cd/MarkupSafe-3.0.2-cp311-cp311-win32.whl", hash = "sha256:6c89876f41da747c8d3677a2b540fb32ef5715f97b66eeb0c6b66f5e3ef6f59d", size = 15094 }, + { url = "https://files.pythonhosted.org/packages/da/b8/3a3bd761922d416f3dc5d00bfbed11f66b1ab89a0c2b6e887240a30b0f6b/MarkupSafe-3.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:70a87b411535ccad5ef2f1df5136506a10775d267e197e4cf531ced10537bd6b", size = 15521 }, + { url = "https://files.pythonhosted.org/packages/22/09/d1f21434c97fc42f09d290cbb6350d44eb12f09cc62c9476effdb33a18aa/MarkupSafe-3.0.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:9778bd8ab0a994ebf6f84c2b949e65736d5575320a17ae8984a77fab08db94cf", size = 14274 }, + { url = "https://files.pythonhosted.org/packages/6b/b0/18f76bba336fa5aecf79d45dcd6c806c280ec44538b3c13671d49099fdd0/MarkupSafe-3.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:846ade7b71e3536c4e56b386c2a47adf5741d2d8b94ec9dc3e92e5e1ee1e2225", size = 12348 }, + { url = "https://files.pythonhosted.org/packages/e0/25/dd5c0f6ac1311e9b40f4af06c78efde0f3b5cbf02502f8ef9501294c425b/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c99d261bd2d5f6b59325c92c73df481e05e57f19837bdca8413b9eac4bd8028", size = 24149 }, + { url = "https://files.pythonhosted.org/packages/f3/f0/89e7aadfb3749d0f52234a0c8c7867877876e0a20b60e2188e9850794c17/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8", size = 23118 }, + { url = "https://files.pythonhosted.org/packages/d5/da/f2eeb64c723f5e3777bc081da884b414671982008c47dcc1873d81f625b6/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:88416bd1e65dcea10bc7569faacb2c20ce071dd1f87539ca2ab364bf6231393c", size = 22993 }, + { url = "https://files.pythonhosted.org/packages/da/0e/1f32af846df486dce7c227fe0f2398dc7e2e51d4a370508281f3c1c5cddc/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2181e67807fc2fa785d0592dc2d6206c019b9502410671cc905d132a92866557", size = 24178 }, + { url = "https://files.pythonhosted.org/packages/c4/f6/bb3ca0532de8086cbff5f06d137064c8410d10779c4c127e0e47d17c0b71/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:52305740fe773d09cffb16f8ed0427942901f00adedac82ec8b67752f58a1b22", size = 23319 }, + { url = "https://files.pythonhosted.org/packages/a2/82/8be4c96ffee03c5b4a034e60a31294daf481e12c7c43ab8e34a1453ee48b/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ad10d3ded218f1039f11a75f8091880239651b52e9bb592ca27de44eed242a48", size = 23352 }, + { url = "https://files.pythonhosted.org/packages/51/ae/97827349d3fcffee7e184bdf7f41cd6b88d9919c80f0263ba7acd1bbcb18/MarkupSafe-3.0.2-cp312-cp312-win32.whl", hash = "sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30", size = 15097 }, + { url = "https://files.pythonhosted.org/packages/c1/80/a61f99dc3a936413c3ee4e1eecac96c0da5ed07ad56fd975f1a9da5bc630/MarkupSafe-3.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87", size = 15601 }, + { url = "https://files.pythonhosted.org/packages/83/0e/67eb10a7ecc77a0c2bbe2b0235765b98d164d81600746914bebada795e97/MarkupSafe-3.0.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd", size = 14274 }, + { url = "https://files.pythonhosted.org/packages/2b/6d/9409f3684d3335375d04e5f05744dfe7e9f120062c9857df4ab490a1031a/MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430", size = 12352 }, + { url = "https://files.pythonhosted.org/packages/d2/f5/6eadfcd3885ea85fe2a7c128315cc1bb7241e1987443d78c8fe712d03091/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094", size = 24122 }, + { url = "https://files.pythonhosted.org/packages/0c/91/96cf928db8236f1bfab6ce15ad070dfdd02ed88261c2afafd4b43575e9e9/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396", size = 23085 }, + { url = "https://files.pythonhosted.org/packages/c2/cf/c9d56af24d56ea04daae7ac0940232d31d5a8354f2b457c6d856b2057d69/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79", size = 22978 }, + { url = "https://files.pythonhosted.org/packages/2a/9f/8619835cd6a711d6272d62abb78c033bda638fdc54c4e7f4272cf1c0962b/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a", size = 24208 }, + { url = "https://files.pythonhosted.org/packages/f9/bf/176950a1792b2cd2102b8ffeb5133e1ed984547b75db47c25a67d3359f77/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca", size = 23357 }, + { url = "https://files.pythonhosted.org/packages/ce/4f/9a02c1d335caabe5c4efb90e1b6e8ee944aa245c1aaaab8e8a618987d816/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c", size = 23344 }, + { url = "https://files.pythonhosted.org/packages/ee/55/c271b57db36f748f0e04a759ace9f8f759ccf22b4960c270c78a394f58be/MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1", size = 15101 }, + { url = "https://files.pythonhosted.org/packages/29/88/07df22d2dd4df40aba9f3e402e6dc1b8ee86297dddbad4872bd5e7b0094f/MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f", size = 15603 }, + { url = "https://files.pythonhosted.org/packages/62/6a/8b89d24db2d32d433dffcd6a8779159da109842434f1dd2f6e71f32f738c/MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c", size = 14510 }, + { url = "https://files.pythonhosted.org/packages/7a/06/a10f955f70a2e5a9bf78d11a161029d278eeacbd35ef806c3fd17b13060d/MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb", size = 12486 }, + { url = "https://files.pythonhosted.org/packages/34/cf/65d4a571869a1a9078198ca28f39fba5fbb910f952f9dbc5220afff9f5e6/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c", size = 25480 }, + { url = "https://files.pythonhosted.org/packages/0c/e3/90e9651924c430b885468b56b3d597cabf6d72be4b24a0acd1fa0e12af67/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d", size = 23914 }, + { url = "https://files.pythonhosted.org/packages/66/8c/6c7cf61f95d63bb866db39085150df1f2a5bd3335298f14a66b48e92659c/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe", size = 23796 }, + { url = "https://files.pythonhosted.org/packages/bb/35/cbe9238ec3f47ac9a7c8b3df7a808e7cb50fe149dc7039f5f454b3fba218/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5", size = 25473 }, + { url = "https://files.pythonhosted.org/packages/e6/32/7621a4382488aa283cc05e8984a9c219abad3bca087be9ec77e89939ded9/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a", size = 24114 }, + { url = "https://files.pythonhosted.org/packages/0d/80/0985960e4b89922cb5a0bac0ed39c5b96cbc1a536a99f30e8c220a996ed9/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9", size = 24098 }, + { url = "https://files.pythonhosted.org/packages/82/78/fedb03c7d5380df2427038ec8d973587e90561b2d90cd472ce9254cf348b/MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6", size = 15208 }, + { url = "https://files.pythonhosted.org/packages/4f/65/6079a46068dfceaeabb5dcad6d674f5f5c61a6fa5673746f42a9f4c233b3/MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f", size = 15739 }, ] [[package]] @@ -770,16 +763,16 @@ wheels = [ [[package]] name = "mkdocs-autorefs" -version = "1.2.0" +version = "1.3.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "markdown" }, { name = "markupsafe" }, { name = "mkdocs" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/fb/ae/0f1154c614d6a8b8a36fff084e5b82af3a15f7d2060cf0dcdb1c53297a71/mkdocs_autorefs-1.2.0.tar.gz", hash = "sha256:a86b93abff653521bda71cf3fc5596342b7a23982093915cb74273f67522190f", size = 40262 } +sdist = { url = "https://files.pythonhosted.org/packages/fe/18/fb1e17fb705228b51bf7b2f791adaf83c0fa708e51bbc003411ba48ae21e/mkdocs_autorefs-1.3.0.tar.gz", hash = "sha256:6867764c099ace9025d6ac24fd07b85a98335fbd30107ef01053697c8f46db61", size = 42597 } wheels = [ - { url = "https://files.pythonhosted.org/packages/71/26/4d39d52ea2219604053a4d05b98e90d6a335511cc01806436ec4886b1028/mkdocs_autorefs-1.2.0-py3-none-any.whl", hash = "sha256:d588754ae89bd0ced0c70c06f58566a4ee43471eeeee5202427da7de9ef85a2f", size = 16522 }, + { url = "https://files.pythonhosted.org/packages/f4/4a/960c441950f98becfa5dd419adab20274939fd575ab848aee2c87e3599ac/mkdocs_autorefs-1.3.0-py3-none-any.whl", hash = "sha256:d180f9778a04e78b7134e31418f238bba56f56d6a8af97873946ff661befffb3", size = 17642 }, ] [[package]] @@ -798,19 +791,19 @@ wheels = [ [[package]] name = "mkdocs-git-authors-plugin" -version = "0.9.0" +version = "0.9.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "mkdocs" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ac/03/99e18d62964d268eb9a866f42c9d53b43cde903a7fb436da85e396945a02/mkdocs_git_authors_plugin-0.9.0.tar.gz", hash = "sha256:6161f63b87064481a48d9ad01c23e43c3e758930c3a9cc167fe482909ceb9eac", size = 20268 } +sdist = { url = "https://files.pythonhosted.org/packages/80/ef/09ab7178d580e342cb3ba279c48eaf3abf55795a2ae6e5426fe2c725143c/mkdocs_git_authors_plugin-0.9.2.tar.gz", hash = "sha256:77f97c321e08a8757beb866293eb257070b11cd5a080976bc6696b249cbade4f", size = 21403 } wheels = [ - { url = "https://files.pythonhosted.org/packages/46/ad/a6e0ce34a1d9abe35844cdc3a64028d3df7bfe24b143021f7fcaa26adfdd/mkdocs_git_authors_plugin-0.9.0-py3-none-any.whl", hash = "sha256:380730a05eeb947a7e84be05fdb1c5ae2a7bc70fd9f6eda941f187c87ae37052", size = 19204 }, + { url = "https://files.pythonhosted.org/packages/48/08/57d0fea1cc30096fcc94ec9cd4ccdee625be89fd710626f78d90fc13738e/mkdocs_git_authors_plugin-0.9.2-py3-none-any.whl", hash = "sha256:f6cefc4dc832865d26f7f9f944c0a8c7dc852742d79320f3800e0d97814e2a84", size = 20332 }, ] [[package]] name = "mkdocs-git-revision-date-localized-plugin" -version = "1.2.9" +version = "1.3.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "babel" }, @@ -818,14 +811,14 @@ dependencies = [ { name = "mkdocs" }, { name = "pytz" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/05/79/56c755035c893af33c3ba29c5100835d10cd98b4b6943f8d1c22a7d56936/mkdocs_git_revision_date_localized_plugin-1.2.9.tar.gz", hash = "sha256:df9a50873fba3a42ce9123885f8c53d589e90ef6c2443fe3280ef1e8d33c8f65", size = 384360 } +sdist = { url = "https://files.pythonhosted.org/packages/73/85/6dc9d4eca486ed5734a05f7fd5c612a8e60a35e65610dad6aa9c58118c3f/mkdocs_git_revision_date_localized_plugin-1.3.0.tar.gz", hash = "sha256:439e2f14582204050a664c258861c325064d97cdc848c541e48bb034a6c4d0cb", size = 384797 } wheels = [ - { url = "https://files.pythonhosted.org/packages/bb/05/0edbbd3a0be3033c44d5cd9f1ac7646da2e7e3911513cc56a25aac9266a4/mkdocs_git_revision_date_localized_plugin-1.2.9-py3-none-any.whl", hash = "sha256:dea5c8067c23df30275702a1708885500fadf0abfb595b60e698bffc79c7a423", size = 22475 }, + { url = "https://files.pythonhosted.org/packages/67/e5/ffeb92db53af8c3aa2d92e21a3cf6b5f83eee7e03b9cf9234ef6b30230d5/mkdocs_git_revision_date_localized_plugin-1.3.0-py3-none-any.whl", hash = "sha256:c99377ee119372d57a9e47cff4e68f04cce634a74831c06bc89b33e456e840a1", size = 22549 }, ] [[package]] name = "mkdocs-material" -version = "9.5.40" +version = "9.5.50" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "babel" }, @@ -840,9 +833,9 @@ dependencies = [ { name = "regex" }, { name = "requests" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/b8/2b/6f9e0b9573a4acfa15834a30eca48ad578fe6ab46afa072df5ff05103a86/mkdocs_material-9.5.40.tar.gz", hash = "sha256:b69d70e667ec51fc41f65e006a3184dd00d95b2439d982cb1586e4c018943156", size = 3963129 } +sdist = { url = "https://files.pythonhosted.org/packages/c7/16/c48d5a28bc4a67c49808180b6009d4d1b4c0753739ffee3cc37046ab29d7/mkdocs_material-9.5.50.tar.gz", hash = "sha256:ae5fe16f3d7c9ccd05bb6916a7da7420cf99a9ce5e33debd9d40403a090d5825", size = 3923354 } wheels = [ - { url = "https://files.pythonhosted.org/packages/2c/ad/f8039114a23cfb02213f133a1dc8865522128a0b2cb251a7e717de8aa979/mkdocs_material-9.5.40-py3-none-any.whl", hash = "sha256:8e7a16ada34e79a7b6459ff2602584222f522c738b6a023d1bea853d5049da6f", size = 8670419 }, + { url = "https://files.pythonhosted.org/packages/ee/b5/1bf29cd744896ae83bd38c72970782c843ba13e0240b1a85277bd3928637/mkdocs_material-9.5.50-py3-none-any.whl", hash = "sha256:f24100f234741f4d423a9d672a909d859668a4f404796be3cf035f10d6050385", size = 8645274 }, ] [package.optional-dependencies] @@ -862,19 +855,19 @@ wheels = [ [[package]] name = "mkdocs-redirects" -version = "1.2.1" +version = "1.2.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "mkdocs" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/04/6a/50edd7ad78042b25c379aac7e8fa9cc34c6f55e3d2c03eb28814a9446617/mkdocs-redirects-1.2.1.tar.gz", hash = "sha256:9420066d70e2a6bb357adf86e67023dcdca1857f97f07c7fe450f8f1fb42f861", size = 6653 } +sdist = { url = "https://files.pythonhosted.org/packages/f1/a8/6d44a6cf07e969c7420cb36ab287b0669da636a2044de38a7d2208d5a758/mkdocs_redirects-1.2.2.tar.gz", hash = "sha256:3094981b42ffab29313c2c1b8ac3969861109f58b2dd58c45fc81cd44bfa0095", size = 7162 } wheels = [ - { url = "https://files.pythonhosted.org/packages/d3/9d/93a881fc5a23c50a4dd4a41dfd3d2a8403aa1dac52370ef43b7b336577a0/mkdocs_redirects-1.2.1-py3-none-any.whl", hash = "sha256:497089f9e0219e7389304cffefccdfa1cac5ff9509f2cb706f4c9b221726dffb", size = 6024 }, + { url = "https://files.pythonhosted.org/packages/c4/ec/38443b1f2a3821bbcb24e46cd8ba979154417794d54baf949fefde1c2146/mkdocs_redirects-1.2.2-py3-none-any.whl", hash = "sha256:7dbfa5647b79a3589da4401403d69494bd1f4ad03b9c15136720367e1f340ed5", size = 6142 }, ] [[package]] name = "mkdocstrings" -version = "0.26.1" +version = "0.27.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "click" }, @@ -886,9 +879,9 @@ dependencies = [ { name = "platformdirs" }, { name = "pymdown-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/e6/bf/170ff04de72227f715d67da32950c7b8434449f3805b2ec3dd1085db4d7c/mkdocstrings-0.26.1.tar.gz", hash = "sha256:bb8b8854d6713d5348ad05b069a09f3b79edbc6a0f33a34c6821141adb03fe33", size = 92677 } +sdist = { url = "https://files.pythonhosted.org/packages/e2/5a/5de70538c2cefae7ac3a15b5601e306ef3717290cb2aab11d51cbbc2d1c0/mkdocstrings-0.27.0.tar.gz", hash = "sha256:16adca6d6b0a1f9e0c07ff0b02ced8e16f228a9d65a37c063ec4c14d7b76a657", size = 94830 } wheels = [ - { url = "https://files.pythonhosted.org/packages/23/cc/8ba127aaee5d1e9046b0d33fa5b3d17da95a9d705d44902792e0569257fd/mkdocstrings-0.26.1-py3-none-any.whl", hash = "sha256:29738bfb72b4608e8e55cc50fb8a54f325dc7ebd2014e4e3881a49892d5983cf", size = 29643 }, + { url = "https://files.pythonhosted.org/packages/cd/10/4c27c3063c2b3681a4b7942f8dbdeb4fa34fecb2c19b594e7345ebf4f86f/mkdocstrings-0.27.0-py3-none-any.whl", hash = "sha256:6ceaa7ea830770959b55a16203ac63da24badd71325b96af950e59fd37366332", size = 30658 }, ] [package.optional-dependencies] @@ -898,16 +891,16 @@ python = [ [[package]] name = "mkdocstrings-python" -version = "1.11.1" +version = "1.13.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "griffe" }, { name = "mkdocs-autorefs" }, { name = "mkdocstrings" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/fc/ba/534c934cd0a809f51c91332d6ed278782ee4126b8ba8db02c2003f162b47/mkdocstrings_python-1.11.1.tar.gz", hash = "sha256:8824b115c5359304ab0b5378a91f6202324a849e1da907a3485b59208b797322", size = 166890 } +sdist = { url = "https://files.pythonhosted.org/packages/ab/ae/32703e35d74040051c672400fd9f5f2b48a6ea094f5071dd8a0e3be35322/mkdocstrings_python-1.13.0.tar.gz", hash = "sha256:2dbd5757e8375b9720e81db16f52f1856bf59905428fd7ef88005d1370e2f64c", size = 185697 } wheels = [ - { url = "https://files.pythonhosted.org/packages/2f/f2/2a2c48fda645ac6bbe73bcc974587a579092b6868e6ff8bc6d177f4db38a/mkdocstrings_python-1.11.1-py3-none-any.whl", hash = "sha256:a21a1c05acef129a618517bb5aae3e33114f569b11588b1e7af3e9d4061a71af", size = 109297 }, + { url = "https://files.pythonhosted.org/packages/51/23/d02d86553327296c3bf369d444194ea83410cce8f0e690565264f37f3261/mkdocstrings_python-1.13.0-py3-none-any.whl", hash = "sha256:b88bbb207bab4086434743849f8e796788b373bd32e7bfefbf8560ac45d88f97", size = 112254 }, ] [[package]] @@ -966,48 +959,50 @@ wheels = [ [[package]] name = "numpy" -version = "2.1.2" +version = "2.2.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/4b/d1/8a730ea07f4a37d94f9172f4ce1d81064b7a64766b460378be278952de75/numpy-2.1.2.tar.gz", hash = "sha256:13532a088217fa624c99b843eeb54640de23b3414b14aa66d023805eb731066c", size = 18878063 } +sdist = { url = "https://files.pythonhosted.org/packages/ec/d0/c12ddfd3a02274be06ffc71f3efc6d0e457b0409c4481596881e748cb264/numpy-2.2.2.tar.gz", hash = "sha256:ed6906f61834d687738d25988ae117683705636936cc605be0bb208b23df4d8f", size = 20233295 } wheels = [ - { url = "https://files.pythonhosted.org/packages/aa/9c/9a6ec3ae89cd0648d419781284308f2956d2a61d932b5ac9682c956a171b/numpy-2.1.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b42a1a511c81cc78cbc4539675713bbcf9d9c3913386243ceff0e9429ca892fe", size = 21154845 }, - { url = "https://files.pythonhosted.org/packages/02/69/9f05c4ecc75fabf297b17743996371b4c3dfc4d92e15c5c38d8bb3db8d74/numpy-2.1.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:faa88bc527d0f097abdc2c663cddf37c05a1c2f113716601555249805cf573f1", size = 13789409 }, - { url = "https://files.pythonhosted.org/packages/34/4e/f95c99217bf77bbfaaf660d693c10bd0dc03b6032d19316d316088c9e479/numpy-2.1.2-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:c82af4b2ddd2ee72d1fc0c6695048d457e00b3582ccde72d8a1c991b808bb20f", size = 5352097 }, - { url = "https://files.pythonhosted.org/packages/06/13/f5d87a497c16658e9af8920449b0b5692b469586b8231340c672962071c5/numpy-2.1.2-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:13602b3174432a35b16c4cfb5de9a12d229727c3dd47a6ce35111f2ebdf66ff4", size = 6891195 }, - { url = "https://files.pythonhosted.org/packages/6c/89/691ac07429ac061b344d5e37fa8e94be51a6017734aea15f2d9d7c6d119a/numpy-2.1.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1ebec5fd716c5a5b3d8dfcc439be82a8407b7b24b230d0ad28a81b61c2f4659a", size = 13895153 }, - { url = "https://files.pythonhosted.org/packages/23/69/538317f0d925095537745f12aced33be1570bbdc4acde49b33748669af96/numpy-2.1.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e2b49c3c0804e8ecb05d59af8386ec2f74877f7ca8fd9c1e00be2672e4d399b1", size = 16338306 }, - { url = "https://files.pythonhosted.org/packages/af/03/863fe7062c2106d3c151f7df9353f2ae2237c1dd6900f127a3eb1f24cb1b/numpy-2.1.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:2cbba4b30bf31ddbe97f1c7205ef976909a93a66bb1583e983adbd155ba72ac2", size = 16710893 }, - { url = "https://files.pythonhosted.org/packages/70/77/0ad9efe25482009873f9660d29a40a8c41a6f0e8b541195e3c95c70684c5/numpy-2.1.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8e00ea6fc82e8a804433d3e9cedaa1051a1422cb6e443011590c14d2dea59146", size = 14398048 }, - { url = "https://files.pythonhosted.org/packages/3e/0f/e785fe75544db9f2b0bb1c181e13ceff349ce49753d807fd9672916aa06d/numpy-2.1.2-cp311-cp311-win32.whl", hash = "sha256:5006b13a06e0b38d561fab5ccc37581f23c9511879be7693bd33c7cd15ca227c", size = 6533458 }, - { url = "https://files.pythonhosted.org/packages/d4/96/450054662295125af861d48d2c4bc081dadcf1974a879b2104613157aa62/numpy-2.1.2-cp311-cp311-win_amd64.whl", hash = "sha256:f1eb068ead09f4994dec71c24b2844f1e4e4e013b9629f812f292f04bd1510d9", size = 12870896 }, - { url = "https://files.pythonhosted.org/packages/a0/7d/554a6838f37f3ada5a55f25173c619d556ae98092a6e01afb6e710501d70/numpy-2.1.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d7bf0a4f9f15b32b5ba53147369e94296f5fffb783db5aacc1be15b4bf72f43b", size = 20848077 }, - { url = "https://files.pythonhosted.org/packages/b0/29/cb48a402ea879e645b16218718f3f7d9588a77d674a9dcf22e4c43487636/numpy-2.1.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b1d0fcae4f0949f215d4632be684a539859b295e2d0cb14f78ec231915d644db", size = 13493242 }, - { url = "https://files.pythonhosted.org/packages/56/44/f899b0581766c230da42f751b7b8896d096640b19b312164c267e48d36cb/numpy-2.1.2-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:f751ed0a2f250541e19dfca9f1eafa31a392c71c832b6bb9e113b10d050cb0f1", size = 5089219 }, - { url = "https://files.pythonhosted.org/packages/79/8f/b987070d45161a7a4504afc67ed38544ed2c0ed5576263599a0402204a9c/numpy-2.1.2-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:bd33f82e95ba7ad632bc57837ee99dba3d7e006536200c4e9124089e1bf42426", size = 6620167 }, - { url = "https://files.pythonhosted.org/packages/c4/a7/af3329fda3c3ec31d9b650e42bbcd3422fc62a765cbb1405fde4177a0996/numpy-2.1.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1b8cde4f11f0a975d1fd59373b32e2f5a562ade7cde4f85b7137f3de8fbb29a0", size = 13604905 }, - { url = "https://files.pythonhosted.org/packages/9b/b4/e3c7e6fab0f77fff6194afa173d1f2342073d91b1d3b4b30b17c3fb4407a/numpy-2.1.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d95f286b8244b3649b477ac066c6906fbb2905f8ac19b170e2175d3d799f4df", size = 16041825 }, - { url = "https://files.pythonhosted.org/packages/e9/50/6828e66a78aa03147c111f84d55f33ce2dde547cb578d6744a3b06a0124b/numpy-2.1.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:ab4754d432e3ac42d33a269c8567413bdb541689b02d93788af4131018cbf366", size = 16409541 }, - { url = "https://files.pythonhosted.org/packages/bf/72/66af7916d9c3c6dbfbc8acdd4930c65461e1953374a2bc43d00f948f004a/numpy-2.1.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e585c8ae871fd38ac50598f4763d73ec5497b0de9a0ab4ef5b69f01c6a046142", size = 14081134 }, - { url = "https://files.pythonhosted.org/packages/dc/5a/59a67d84f33fe00ae74f0b5b69dd4f93a586a4aba7f7e19b54b2133db038/numpy-2.1.2-cp312-cp312-win32.whl", hash = "sha256:9c6c754df29ce6a89ed23afb25550d1c2d5fdb9901d9c67a16e0b16eaf7e2550", size = 6237784 }, - { url = "https://files.pythonhosted.org/packages/4c/79/73735a6a5dad6059c085f240a4e74c9270feccd2bc66e4d31b5ca01d329c/numpy-2.1.2-cp312-cp312-win_amd64.whl", hash = "sha256:456e3b11cb79ac9946c822a56346ec80275eaf2950314b249b512896c0d2505e", size = 12568254 }, - { url = "https://files.pythonhosted.org/packages/16/72/716fa1dbe92395a9a623d5049203ff8ddb0cfce65b9df9117c3696ccc011/numpy-2.1.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a84498e0d0a1174f2b3ed769b67b656aa5460c92c9554039e11f20a05650f00d", size = 20834690 }, - { url = "https://files.pythonhosted.org/packages/1e/fb/3e85a39511586053b5c6a59a643879e376fae22230ebfef9cfabb0e032e2/numpy-2.1.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:4d6ec0d4222e8ffdab1744da2560f07856421b367928026fb540e1945f2eeeaf", size = 13507474 }, - { url = "https://files.pythonhosted.org/packages/35/eb/5677556d9ba13436dab51e129f98d4829d95cd1b6bd0e199c14485a4bdb9/numpy-2.1.2-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:259ec80d54999cc34cd1eb8ded513cb053c3bf4829152a2e00de2371bd406f5e", size = 5074742 }, - { url = "https://files.pythonhosted.org/packages/3e/c5/6c5ef5ba41b65a7e51bed50dbf3e1483eb578055633dd013e811a28e96a1/numpy-2.1.2-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:675c741d4739af2dc20cd6c6a5c4b7355c728167845e3c6b0e824e4e5d36a6c3", size = 6606787 }, - { url = "https://files.pythonhosted.org/packages/08/ac/f2f29dd4fd325b379c7dc932a0ebab22f0e031dbe80b2f6019b291a3a544/numpy-2.1.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:05b2d4e667895cc55e3ff2b56077e4c8a5604361fc21a042845ea3ad67465aa8", size = 13601333 }, - { url = "https://files.pythonhosted.org/packages/44/26/63f5f4e5089654dfb858f4892215ed968cd1a68e6f4a83f9961f84f855cb/numpy-2.1.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:43cca367bf94a14aca50b89e9bc2061683116cfe864e56740e083392f533ce7a", size = 16038090 }, - { url = "https://files.pythonhosted.org/packages/1d/21/015e0594de9c3a8d5edd24943d2bd23f102ec71aec026083f822f86497e2/numpy-2.1.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:76322dcdb16fccf2ac56f99048af32259dcc488d9b7e25b51e5eca5147a3fb98", size = 16410865 }, - { url = "https://files.pythonhosted.org/packages/df/01/c1bcf9e6025d79077fbf3f3ee503b50aa7bfabfcd8f4b54f5829f4c00f3f/numpy-2.1.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:32e16a03138cabe0cb28e1007ee82264296ac0983714094380b408097a418cfe", size = 14078077 }, - { url = "https://files.pythonhosted.org/packages/ba/06/db9d127d63bd11591770ba9f3d960f8041e0f895184b9351d4b1b5b56983/numpy-2.1.2-cp313-cp313-win32.whl", hash = "sha256:242b39d00e4944431a3cd2db2f5377e15b5785920421993770cddb89992c3f3a", size = 6234904 }, - { url = "https://files.pythonhosted.org/packages/a9/96/9f61f8f95b6e0ea0aa08633b704c75d1882bdcb331bdf8bfd63263b25b00/numpy-2.1.2-cp313-cp313-win_amd64.whl", hash = "sha256:f2ded8d9b6f68cc26f8425eda5d3877b47343e68ca23d0d0846f4d312ecaa445", size = 12561910 }, - { url = "https://files.pythonhosted.org/packages/36/b8/033f627821784a48e8f75c218033471eebbaacdd933f8979c79637a1b44b/numpy-2.1.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:2ffef621c14ebb0188a8633348504a35c13680d6da93ab5cb86f4e54b7e922b5", size = 20857719 }, - { url = "https://files.pythonhosted.org/packages/96/46/af5726fde5b74ed83f2f17a73386d399319b7ed4d51279fb23b721d0816d/numpy-2.1.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:ad369ed238b1959dfbade9018a740fb9392c5ac4f9b5173f420bd4f37ba1f7a0", size = 13518826 }, - { url = "https://files.pythonhosted.org/packages/db/6e/8ce677edf36da1c4dae80afe5529f47690697eb55b4864673af260ccea7b/numpy-2.1.2-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:d82075752f40c0ddf57e6e02673a17f6cb0f8eb3f587f63ca1eaab5594da5b17", size = 5115036 }, - { url = "https://files.pythonhosted.org/packages/6a/ba/3cce44fb1b8438042c11847048812a776f75ee0e7070179c22e4cfbf420c/numpy-2.1.2-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:1600068c262af1ca9580a527d43dc9d959b0b1d8e56f8a05d830eea39b7c8af6", size = 6628641 }, - { url = "https://files.pythonhosted.org/packages/59/c8/e722998720ccbd35ffbcf1d1b8ed0aa2304af88d3f1c38e06ebf983599b3/numpy-2.1.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a26ae94658d3ba3781d5e103ac07a876b3e9b29db53f68ed7df432fd033358a8", size = 13574803 }, - { url = "https://files.pythonhosted.org/packages/7c/8e/fc1fdd83a55476765329ac2913321c4aed5b082a7915095628c4ca30ea72/numpy-2.1.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13311c2db4c5f7609b462bc0f43d3c465424d25c626d95040f073e30f7570e35", size = 16021174 }, - { url = "https://files.pythonhosted.org/packages/2a/b6/a790742aa88067adb4bd6c89a946778c1417d4deaeafce3ca928f26d4c52/numpy-2.1.2-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:2abbf905a0b568706391ec6fa15161fad0fb5d8b68d73c461b3c1bab6064dd62", size = 16400117 }, - { url = "https://files.pythonhosted.org/packages/48/6f/129e3c17e3befe7fefdeaa6890f4c4df3f3cf0831aa053802c3862da67aa/numpy-2.1.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:ef444c57d664d35cac4e18c298c47d7b504c66b17c2ea91312e979fcfbdfb08a", size = 14066202 }, + { url = "https://files.pythonhosted.org/packages/21/67/32c68756eed84df181c06528ff57e09138f893c4653448c4967311e0f992/numpy-2.2.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:642199e98af1bd2b6aeb8ecf726972d238c9877b0f6e8221ee5ab945ec8a2189", size = 21220002 }, + { url = "https://files.pythonhosted.org/packages/3b/89/f43bcad18f2b2e5814457b1c7f7b0e671d0db12c8c0e43397ab8cb1831ed/numpy-2.2.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6d9fc9d812c81e6168b6d405bf00b8d6739a7f72ef22a9214c4241e0dc70b323", size = 14391215 }, + { url = "https://files.pythonhosted.org/packages/9c/e6/efb8cd6122bf25e86e3dd89d9dbfec9e6861c50e8810eed77d4be59b51c6/numpy-2.2.2-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:c7d1fd447e33ee20c1f33f2c8e6634211124a9aabde3c617687d8b739aa69eac", size = 5391918 }, + { url = "https://files.pythonhosted.org/packages/47/e2/fccf89d64d9b47ffb242823d4e851fc9d36fa751908c9aac2807924d9b4e/numpy-2.2.2-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:451e854cfae0febe723077bd0cf0a4302a5d84ff25f0bfece8f29206c7bed02e", size = 6933133 }, + { url = "https://files.pythonhosted.org/packages/34/22/5ece749c0e5420a9380eef6fbf83d16a50010bd18fef77b9193d80a6760e/numpy-2.2.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd249bc894af67cbd8bad2c22e7cbcd46cf87ddfca1f1289d1e7e54868cc785c", size = 14338187 }, + { url = "https://files.pythonhosted.org/packages/5b/86/caec78829311f62afa6fa334c8dfcd79cffb4d24bcf96ee02ae4840d462b/numpy-2.2.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:02935e2c3c0c6cbe9c7955a8efa8908dd4221d7755644c59d1bba28b94fd334f", size = 16393429 }, + { url = "https://files.pythonhosted.org/packages/c8/4e/0c25f74c88239a37924577d6ad780f3212a50f4b4b5f54f5e8c918d726bd/numpy-2.2.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:a972cec723e0563aa0823ee2ab1df0cb196ed0778f173b381c871a03719d4826", size = 15559103 }, + { url = "https://files.pythonhosted.org/packages/d4/bd/d557f10fa50dc4d5871fb9606af563249b66af2fc6f99041a10e8757c6f1/numpy-2.2.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d6d6a0910c3b4368d89dde073e630882cdb266755565155bc33520283b2d9df8", size = 18182967 }, + { url = "https://files.pythonhosted.org/packages/30/e9/66cc0f66386d78ed89e45a56e2a1d051e177b6e04477c4a41cd590ef4017/numpy-2.2.2-cp311-cp311-win32.whl", hash = "sha256:860fd59990c37c3ef913c3ae390b3929d005243acca1a86facb0773e2d8d9e50", size = 6571499 }, + { url = "https://files.pythonhosted.org/packages/66/a3/4139296b481ae7304a43581046b8f0a20da6a0dfe0ee47a044cade796603/numpy-2.2.2-cp311-cp311-win_amd64.whl", hash = "sha256:da1eeb460ecce8d5b8608826595c777728cdf28ce7b5a5a8c8ac8d949beadcf2", size = 12919805 }, + { url = "https://files.pythonhosted.org/packages/0c/e6/847d15770ab7a01e807bdfcd4ead5bdae57c0092b7dc83878171b6af97bb/numpy-2.2.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:ac9bea18d6d58a995fac1b2cb4488e17eceeac413af014b1dd26170b766d8467", size = 20912636 }, + { url = "https://files.pythonhosted.org/packages/d1/af/f83580891577b13bd7e261416120e036d0d8fb508c8a43a73e38928b794b/numpy-2.2.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:23ae9f0c2d889b7b2d88a3791f6c09e2ef827c2446f1c4a3e3e76328ee4afd9a", size = 14098403 }, + { url = "https://files.pythonhosted.org/packages/2b/86/d019fb60a9d0f1d4cf04b014fe88a9135090adfadcc31c1fadbb071d7fa7/numpy-2.2.2-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:3074634ea4d6df66be04f6728ee1d173cfded75d002c75fac79503a880bf3825", size = 5128938 }, + { url = "https://files.pythonhosted.org/packages/7a/1b/50985edb6f1ec495a1c36452e860476f5b7ecdc3fc59ea89ccad3c4926c5/numpy-2.2.2-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:8ec0636d3f7d68520afc6ac2dc4b8341ddb725039de042faf0e311599f54eb37", size = 6661937 }, + { url = "https://files.pythonhosted.org/packages/f4/1b/17efd94cad1b9d605c3f8907fb06bcffc4ce4d1d14d46b95316cccccf2b9/numpy-2.2.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2ffbb1acd69fdf8e89dd60ef6182ca90a743620957afb7066385a7bbe88dc748", size = 14049518 }, + { url = "https://files.pythonhosted.org/packages/5b/73/65d2f0b698df1731e851e3295eb29a5ab8aa06f763f7e4188647a809578d/numpy-2.2.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0349b025e15ea9d05c3d63f9657707a4e1d471128a3b1d876c095f328f8ff7f0", size = 16099146 }, + { url = "https://files.pythonhosted.org/packages/d5/69/308f55c0e19d4b5057b5df286c5433822e3c8039ede06d4051d96f1c2c4e/numpy-2.2.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:463247edcee4a5537841d5350bc87fe8e92d7dd0e8c71c995d2c6eecb8208278", size = 15246336 }, + { url = "https://files.pythonhosted.org/packages/f0/d8/d8d333ad0d8518d077a21aeea7b7c826eff766a2b1ce1194dea95ca0bacf/numpy-2.2.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:9dd47ff0cb2a656ad69c38da850df3454da88ee9a6fde0ba79acceee0e79daba", size = 17863507 }, + { url = "https://files.pythonhosted.org/packages/82/6e/0b84ad3103ffc16d6673e63b5acbe7901b2af96c2837174c6318c98e27ab/numpy-2.2.2-cp312-cp312-win32.whl", hash = "sha256:4525b88c11906d5ab1b0ec1f290996c0020dd318af8b49acaa46f198b1ffc283", size = 6276491 }, + { url = "https://files.pythonhosted.org/packages/fc/84/7f801a42a67b9772a883223a0a1e12069a14626c81a732bd70aac57aebc1/numpy-2.2.2-cp312-cp312-win_amd64.whl", hash = "sha256:5acea83b801e98541619af398cc0109ff48016955cc0818f478ee9ef1c5c3dcb", size = 12616372 }, + { url = "https://files.pythonhosted.org/packages/e1/fe/df5624001f4f5c3e0b78e9017bfab7fdc18a8d3b3d3161da3d64924dd659/numpy-2.2.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:b208cfd4f5fe34e1535c08983a1a6803fdbc7a1e86cf13dd0c61de0b51a0aadc", size = 20899188 }, + { url = "https://files.pythonhosted.org/packages/a9/80/d349c3b5ed66bd3cb0214be60c27e32b90a506946857b866838adbe84040/numpy-2.2.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d0bbe7dd86dca64854f4b6ce2ea5c60b51e36dfd597300057cf473d3615f2369", size = 14113972 }, + { url = "https://files.pythonhosted.org/packages/9d/50/949ec9cbb28c4b751edfa64503f0913cbfa8d795b4a251e7980f13a8a655/numpy-2.2.2-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:22ea3bb552ade325530e72a0c557cdf2dea8914d3a5e1fecf58fa5dbcc6f43cd", size = 5114294 }, + { url = "https://files.pythonhosted.org/packages/8d/f3/399c15629d5a0c68ef2aa7621d430b2be22034f01dd7f3c65a9c9666c445/numpy-2.2.2-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:128c41c085cab8a85dc29e66ed88c05613dccf6bc28b3866cd16050a2f5448be", size = 6648426 }, + { url = "https://files.pythonhosted.org/packages/2c/03/c72474c13772e30e1bc2e558cdffd9123c7872b731263d5648b5c49dd459/numpy-2.2.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:250c16b277e3b809ac20d1f590716597481061b514223c7badb7a0f9993c7f84", size = 14045990 }, + { url = "https://files.pythonhosted.org/packages/83/9c/96a9ab62274ffafb023f8ee08c88d3d31ee74ca58869f859db6845494fa6/numpy-2.2.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e0c8854b09bc4de7b041148d8550d3bd712b5c21ff6a8ed308085f190235d7ff", size = 16096614 }, + { url = "https://files.pythonhosted.org/packages/d5/34/cd0a735534c29bec7093544b3a509febc9b0df77718a9b41ffb0809c9f46/numpy-2.2.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:b6fb9c32a91ec32a689ec6410def76443e3c750e7cfc3fb2206b985ffb2b85f0", size = 15242123 }, + { url = "https://files.pythonhosted.org/packages/5e/6d/541717a554a8f56fa75e91886d9b79ade2e595918690eb5d0d3dbd3accb9/numpy-2.2.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:57b4012e04cc12b78590a334907e01b3a85efb2107df2b8733ff1ed05fce71de", size = 17859160 }, + { url = "https://files.pythonhosted.org/packages/b9/a5/fbf1f2b54adab31510728edd06a05c1b30839f37cf8c9747cb85831aaf1b/numpy-2.2.2-cp313-cp313-win32.whl", hash = "sha256:4dbd80e453bd34bd003b16bd802fac70ad76bd463f81f0c518d1245b1c55e3d9", size = 6273337 }, + { url = "https://files.pythonhosted.org/packages/56/e5/01106b9291ef1d680f82bc47d0c5b5e26dfed15b0754928e8f856c82c881/numpy-2.2.2-cp313-cp313-win_amd64.whl", hash = "sha256:5a8c863ceacae696aff37d1fd636121f1a512117652e5dfb86031c8d84836369", size = 12609010 }, + { url = "https://files.pythonhosted.org/packages/9f/30/f23d9876de0f08dceb707c4dcf7f8dd7588266745029debb12a3cdd40be6/numpy-2.2.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:b3482cb7b3325faa5f6bc179649406058253d91ceda359c104dac0ad320e1391", size = 20924451 }, + { url = "https://files.pythonhosted.org/packages/6a/ec/6ea85b2da9d5dfa1dbb4cb3c76587fc8ddcae580cb1262303ab21c0926c4/numpy-2.2.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:9491100aba630910489c1d0158034e1c9a6546f0b1340f716d522dc103788e39", size = 14122390 }, + { url = "https://files.pythonhosted.org/packages/68/05/bfbdf490414a7dbaf65b10c78bc243f312c4553234b6d91c94eb7c4b53c2/numpy-2.2.2-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:41184c416143defa34cc8eb9d070b0a5ba4f13a0fa96a709e20584638254b317", size = 5156590 }, + { url = "https://files.pythonhosted.org/packages/f7/ec/fe2e91b2642b9d6544518388a441bcd65c904cea38d9ff998e2e8ebf808e/numpy-2.2.2-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:7dca87ca328f5ea7dafc907c5ec100d187911f94825f8700caac0b3f4c384b49", size = 6671958 }, + { url = "https://files.pythonhosted.org/packages/b1/6f/6531a78e182f194d33ee17e59d67d03d0d5a1ce7f6be7343787828d1bd4a/numpy-2.2.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0bc61b307655d1a7f9f4b043628b9f2b721e80839914ede634e3d485913e1fb2", size = 14019950 }, + { url = "https://files.pythonhosted.org/packages/e1/fb/13c58591d0b6294a08cc40fcc6b9552d239d773d520858ae27f39997f2ae/numpy-2.2.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fad446ad0bc886855ddf5909cbf8cb5d0faa637aaa6277fb4b19ade134ab3c7", size = 16079759 }, + { url = "https://files.pythonhosted.org/packages/2c/f2/f2f8edd62abb4b289f65a7f6d1f3650273af00b91b7267a2431be7f1aec6/numpy-2.2.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:149d1113ac15005652e8d0d3f6fd599360e1a708a4f98e43c9c77834a28238cb", size = 15226139 }, + { url = "https://files.pythonhosted.org/packages/aa/29/14a177f1a90b8ad8a592ca32124ac06af5eff32889874e53a308f850290f/numpy-2.2.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:106397dbbb1896f99e044efc90360d098b3335060375c26aa89c0d8a97c5f648", size = 17856316 }, + { url = "https://files.pythonhosted.org/packages/95/03/242ae8d7b97f4e0e4ab8dd51231465fb23ed5e802680d629149722e3faf1/numpy-2.2.2-cp313-cp313t-win32.whl", hash = "sha256:0eec19f8af947a61e968d5429f0bd92fec46d92b0008d0a6685b40d6adf8a4f4", size = 6329134 }, + { url = "https://files.pythonhosted.org/packages/80/94/cd9e9b04012c015cb6320ab3bf43bc615e248dddfeb163728e800a5d96f0/numpy-2.2.2-cp313-cp313t-win_amd64.whl", hash = "sha256:97b974d3ba0fb4612b77ed35d7627490e8e3dff56ab41454d9e8b23448940576", size = 12696208 }, ] [[package]] @@ -1082,17 +1077,17 @@ wheels = [ [[package]] name = "peewee" -version = "3.17.6" +version = "3.17.8" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/bd/be/e9c886b4601a19f4c34a1b75c5fe8b98a2115dd964251a76b24c977c369d/peewee-3.17.6.tar.gz", hash = "sha256:cea5592c6f4da1592b7cff8eaf655be6648a1f5857469e30037bf920c03fb8fb", size = 2954075 } +sdist = { url = "https://files.pythonhosted.org/packages/b4/dc/832bcf4ea5ee2ebc4ea42ef36e44a451de5d80f8b9858bf2066e30738c67/peewee-3.17.8.tar.gz", hash = "sha256:ce1d05db3438830b989a1b9d0d0aa4e7f6134d5f6fd57686eeaa26a3e6485a8c", size = 948249 } [[package]] name = "phx-class-registry" -version = "5.0.0" +version = "5.1.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d4/b0/dfe7eee3715a522e0507c5d81daab52d4348ee2672fa77c721617dbb6319/phx_class_registry-5.0.0.tar.gz", hash = "sha256:a57ab8c2eca03e0daf06e0dd840ea26b72e2e51b7b7509015b3df7c0d537ee73", size = 32284 } +sdist = { url = "https://files.pythonhosted.org/packages/ad/e1/4038dc8b09e66b1f850913c05fe1c039f8d9c0ef61347af37c75bbe77e3f/phx_class_registry-5.1.1.tar.gz", hash = "sha256:06c9af198b846a7530406314f63f8d83441daf42d29ee25d8c0b19a9dbc37939", size = 32115 } wheels = [ - { url = "https://files.pythonhosted.org/packages/41/e5/9384dd7f575ade7a14ae4371d6b4eafd997f18577d3e93ccd0e055389b0b/phx_class_registry-5.0.0-py3-none-any.whl", hash = "sha256:6e0644f779c7d793a96090d938fe4c396f3274dd57563dc1c57ea245b5c07f89", size = 14850 }, + { url = "https://files.pythonhosted.org/packages/7d/85/67eb86f25b1857a7669c4ad7a46b439e55c5301cbcb08b9ce8fa9125700d/phx_class_registry-5.1.1-py3-none-any.whl", hash = "sha256:b093ecc1dad34c5dc6eda2530046d956f2303a5cfaa543bf7fba35ce3c7b1672", size = 15732 }, ] [[package]] @@ -1138,11 +1133,11 @@ wheels = [ [[package]] name = "pip" -version = "24.3.1" +version = "25.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f4/b1/b422acd212ad7eedddaf7981eee6e5de085154ff726459cf2da7c5a184c1/pip-24.3.1.tar.gz", hash = "sha256:ebcb60557f2aefabc2e0f918751cd24ea0d56d8ec5445fe1807f1d2109660b99", size = 1931073 } +sdist = { url = "https://files.pythonhosted.org/packages/47/3e/68beeeeb306ea20ffd30b3ed993f531d16cd884ec4f60c9b1e238f69f2af/pip-25.0.tar.gz", hash = "sha256:8e0a97f7b4c47ae4a494560da84775e9e2f671d415d8d828e052efefb206b30b", size = 1950328 } wheels = [ - { url = "https://files.pythonhosted.org/packages/ef/7d/500c9ad20238fcfcb4cb9243eede163594d7020ce87bd9610c9e02771876/pip-24.3.1-py3-none-any.whl", hash = "sha256:3790624780082365f47549d032f3770eeb2b1e8bd1f7b2e02dace1afa361b4ed", size = 1822182 }, + { url = "https://files.pythonhosted.org/packages/85/8a/1ddf40be20103bcc605db840e9ade09c8e8c9f920a03e9cfe88eae97a058/pip-25.0-py3-none-any.whl", hash = "sha256:b6eb97a803356a52b2dd4bb73ba9e65b2ba16caa6bcb25a7497350a4e5859b65", size = 1841506 }, ] [[package]] @@ -1245,63 +1240,69 @@ wheels = [ [[package]] name = "pydantic" -version = "2.9.2" +version = "2.10.6" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "annotated-types" }, { name = "pydantic-core" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/a9/b7/d9e3f12af310e1120c21603644a1cd86f59060e040ec5c3a80b8f05fae30/pydantic-2.9.2.tar.gz", hash = "sha256:d155cef71265d1e9807ed1c32b4c8deec042a44a50a4188b25ac67ecd81a9c0f", size = 769917 } +sdist = { url = "https://files.pythonhosted.org/packages/b7/ae/d5220c5c52b158b1de7ca89fc5edb72f304a70a4c540c84c8844bf4008de/pydantic-2.10.6.tar.gz", hash = "sha256:ca5daa827cce33de7a42be142548b0096bf05a7e7b365aebfa5f8eeec7128236", size = 761681 } wheels = [ - { url = "https://files.pythonhosted.org/packages/df/e4/ba44652d562cbf0bf320e0f3810206149c8a4e99cdbf66da82e97ab53a15/pydantic-2.9.2-py3-none-any.whl", hash = "sha256:f048cec7b26778210e28a0459867920654d48e5e62db0958433636cde4254f12", size = 434928 }, + { url = "https://files.pythonhosted.org/packages/f4/3c/8cc1cc84deffa6e25d2d0c688ebb80635dfdbf1dbea3e30c541c8cf4d860/pydantic-2.10.6-py3-none-any.whl", hash = "sha256:427d664bf0b8a2b34ff5dd0f5a18df00591adcee7198fbd71981054cef37b584", size = 431696 }, ] [[package]] name = "pydantic-core" -version = "2.23.4" +version = "2.27.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/e2/aa/6b6a9b9f8537b872f552ddd46dd3da230367754b6f707b8e1e963f515ea3/pydantic_core-2.23.4.tar.gz", hash = "sha256:2584f7cf844ac4d970fba483a717dbe10c1c1c96a969bf65d61ffe94df1b2863", size = 402156 } +sdist = { url = "https://files.pythonhosted.org/packages/fc/01/f3e5ac5e7c25833db5eb555f7b7ab24cd6f8c322d3a3ad2d67a952dc0abc/pydantic_core-2.27.2.tar.gz", hash = "sha256:eb026e5a4c1fee05726072337ff51d1efb6f59090b7da90d30ea58625b1ffb39", size = 413443 } wheels = [ - { url = "https://files.pythonhosted.org/packages/5d/30/890a583cd3f2be27ecf32b479d5d615710bb926d92da03e3f7838ff3e58b/pydantic_core-2.23.4-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:77733e3892bb0a7fa797826361ce8a9184d25c8dffaec60b7ffe928153680ba8", size = 1865160 }, - { url = "https://files.pythonhosted.org/packages/1d/9a/b634442e1253bc6889c87afe8bb59447f106ee042140bd57680b3b113ec7/pydantic_core-2.23.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1b84d168f6c48fabd1f2027a3d1bdfe62f92cade1fb273a5d68e621da0e44e6d", size = 1776777 }, - { url = "https://files.pythonhosted.org/packages/75/9a/7816295124a6b08c24c96f9ce73085032d8bcbaf7e5a781cd41aa910c891/pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:df49e7a0861a8c36d089c1ed57d308623d60416dab2647a4a17fe050ba85de0e", size = 1799244 }, - { url = "https://files.pythonhosted.org/packages/a9/8f/89c1405176903e567c5f99ec53387449e62f1121894aa9fc2c4fdc51a59b/pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ff02b6d461a6de369f07ec15e465a88895f3223eb75073ffea56b84d9331f607", size = 1805307 }, - { url = "https://files.pythonhosted.org/packages/d5/a5/1a194447d0da1ef492e3470680c66048fef56fc1f1a25cafbea4bc1d1c48/pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:996a38a83508c54c78a5f41456b0103c30508fed9abcad0a59b876d7398f25fd", size = 2000663 }, - { url = "https://files.pythonhosted.org/packages/13/a5/1df8541651de4455e7d587cf556201b4f7997191e110bca3b589218745a5/pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d97683ddee4723ae8c95d1eddac7c192e8c552da0c73a925a89fa8649bf13eea", size = 2655941 }, - { url = "https://files.pythonhosted.org/packages/44/31/a3899b5ce02c4316865e390107f145089876dff7e1dfc770a231d836aed8/pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:216f9b2d7713eb98cb83c80b9c794de1f6b7e3145eef40400c62e86cee5f4e1e", size = 2052105 }, - { url = "https://files.pythonhosted.org/packages/1b/aa/98e190f8745d5ec831f6d5449344c48c0627ac5fed4e5340a44b74878f8e/pydantic_core-2.23.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6f783e0ec4803c787bcea93e13e9932edab72068f68ecffdf86a99fd5918878b", size = 1919967 }, - { url = "https://files.pythonhosted.org/packages/ae/35/b6e00b6abb2acfee3e8f85558c02a0822e9a8b2f2d812ea8b9079b118ba0/pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d0776dea117cf5272382634bd2a5c1b6eb16767c223c6a5317cd3e2a757c61a0", size = 1964291 }, - { url = "https://files.pythonhosted.org/packages/13/46/7bee6d32b69191cd649bbbd2361af79c472d72cb29bb2024f0b6e350ba06/pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d5f7a395a8cf1621939692dba2a6b6a830efa6b3cee787d82c7de1ad2930de64", size = 2109666 }, - { url = "https://files.pythonhosted.org/packages/39/ef/7b34f1b122a81b68ed0a7d0e564da9ccdc9a2924c8d6c6b5b11fa3a56970/pydantic_core-2.23.4-cp311-none-win32.whl", hash = "sha256:74b9127ffea03643e998e0c5ad9bd3811d3dac8c676e47db17b0ee7c3c3bf35f", size = 1732940 }, - { url = "https://files.pythonhosted.org/packages/2f/76/37b7e76c645843ff46c1d73e046207311ef298d3f7b2f7d8f6ac60113071/pydantic_core-2.23.4-cp311-none-win_amd64.whl", hash = "sha256:98d134c954828488b153d88ba1f34e14259284f256180ce659e8d83e9c05eaa3", size = 1916804 }, - { url = "https://files.pythonhosted.org/packages/74/7b/8e315f80666194b354966ec84b7d567da77ad927ed6323db4006cf915f3f/pydantic_core-2.23.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:f3e0da4ebaef65158d4dfd7d3678aad692f7666877df0002b8a522cdf088f231", size = 1856459 }, - { url = "https://files.pythonhosted.org/packages/14/de/866bdce10ed808323d437612aca1ec9971b981e1c52e5e42ad9b8e17a6f6/pydantic_core-2.23.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f69a8e0b033b747bb3e36a44e7732f0c99f7edd5cea723d45bc0d6e95377ffee", size = 1770007 }, - { url = "https://files.pythonhosted.org/packages/dc/69/8edd5c3cd48bb833a3f7ef9b81d7666ccddd3c9a635225214e044b6e8281/pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:723314c1d51722ab28bfcd5240d858512ffd3116449c557a1336cbe3919beb87", size = 1790245 }, - { url = "https://files.pythonhosted.org/packages/80/33/9c24334e3af796ce80d2274940aae38dd4e5676298b4398eff103a79e02d/pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bb2802e667b7051a1bebbfe93684841cc9351004e2badbd6411bf357ab8d5ac8", size = 1801260 }, - { url = "https://files.pythonhosted.org/packages/a5/6f/e9567fd90104b79b101ca9d120219644d3314962caa7948dd8b965e9f83e/pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d18ca8148bebe1b0a382a27a8ee60350091a6ddaf475fa05ef50dc35b5df6327", size = 1996872 }, - { url = "https://files.pythonhosted.org/packages/2d/ad/b5f0fe9e6cfee915dd144edbd10b6e9c9c9c9d7a56b69256d124b8ac682e/pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33e3d65a85a2a4a0dc3b092b938a4062b1a05f3a9abde65ea93b233bca0e03f2", size = 2661617 }, - { url = "https://files.pythonhosted.org/packages/06/c8/7d4b708f8d05a5cbfda3243aad468052c6e99de7d0937c9146c24d9f12e9/pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:128585782e5bfa515c590ccee4b727fb76925dd04a98864182b22e89a4e6ed36", size = 2071831 }, - { url = "https://files.pythonhosted.org/packages/89/4d/3079d00c47f22c9a9a8220db088b309ad6e600a73d7a69473e3a8e5e3ea3/pydantic_core-2.23.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:68665f4c17edcceecc112dfed5dbe6f92261fb9d6054b47d01bf6371a6196126", size = 1917453 }, - { url = "https://files.pythonhosted.org/packages/e9/88/9df5b7ce880a4703fcc2d76c8c2d8eb9f861f79d0c56f4b8f5f2607ccec8/pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:20152074317d9bed6b7a95ade3b7d6054845d70584216160860425f4fbd5ee9e", size = 1968793 }, - { url = "https://files.pythonhosted.org/packages/e3/b9/41f7efe80f6ce2ed3ee3c2dcfe10ab7adc1172f778cc9659509a79518c43/pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9261d3ce84fa1d38ed649c3638feefeae23d32ba9182963e465d58d62203bd24", size = 2116872 }, - { url = "https://files.pythonhosted.org/packages/63/08/b59b7a92e03dd25554b0436554bf23e7c29abae7cce4b1c459cd92746811/pydantic_core-2.23.4-cp312-none-win32.whl", hash = "sha256:4ba762ed58e8d68657fc1281e9bb72e1c3e79cc5d464be146e260c541ec12d84", size = 1738535 }, - { url = "https://files.pythonhosted.org/packages/88/8d/479293e4d39ab409747926eec4329de5b7129beaedc3786eca070605d07f/pydantic_core-2.23.4-cp312-none-win_amd64.whl", hash = "sha256:97df63000f4fea395b2824da80e169731088656d1818a11b95f3b173747b6cd9", size = 1917992 }, - { url = "https://files.pythonhosted.org/packages/ad/ef/16ee2df472bf0e419b6bc68c05bf0145c49247a1095e85cee1463c6a44a1/pydantic_core-2.23.4-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7530e201d10d7d14abce4fb54cfe5b94a0aefc87da539d0346a484ead376c3cc", size = 1856143 }, - { url = "https://files.pythonhosted.org/packages/da/fa/bc3dbb83605669a34a93308e297ab22be82dfb9dcf88c6cf4b4f264e0a42/pydantic_core-2.23.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:df933278128ea1cd77772673c73954e53a1c95a4fdf41eef97c2b779271bd0bd", size = 1770063 }, - { url = "https://files.pythonhosted.org/packages/4e/48/e813f3bbd257a712303ebdf55c8dc46f9589ec74b384c9f652597df3288d/pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cb3da3fd1b6a5d0279a01877713dbda118a2a4fc6f0d821a57da2e464793f05", size = 1790013 }, - { url = "https://files.pythonhosted.org/packages/b4/e0/56eda3a37929a1d297fcab1966db8c339023bcca0b64c5a84896db3fcc5c/pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42c6dcb030aefb668a2b7009c85b27f90e51e6a3b4d5c9bc4c57631292015b0d", size = 1801077 }, - { url = "https://files.pythonhosted.org/packages/04/be/5e49376769bfbf82486da6c5c1683b891809365c20d7c7e52792ce4c71f3/pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:696dd8d674d6ce621ab9d45b205df149399e4bb9aa34102c970b721554828510", size = 1996782 }, - { url = "https://files.pythonhosted.org/packages/bc/24/e3ee6c04f1d58cc15f37bcc62f32c7478ff55142b7b3e6d42ea374ea427c/pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2971bb5ffe72cc0f555c13e19b23c85b654dd2a8f7ab493c262071377bfce9f6", size = 2661375 }, - { url = "https://files.pythonhosted.org/packages/c1/f8/11a9006de4e89d016b8de74ebb1db727dc100608bb1e6bbe9d56a3cbbcce/pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8394d940e5d400d04cad4f75c0598665cbb81aecefaca82ca85bd28264af7f9b", size = 2071635 }, - { url = "https://files.pythonhosted.org/packages/7c/45/bdce5779b59f468bdf262a5bc9eecbae87f271c51aef628d8c073b4b4b4c/pydantic_core-2.23.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0dff76e0602ca7d4cdaacc1ac4c005e0ce0dcfe095d5b5259163a80d3a10d327", size = 1916994 }, - { url = "https://files.pythonhosted.org/packages/d8/fa/c648308fe711ee1f88192cad6026ab4f925396d1293e8356de7e55be89b5/pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7d32706badfe136888bdea71c0def994644e09fff0bfe47441deaed8e96fdbc6", size = 1968877 }, - { url = "https://files.pythonhosted.org/packages/16/16/b805c74b35607d24d37103007f899abc4880923b04929547ae68d478b7f4/pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ed541d70698978a20eb63d8c5d72f2cc6d7079d9d90f6b50bad07826f1320f5f", size = 2116814 }, - { url = "https://files.pythonhosted.org/packages/d1/58/5305e723d9fcdf1c5a655e6a4cc2a07128bf644ff4b1d98daf7a9dbf57da/pydantic_core-2.23.4-cp313-none-win32.whl", hash = "sha256:3d5639516376dce1940ea36edf408c554475369f5da2abd45d44621cb616f769", size = 1738360 }, - { url = "https://files.pythonhosted.org/packages/a5/ae/e14b0ff8b3f48e02394d8acd911376b7b66e164535687ef7dc24ea03072f/pydantic_core-2.23.4-cp313-none-win_amd64.whl", hash = "sha256:5a1504ad17ba4210df3a045132a7baeeba5a200e930f57512ee02909fc5c4cb5", size = 1919411 }, + { url = "https://files.pythonhosted.org/packages/c2/89/f3450af9d09d44eea1f2c369f49e8f181d742f28220f88cc4dfaae91ea6e/pydantic_core-2.27.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:8e10c99ef58cfdf2a66fc15d66b16c4a04f62bca39db589ae8cba08bc55331bc", size = 1893421 }, + { url = "https://files.pythonhosted.org/packages/9e/e3/71fe85af2021f3f386da42d291412e5baf6ce7716bd7101ea49c810eda90/pydantic_core-2.27.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:26f32e0adf166a84d0cb63be85c562ca8a6fa8de28e5f0d92250c6b7e9e2aff7", size = 1814998 }, + { url = "https://files.pythonhosted.org/packages/a6/3c/724039e0d848fd69dbf5806894e26479577316c6f0f112bacaf67aa889ac/pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c19d1ea0673cd13cc2f872f6c9ab42acc4e4f492a7ca9d3795ce2b112dd7e15", size = 1826167 }, + { url = "https://files.pythonhosted.org/packages/2b/5b/1b29e8c1fb5f3199a9a57c1452004ff39f494bbe9bdbe9a81e18172e40d3/pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5e68c4446fe0810e959cdff46ab0a41ce2f2c86d227d96dc3847af0ba7def306", size = 1865071 }, + { url = "https://files.pythonhosted.org/packages/89/6c/3985203863d76bb7d7266e36970d7e3b6385148c18a68cc8915fd8c84d57/pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d9640b0059ff4f14d1f37321b94061c6db164fbe49b334b31643e0528d100d99", size = 2036244 }, + { url = "https://files.pythonhosted.org/packages/0e/41/f15316858a246b5d723f7d7f599f79e37493b2e84bfc789e58d88c209f8a/pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:40d02e7d45c9f8af700f3452f329ead92da4c5f4317ca9b896de7ce7199ea459", size = 2737470 }, + { url = "https://files.pythonhosted.org/packages/a8/7c/b860618c25678bbd6d1d99dbdfdf0510ccb50790099b963ff78a124b754f/pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1c1fd185014191700554795c99b347d64f2bb637966c4cfc16998a0ca700d048", size = 1992291 }, + { url = "https://files.pythonhosted.org/packages/bf/73/42c3742a391eccbeab39f15213ecda3104ae8682ba3c0c28069fbcb8c10d/pydantic_core-2.27.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d81d2068e1c1228a565af076598f9e7451712700b673de8f502f0334f281387d", size = 1994613 }, + { url = "https://files.pythonhosted.org/packages/94/7a/941e89096d1175d56f59340f3a8ebaf20762fef222c298ea96d36a6328c5/pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:1a4207639fb02ec2dbb76227d7c751a20b1a6b4bc52850568e52260cae64ca3b", size = 2002355 }, + { url = "https://files.pythonhosted.org/packages/6e/95/2359937a73d49e336a5a19848713555605d4d8d6940c3ec6c6c0ca4dcf25/pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:3de3ce3c9ddc8bbd88f6e0e304dea0e66d843ec9de1b0042b0911c1663ffd474", size = 2126661 }, + { url = "https://files.pythonhosted.org/packages/2b/4c/ca02b7bdb6012a1adef21a50625b14f43ed4d11f1fc237f9d7490aa5078c/pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:30c5f68ded0c36466acede341551106821043e9afaad516adfb6e8fa80a4e6a6", size = 2153261 }, + { url = "https://files.pythonhosted.org/packages/72/9d/a241db83f973049a1092a079272ffe2e3e82e98561ef6214ab53fe53b1c7/pydantic_core-2.27.2-cp311-cp311-win32.whl", hash = "sha256:c70c26d2c99f78b125a3459f8afe1aed4d9687c24fd677c6a4436bc042e50d6c", size = 1812361 }, + { url = "https://files.pythonhosted.org/packages/e8/ef/013f07248041b74abd48a385e2110aa3a9bbfef0fbd97d4e6d07d2f5b89a/pydantic_core-2.27.2-cp311-cp311-win_amd64.whl", hash = "sha256:08e125dbdc505fa69ca7d9c499639ab6407cfa909214d500897d02afb816e7cc", size = 1982484 }, + { url = "https://files.pythonhosted.org/packages/10/1c/16b3a3e3398fd29dca77cea0a1d998d6bde3902fa2706985191e2313cc76/pydantic_core-2.27.2-cp311-cp311-win_arm64.whl", hash = "sha256:26f0d68d4b235a2bae0c3fc585c585b4ecc51382db0e3ba402a22cbc440915e4", size = 1867102 }, + { url = "https://files.pythonhosted.org/packages/d6/74/51c8a5482ca447871c93e142d9d4a92ead74de6c8dc5e66733e22c9bba89/pydantic_core-2.27.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:9e0c8cfefa0ef83b4da9588448b6d8d2a2bf1a53c3f1ae5fca39eb3061e2f0b0", size = 1893127 }, + { url = "https://files.pythonhosted.org/packages/d3/f3/c97e80721735868313c58b89d2de85fa80fe8dfeeed84dc51598b92a135e/pydantic_core-2.27.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:83097677b8e3bd7eaa6775720ec8e0405f1575015a463285a92bfdfe254529ef", size = 1811340 }, + { url = "https://files.pythonhosted.org/packages/9e/91/840ec1375e686dbae1bd80a9e46c26a1e0083e1186abc610efa3d9a36180/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:172fce187655fece0c90d90a678424b013f8fbb0ca8b036ac266749c09438cb7", size = 1822900 }, + { url = "https://files.pythonhosted.org/packages/f6/31/4240bc96025035500c18adc149aa6ffdf1a0062a4b525c932065ceb4d868/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:519f29f5213271eeeeb3093f662ba2fd512b91c5f188f3bb7b27bc5973816934", size = 1869177 }, + { url = "https://files.pythonhosted.org/packages/fa/20/02fbaadb7808be578317015c462655c317a77a7c8f0ef274bc016a784c54/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:05e3a55d124407fffba0dd6b0c0cd056d10e983ceb4e5dbd10dda135c31071d6", size = 2038046 }, + { url = "https://files.pythonhosted.org/packages/06/86/7f306b904e6c9eccf0668248b3f272090e49c275bc488a7b88b0823444a4/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9c3ed807c7b91de05e63930188f19e921d1fe90de6b4f5cd43ee7fcc3525cb8c", size = 2685386 }, + { url = "https://files.pythonhosted.org/packages/8d/f0/49129b27c43396581a635d8710dae54a791b17dfc50c70164866bbf865e3/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fb4aadc0b9a0c063206846d603b92030eb6f03069151a625667f982887153e2", size = 1997060 }, + { url = "https://files.pythonhosted.org/packages/0d/0f/943b4af7cd416c477fd40b187036c4f89b416a33d3cc0ab7b82708a667aa/pydantic_core-2.27.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:28ccb213807e037460326424ceb8b5245acb88f32f3d2777427476e1b32c48c4", size = 2004870 }, + { url = "https://files.pythonhosted.org/packages/35/40/aea70b5b1a63911c53a4c8117c0a828d6790483f858041f47bab0b779f44/pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:de3cd1899e2c279b140adde9357c4495ed9d47131b4a4eaff9052f23398076b3", size = 1999822 }, + { url = "https://files.pythonhosted.org/packages/f2/b3/807b94fd337d58effc5498fd1a7a4d9d59af4133e83e32ae39a96fddec9d/pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:220f892729375e2d736b97d0e51466252ad84c51857d4d15f5e9692f9ef12be4", size = 2130364 }, + { url = "https://files.pythonhosted.org/packages/fc/df/791c827cd4ee6efd59248dca9369fb35e80a9484462c33c6649a8d02b565/pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a0fcd29cd6b4e74fe8ddd2c90330fd8edf2e30cb52acda47f06dd615ae72da57", size = 2158303 }, + { url = "https://files.pythonhosted.org/packages/9b/67/4e197c300976af185b7cef4c02203e175fb127e414125916bf1128b639a9/pydantic_core-2.27.2-cp312-cp312-win32.whl", hash = "sha256:1e2cb691ed9834cd6a8be61228471d0a503731abfb42f82458ff27be7b2186fc", size = 1834064 }, + { url = "https://files.pythonhosted.org/packages/1f/ea/cd7209a889163b8dcca139fe32b9687dd05249161a3edda62860430457a5/pydantic_core-2.27.2-cp312-cp312-win_amd64.whl", hash = "sha256:cc3f1a99a4f4f9dd1de4fe0312c114e740b5ddead65bb4102884b384c15d8bc9", size = 1989046 }, + { url = "https://files.pythonhosted.org/packages/bc/49/c54baab2f4658c26ac633d798dab66b4c3a9bbf47cff5284e9c182f4137a/pydantic_core-2.27.2-cp312-cp312-win_arm64.whl", hash = "sha256:3911ac9284cd8a1792d3cb26a2da18f3ca26c6908cc434a18f730dc0db7bfa3b", size = 1885092 }, + { url = "https://files.pythonhosted.org/packages/41/b1/9bc383f48f8002f99104e3acff6cba1231b29ef76cfa45d1506a5cad1f84/pydantic_core-2.27.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7d14bd329640e63852364c306f4d23eb744e0f8193148d4044dd3dacdaacbd8b", size = 1892709 }, + { url = "https://files.pythonhosted.org/packages/10/6c/e62b8657b834f3eb2961b49ec8e301eb99946245e70bf42c8817350cbefc/pydantic_core-2.27.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:82f91663004eb8ed30ff478d77c4d1179b3563df6cdb15c0817cd1cdaf34d154", size = 1811273 }, + { url = "https://files.pythonhosted.org/packages/ba/15/52cfe49c8c986e081b863b102d6b859d9defc63446b642ccbbb3742bf371/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:71b24c7d61131bb83df10cc7e687433609963a944ccf45190cfc21e0887b08c9", size = 1823027 }, + { url = "https://files.pythonhosted.org/packages/b1/1c/b6f402cfc18ec0024120602bdbcebc7bdd5b856528c013bd4d13865ca473/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fa8e459d4954f608fa26116118bb67f56b93b209c39b008277ace29937453dc9", size = 1868888 }, + { url = "https://files.pythonhosted.org/packages/bd/7b/8cb75b66ac37bc2975a3b7de99f3c6f355fcc4d89820b61dffa8f1e81677/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce8918cbebc8da707ba805b7fd0b382816858728ae7fe19a942080c24e5b7cd1", size = 2037738 }, + { url = "https://files.pythonhosted.org/packages/c8/f1/786d8fe78970a06f61df22cba58e365ce304bf9b9f46cc71c8c424e0c334/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eda3f5c2a021bbc5d976107bb302e0131351c2ba54343f8a496dc8783d3d3a6a", size = 2685138 }, + { url = "https://files.pythonhosted.org/packages/a6/74/d12b2cd841d8724dc8ffb13fc5cef86566a53ed358103150209ecd5d1999/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bd8086fa684c4775c27f03f062cbb9eaa6e17f064307e86b21b9e0abc9c0f02e", size = 1997025 }, + { url = "https://files.pythonhosted.org/packages/a0/6e/940bcd631bc4d9a06c9539b51f070b66e8f370ed0933f392db6ff350d873/pydantic_core-2.27.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8d9b3388db186ba0c099a6d20f0604a44eabdeef1777ddd94786cdae158729e4", size = 2004633 }, + { url = "https://files.pythonhosted.org/packages/50/cc/a46b34f1708d82498c227d5d80ce615b2dd502ddcfd8376fc14a36655af1/pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7a66efda2387de898c8f38c0cf7f14fca0b51a8ef0b24bfea5849f1b3c95af27", size = 1999404 }, + { url = "https://files.pythonhosted.org/packages/ca/2d/c365cfa930ed23bc58c41463bae347d1005537dc8db79e998af8ba28d35e/pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:18a101c168e4e092ab40dbc2503bdc0f62010e95d292b27827871dc85450d7ee", size = 2130130 }, + { url = "https://files.pythonhosted.org/packages/f4/d7/eb64d015c350b7cdb371145b54d96c919d4db516817f31cd1c650cae3b21/pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ba5dd002f88b78a4215ed2f8ddbdf85e8513382820ba15ad5ad8955ce0ca19a1", size = 2157946 }, + { url = "https://files.pythonhosted.org/packages/a4/99/bddde3ddde76c03b65dfd5a66ab436c4e58ffc42927d4ff1198ffbf96f5f/pydantic_core-2.27.2-cp313-cp313-win32.whl", hash = "sha256:1ebaf1d0481914d004a573394f4be3a7616334be70261007e47c2a6fe7e50130", size = 1834387 }, + { url = "https://files.pythonhosted.org/packages/71/47/82b5e846e01b26ac6f1893d3c5f9f3a2eb6ba79be26eef0b759b4fe72946/pydantic_core-2.27.2-cp313-cp313-win_amd64.whl", hash = "sha256:953101387ecf2f5652883208769a79e48db18c6df442568a0b5ccd8c2723abee", size = 1990453 }, + { url = "https://files.pythonhosted.org/packages/51/b2/b2b50d5ecf21acf870190ae5d093602d95f66c9c31f9d5de6062eb329ad1/pydantic_core-2.27.2-cp313-cp313-win_arm64.whl", hash = "sha256:ac4dbfd1691affb8f48c2c13241a2e3b60ff23247cbcf981759c768b6633cf8b", size = 1885186 }, ] [[package]] @@ -1315,7 +1316,7 @@ wheels = [ [[package]] name = "pylint" -version = "3.3.1" +version = "3.3.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "astroid" }, @@ -1326,22 +1327,22 @@ dependencies = [ { name = "platformdirs" }, { name = "tomlkit" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/63/3a/13e90e29777e695d90f422cf4fadb81c999e4755a9089838561bd0590cac/pylint-3.3.1.tar.gz", hash = "sha256:9f3dcc87b1203e612b78d91a896407787e708b3f189b5fa0b307712d49ff0c6e", size = 1516703 } +sdist = { url = "https://files.pythonhosted.org/packages/17/fd/e9a739afac274a39596bbe562e9d966db6f3917fdb2bd7322ffc56da0ba2/pylint-3.3.3.tar.gz", hash = "sha256:07c607523b17e6d16e2ae0d7ef59602e332caa762af64203c24b41c27139f36a", size = 1516550 } wheels = [ - { url = "https://files.pythonhosted.org/packages/4d/11/4a3f814eee14593f3cfcf7046bc765bf1646d5c88132c08c45310fc7d85f/pylint-3.3.1-py3-none-any.whl", hash = "sha256:2f846a466dd023513240bc140ad2dd73bfc080a5d85a710afdb728c420a5a2b9", size = 521768 }, + { url = "https://files.pythonhosted.org/packages/91/e1/26d55acea92b1ea4d33672e48f09ceeb274e84d7d542a4fb9a32a556db46/pylint-3.3.3-py3-none-any.whl", hash = "sha256:26e271a2bc8bce0fc23833805a9076dd9b4d5194e2a02164942cb3cdc37b4183", size = 521918 }, ] [[package]] name = "pymdown-extensions" -version = "10.11.2" +version = "10.14.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "markdown" }, { name = "pyyaml" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/f4/71/2730a20e9e3752393d78998347f8b1085ef9c417646ea9befbeef221e3c4/pymdown_extensions-10.11.2.tar.gz", hash = "sha256:bc8847ecc9e784a098efd35e20cba772bc5a1b529dfcef9dc1972db9021a1049", size = 830241 } +sdist = { url = "https://files.pythonhosted.org/packages/e7/24/f7a412dc1630b1a6d7b288e7c736215ce878ee4aad24359f7f67b53bbaa9/pymdown_extensions-10.14.1.tar.gz", hash = "sha256:b65801996a0cd4f42a3110810c306c45b7313c09b0610a6f773730f2a9e3c96b", size = 845243 } wheels = [ - { url = "https://files.pythonhosted.org/packages/c2/35/c0edf199257ef0a7d407d29cd51c4e70d1dad4370a5f44deb65a7a5475e2/pymdown_extensions-10.11.2-py3-none-any.whl", hash = "sha256:41cdde0a77290e480cf53892f5c5e50921a7ee3e5cd60ba91bf19837b33badcf", size = 259044 }, + { url = "https://files.pythonhosted.org/packages/09/fb/79a8d27966e90feeeb686395c8b1bff8221727abcbd80d2485841393a955/pymdown_extensions-10.14.1-py3-none-any.whl", hash = "sha256:637951cbfbe9874ba28134fb3ce4b8bcadd6aca89ac4998ec29dcbafd554ae08", size = 264283 }, ] [[package]] @@ -1538,55 +1539,55 @@ wheels = [ [[package]] name = "regex" -version = "2024.9.11" +version = "2024.11.6" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f9/38/148df33b4dbca3bd069b963acab5e0fa1a9dbd6820f8c322d0dd6faeff96/regex-2024.9.11.tar.gz", hash = "sha256:6c188c307e8433bcb63dc1915022deb553b4203a70722fc542c363bf120a01fd", size = 399403 } +sdist = { url = "https://files.pythonhosted.org/packages/8e/5f/bd69653fbfb76cf8604468d3b4ec4c403197144c7bfe0e6a5fc9e02a07cb/regex-2024.11.6.tar.gz", hash = "sha256:7ab159b063c52a0333c884e4679f8d7a85112ee3078fe3d9004b2dd875585519", size = 399494 } wheels = [ - { url = "https://files.pythonhosted.org/packages/86/a1/d526b7b6095a0019aa360948c143aacfeb029919c898701ce7763bbe4c15/regex-2024.9.11-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2cce2449e5927a0bf084d346da6cd5eb016b2beca10d0013ab50e3c226ffc0df", size = 482483 }, - { url = "https://files.pythonhosted.org/packages/32/d9/bfdd153179867c275719e381e1e8e84a97bd186740456a0dcb3e7125c205/regex-2024.9.11-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3b37fa423beefa44919e009745ccbf353d8c981516e807995b2bd11c2c77d268", size = 287442 }, - { url = "https://files.pythonhosted.org/packages/33/c4/60f3370735135e3a8d673ddcdb2507a8560d0e759e1398d366e43d000253/regex-2024.9.11-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:64ce2799bd75039b480cc0360907c4fb2f50022f030bf9e7a8705b636e408fad", size = 284561 }, - { url = "https://files.pythonhosted.org/packages/b1/51/91a5ebdff17f9ec4973cb0aa9d37635efec1c6868654bbc25d1543aca4ec/regex-2024.9.11-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a4cc92bb6db56ab0c1cbd17294e14f5e9224f0cc6521167ef388332604e92679", size = 791779 }, - { url = "https://files.pythonhosted.org/packages/07/4a/022c5e6f0891a90cd7eb3d664d6c58ce2aba48bff107b00013f3d6167069/regex-2024.9.11-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d05ac6fa06959c4172eccd99a222e1fbf17b5670c4d596cb1e5cde99600674c4", size = 832605 }, - { url = "https://files.pythonhosted.org/packages/ac/1c/3793990c8c83ca04e018151ddda83b83ecc41d89964f0f17749f027fc44d/regex-2024.9.11-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:040562757795eeea356394a7fb13076ad4f99d3c62ab0f8bdfb21f99a1f85664", size = 818556 }, - { url = "https://files.pythonhosted.org/packages/e9/5c/8b385afbfacb853730682c57be56225f9fe275c5bf02ac1fc88edbff316d/regex-2024.9.11-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6113c008a7780792efc80f9dfe10ba0cd043cbf8dc9a76ef757850f51b4edc50", size = 792808 }, - { url = "https://files.pythonhosted.org/packages/9b/8b/a4723a838b53c771e9240951adde6af58c829fb6a6a28f554e8131f53839/regex-2024.9.11-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8e5fb5f77c8745a60105403a774fe2c1759b71d3e7b4ca237a5e67ad066c7199", size = 781115 }, - { url = "https://files.pythonhosted.org/packages/83/5f/031a04b6017033d65b261259c09043c06f4ef2d4eac841d0649d76d69541/regex-2024.9.11-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:54d9ff35d4515debf14bc27f1e3b38bfc453eff3220f5bce159642fa762fe5d4", size = 778155 }, - { url = "https://files.pythonhosted.org/packages/fd/cd/4660756070b03ce4a66663a43f6c6e7ebc2266cc6b4c586c167917185eb4/regex-2024.9.11-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:df5cbb1fbc74a8305b6065d4ade43b993be03dbe0f8b30032cced0d7740994bd", size = 784614 }, - { url = "https://files.pythonhosted.org/packages/93/8d/65b9bea7df120a7be8337c415b6d256ba786cbc9107cebba3bf8ff09da99/regex-2024.9.11-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:7fb89ee5d106e4a7a51bce305ac4efb981536301895f7bdcf93ec92ae0d91c7f", size = 853744 }, - { url = "https://files.pythonhosted.org/packages/96/a7/fba1eae75eb53a704475baf11bd44b3e6ccb95b316955027eb7748f24ef8/regex-2024.9.11-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:a738b937d512b30bf75995c0159c0ddf9eec0775c9d72ac0202076c72f24aa96", size = 855890 }, - { url = "https://files.pythonhosted.org/packages/45/14/d864b2db80a1a3358534392373e8a281d95b28c29c87d8548aed58813910/regex-2024.9.11-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e28f9faeb14b6f23ac55bfbbfd3643f5c7c18ede093977f1df249f73fd22c7b1", size = 781887 }, - { url = "https://files.pythonhosted.org/packages/4d/a9/bfb29b3de3eb11dc9b412603437023b8e6c02fb4e11311863d9bf62c403a/regex-2024.9.11-cp311-cp311-win32.whl", hash = "sha256:18e707ce6c92d7282dfce370cd205098384b8ee21544e7cb29b8aab955b66fa9", size = 261644 }, - { url = "https://files.pythonhosted.org/packages/c7/ab/1ad2511cf6a208fde57fafe49829cab8ca018128ab0d0b48973d8218634a/regex-2024.9.11-cp311-cp311-win_amd64.whl", hash = "sha256:313ea15e5ff2a8cbbad96ccef6be638393041b0a7863183c2d31e0c6116688cf", size = 274033 }, - { url = "https://files.pythonhosted.org/packages/6e/92/407531450762bed778eedbde04407f68cbd75d13cee96c6f8d6903d9c6c1/regex-2024.9.11-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:b0d0a6c64fcc4ef9c69bd5b3b3626cc3776520a1637d8abaa62b9edc147a58f7", size = 483590 }, - { url = "https://files.pythonhosted.org/packages/8e/a2/048acbc5ae1f615adc6cba36cc45734e679b5f1e4e58c3c77f0ed611d4e2/regex-2024.9.11-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:49b0e06786ea663f933f3710a51e9385ce0cba0ea56b67107fd841a55d56a231", size = 288175 }, - { url = "https://files.pythonhosted.org/packages/8a/ea/909d8620329ab710dfaf7b4adee41242ab7c9b95ea8d838e9bfe76244259/regex-2024.9.11-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5b513b6997a0b2f10e4fd3a1313568e373926e8c252bd76c960f96fd039cd28d", size = 284749 }, - { url = "https://files.pythonhosted.org/packages/ca/fa/521eb683b916389b4975337873e66954e0f6d8f91bd5774164a57b503185/regex-2024.9.11-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ee439691d8c23e76f9802c42a95cfeebf9d47cf4ffd06f18489122dbb0a7ad64", size = 795181 }, - { url = "https://files.pythonhosted.org/packages/28/db/63047feddc3280cc242f9c74f7aeddc6ee662b1835f00046f57d5630c827/regex-2024.9.11-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a8f877c89719d759e52783f7fe6e1c67121076b87b40542966c02de5503ace42", size = 835842 }, - { url = "https://files.pythonhosted.org/packages/e3/94/86adc259ff8ec26edf35fcca7e334566c1805c7493b192cb09679f9c3dee/regex-2024.9.11-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:23b30c62d0f16827f2ae9f2bb87619bc4fba2044911e2e6c2eb1af0161cdb766", size = 823533 }, - { url = "https://files.pythonhosted.org/packages/29/52/84662b6636061277cb857f658518aa7db6672bc6d1a3f503ccd5aefc581e/regex-2024.9.11-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:85ab7824093d8f10d44330fe1e6493f756f252d145323dd17ab6b48733ff6c0a", size = 797037 }, - { url = "https://files.pythonhosted.org/packages/c3/2a/cd4675dd987e4a7505f0364a958bc41f3b84942de9efaad0ef9a2646681c/regex-2024.9.11-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8dee5b4810a89447151999428fe096977346cf2f29f4d5e29609d2e19e0199c9", size = 784106 }, - { url = "https://files.pythonhosted.org/packages/6f/75/3ea7ec29de0bbf42f21f812f48781d41e627d57a634f3f23947c9a46e303/regex-2024.9.11-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:98eeee2f2e63edae2181c886d7911ce502e1292794f4c5ee71e60e23e8d26b5d", size = 782468 }, - { url = "https://files.pythonhosted.org/packages/d3/67/15519d69b52c252b270e679cb578e22e0c02b8dd4e361f2b04efcc7f2335/regex-2024.9.11-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:57fdd2e0b2694ce6fc2e5ccf189789c3e2962916fb38779d3e3521ff8fe7a822", size = 790324 }, - { url = "https://files.pythonhosted.org/packages/9c/71/eff77d3fe7ba08ab0672920059ec30d63fa7e41aa0fb61c562726e9bd721/regex-2024.9.11-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:d552c78411f60b1fdaafd117a1fca2f02e562e309223b9d44b7de8be451ec5e0", size = 860214 }, - { url = "https://files.pythonhosted.org/packages/81/11/e1bdf84a72372e56f1ea4b833dd583b822a23138a616ace7ab57a0e11556/regex-2024.9.11-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:a0b2b80321c2ed3fcf0385ec9e51a12253c50f146fddb2abbb10f033fe3d049a", size = 859420 }, - { url = "https://files.pythonhosted.org/packages/ea/75/9753e9dcebfa7c3645563ef5c8a58f3a47e799c872165f37c55737dadd3e/regex-2024.9.11-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:18406efb2f5a0e57e3a5881cd9354c1512d3bb4f5c45d96d110a66114d84d23a", size = 787333 }, - { url = "https://files.pythonhosted.org/packages/bc/4e/ba1cbca93141f7416624b3ae63573e785d4bc1834c8be44a8f0747919eca/regex-2024.9.11-cp312-cp312-win32.whl", hash = "sha256:e464b467f1588e2c42d26814231edecbcfe77f5ac414d92cbf4e7b55b2c2a776", size = 262058 }, - { url = "https://files.pythonhosted.org/packages/6e/16/efc5f194778bf43e5888209e5cec4b258005d37c613b67ae137df3b89c53/regex-2024.9.11-cp312-cp312-win_amd64.whl", hash = "sha256:9e8719792ca63c6b8340380352c24dcb8cd7ec49dae36e963742a275dfae6009", size = 273526 }, - { url = "https://files.pythonhosted.org/packages/93/0a/d1c6b9af1ff1e36832fe38d74d5c5bab913f2bdcbbd6bc0e7f3ce8b2f577/regex-2024.9.11-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:c157bb447303070f256e084668b702073db99bbb61d44f85d811025fcf38f784", size = 483376 }, - { url = "https://files.pythonhosted.org/packages/a4/42/5910a050c105d7f750a72dcb49c30220c3ae4e2654e54aaaa0e9bc0584cb/regex-2024.9.11-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4db21ece84dfeefc5d8a3863f101995de646c6cb0536952c321a2650aa202c36", size = 288112 }, - { url = "https://files.pythonhosted.org/packages/8d/56/0c262aff0e9224fa7ffce47b5458d373f4d3e3ff84e99b5ff0cb15e0b5b2/regex-2024.9.11-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:220e92a30b426daf23bb67a7962900ed4613589bab80382be09b48896d211e92", size = 284608 }, - { url = "https://files.pythonhosted.org/packages/b9/54/9fe8f9aec5007bbbbce28ba3d2e3eaca425f95387b7d1e84f0d137d25237/regex-2024.9.11-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eb1ae19e64c14c7ec1995f40bd932448713d3c73509e82d8cd7744dc00e29e86", size = 795337 }, - { url = "https://files.pythonhosted.org/packages/b2/e7/6b2f642c3cded271c4f16cc4daa7231be544d30fe2b168e0223724b49a61/regex-2024.9.11-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f47cd43a5bfa48f86925fe26fbdd0a488ff15b62468abb5d2a1e092a4fb10e85", size = 835848 }, - { url = "https://files.pythonhosted.org/packages/cd/9e/187363bdf5d8c0e4662117b92aa32bf52f8f09620ae93abc7537d96d3311/regex-2024.9.11-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9d4a76b96f398697fe01117093613166e6aa8195d63f1b4ec3f21ab637632963", size = 823503 }, - { url = "https://files.pythonhosted.org/packages/f8/10/601303b8ee93589f879664b0cfd3127949ff32b17f9b6c490fb201106c4d/regex-2024.9.11-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ea51dcc0835eea2ea31d66456210a4e01a076d820e9039b04ae8d17ac11dee6", size = 797049 }, - { url = "https://files.pythonhosted.org/packages/ef/1c/ea200f61ce9f341763f2717ab4daebe4422d83e9fd4ac5e33435fd3a148d/regex-2024.9.11-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b7aaa315101c6567a9a45d2839322c51c8d6e81f67683d529512f5bcfb99c802", size = 784144 }, - { url = "https://files.pythonhosted.org/packages/d8/5c/d2429be49ef3292def7688401d3deb11702c13dcaecdc71d2b407421275b/regex-2024.9.11-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c57d08ad67aba97af57a7263c2d9006d5c404d721c5f7542f077f109ec2a4a29", size = 782483 }, - { url = "https://files.pythonhosted.org/packages/12/d9/cbc30f2ff7164f3b26a7760f87c54bf8b2faed286f60efd80350a51c5b99/regex-2024.9.11-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:f8404bf61298bb6f8224bb9176c1424548ee1181130818fcd2cbffddc768bed8", size = 790320 }, - { url = "https://files.pythonhosted.org/packages/19/1d/43ed03a236313639da5a45e61bc553c8d41e925bcf29b0f8ecff0c2c3f25/regex-2024.9.11-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:dd4490a33eb909ef5078ab20f5f000087afa2a4daa27b4c072ccb3cb3050ad84", size = 860435 }, - { url = "https://files.pythonhosted.org/packages/34/4f/5d04da61c7c56e785058a46349f7285ae3ebc0726c6ea7c5c70600a52233/regex-2024.9.11-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:eee9130eaad130649fd73e5cd92f60e55708952260ede70da64de420cdcad554", size = 859571 }, - { url = "https://files.pythonhosted.org/packages/12/7f/8398c8155a3c70703a8e91c29532558186558e1aea44144b382faa2a6f7a/regex-2024.9.11-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6a2644a93da36c784e546de579ec1806bfd2763ef47babc1b03d765fe560c9f8", size = 787398 }, - { url = "https://files.pythonhosted.org/packages/58/3a/f5903977647a9a7e46d5535e9e96c194304aeeca7501240509bde2f9e17f/regex-2024.9.11-cp313-cp313-win32.whl", hash = "sha256:e997fd30430c57138adc06bba4c7c2968fb13d101e57dd5bb9355bf8ce3fa7e8", size = 262035 }, - { url = "https://files.pythonhosted.org/packages/ff/80/51ba3a4b7482f6011095b3a036e07374f64de180b7d870b704ed22509002/regex-2024.9.11-cp313-cp313-win_amd64.whl", hash = "sha256:042c55879cfeb21a8adacc84ea347721d3d83a159da6acdf1116859e2427c43f", size = 273510 }, + { url = "https://files.pythonhosted.org/packages/58/58/7e4d9493a66c88a7da6d205768119f51af0f684fe7be7bac8328e217a52c/regex-2024.11.6-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5478c6962ad548b54a591778e93cd7c456a7a29f8eca9c49e4f9a806dcc5d638", size = 482669 }, + { url = "https://files.pythonhosted.org/packages/34/4c/8f8e631fcdc2ff978609eaeef1d6994bf2f028b59d9ac67640ed051f1218/regex-2024.11.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2c89a8cc122b25ce6945f0423dc1352cb9593c68abd19223eebbd4e56612c5b7", size = 287684 }, + { url = "https://files.pythonhosted.org/packages/c5/1b/f0e4d13e6adf866ce9b069e191f303a30ab1277e037037a365c3aad5cc9c/regex-2024.11.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:94d87b689cdd831934fa3ce16cc15cd65748e6d689f5d2b8f4f4df2065c9fa20", size = 284589 }, + { url = "https://files.pythonhosted.org/packages/25/4d/ab21047f446693887f25510887e6820b93f791992994f6498b0318904d4a/regex-2024.11.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1062b39a0a2b75a9c694f7a08e7183a80c63c0d62b301418ffd9c35f55aaa114", size = 792121 }, + { url = "https://files.pythonhosted.org/packages/45/ee/c867e15cd894985cb32b731d89576c41a4642a57850c162490ea34b78c3b/regex-2024.11.6-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:167ed4852351d8a750da48712c3930b031f6efdaa0f22fa1933716bfcd6bf4a3", size = 831275 }, + { url = "https://files.pythonhosted.org/packages/b3/12/b0f480726cf1c60f6536fa5e1c95275a77624f3ac8fdccf79e6727499e28/regex-2024.11.6-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d548dafee61f06ebdb584080621f3e0c23fff312f0de1afc776e2a2ba99a74f", size = 818257 }, + { url = "https://files.pythonhosted.org/packages/bf/ce/0d0e61429f603bac433910d99ef1a02ce45a8967ffbe3cbee48599e62d88/regex-2024.11.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2a19f302cd1ce5dd01a9099aaa19cae6173306d1302a43b627f62e21cf18ac0", size = 792727 }, + { url = "https://files.pythonhosted.org/packages/e4/c1/243c83c53d4a419c1556f43777ccb552bccdf79d08fda3980e4e77dd9137/regex-2024.11.6-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bec9931dfb61ddd8ef2ebc05646293812cb6b16b60cf7c9511a832b6f1854b55", size = 780667 }, + { url = "https://files.pythonhosted.org/packages/c5/f4/75eb0dd4ce4b37f04928987f1d22547ddaf6c4bae697623c1b05da67a8aa/regex-2024.11.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9714398225f299aa85267fd222f7142fcb5c769e73d7733344efc46f2ef5cf89", size = 776963 }, + { url = "https://files.pythonhosted.org/packages/16/5d/95c568574e630e141a69ff8a254c2f188b4398e813c40d49228c9bbd9875/regex-2024.11.6-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:202eb32e89f60fc147a41e55cb086db2a3f8cb82f9a9a88440dcfc5d37faae8d", size = 784700 }, + { url = "https://files.pythonhosted.org/packages/8e/b5/f8495c7917f15cc6fee1e7f395e324ec3e00ab3c665a7dc9d27562fd5290/regex-2024.11.6-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:4181b814e56078e9b00427ca358ec44333765f5ca1b45597ec7446d3a1ef6e34", size = 848592 }, + { url = "https://files.pythonhosted.org/packages/1c/80/6dd7118e8cb212c3c60b191b932dc57db93fb2e36fb9e0e92f72a5909af9/regex-2024.11.6-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:068376da5a7e4da51968ce4c122a7cd31afaaec4fccc7856c92f63876e57b51d", size = 852929 }, + { url = "https://files.pythonhosted.org/packages/11/9b/5a05d2040297d2d254baf95eeeb6df83554e5e1df03bc1a6687fc4ba1f66/regex-2024.11.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ac10f2c4184420d881a3475fb2c6f4d95d53a8d50209a2500723d831036f7c45", size = 781213 }, + { url = "https://files.pythonhosted.org/packages/26/b7/b14e2440156ab39e0177506c08c18accaf2b8932e39fb092074de733d868/regex-2024.11.6-cp311-cp311-win32.whl", hash = "sha256:c36f9b6f5f8649bb251a5f3f66564438977b7ef8386a52460ae77e6070d309d9", size = 261734 }, + { url = "https://files.pythonhosted.org/packages/80/32/763a6cc01d21fb3819227a1cc3f60fd251c13c37c27a73b8ff4315433a8e/regex-2024.11.6-cp311-cp311-win_amd64.whl", hash = "sha256:02e28184be537f0e75c1f9b2f8847dc51e08e6e171c6bde130b2687e0c33cf60", size = 274052 }, + { url = "https://files.pythonhosted.org/packages/ba/30/9a87ce8336b172cc232a0db89a3af97929d06c11ceaa19d97d84fa90a8f8/regex-2024.11.6-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:52fb28f528778f184f870b7cf8f225f5eef0a8f6e3778529bdd40c7b3920796a", size = 483781 }, + { url = "https://files.pythonhosted.org/packages/01/e8/00008ad4ff4be8b1844786ba6636035f7ef926db5686e4c0f98093612add/regex-2024.11.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fdd6028445d2460f33136c55eeb1f601ab06d74cb3347132e1c24250187500d9", size = 288455 }, + { url = "https://files.pythonhosted.org/packages/60/85/cebcc0aff603ea0a201667b203f13ba75d9fc8668fab917ac5b2de3967bc/regex-2024.11.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:805e6b60c54bf766b251e94526ebad60b7de0c70f70a4e6210ee2891acb70bf2", size = 284759 }, + { url = "https://files.pythonhosted.org/packages/94/2b/701a4b0585cb05472a4da28ee28fdfe155f3638f5e1ec92306d924e5faf0/regex-2024.11.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b85c2530be953a890eaffde05485238f07029600e8f098cdf1848d414a8b45e4", size = 794976 }, + { url = "https://files.pythonhosted.org/packages/4b/bf/fa87e563bf5fee75db8915f7352e1887b1249126a1be4813837f5dbec965/regex-2024.11.6-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bb26437975da7dc36b7efad18aa9dd4ea569d2357ae6b783bf1118dabd9ea577", size = 833077 }, + { url = "https://files.pythonhosted.org/packages/a1/56/7295e6bad94b047f4d0834e4779491b81216583c00c288252ef625c01d23/regex-2024.11.6-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:abfa5080c374a76a251ba60683242bc17eeb2c9818d0d30117b4486be10c59d3", size = 823160 }, + { url = "https://files.pythonhosted.org/packages/fb/13/e3b075031a738c9598c51cfbc4c7879e26729c53aa9cca59211c44235314/regex-2024.11.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b7fa6606c2881c1db9479b0eaa11ed5dfa11c8d60a474ff0e095099f39d98e", size = 796896 }, + { url = "https://files.pythonhosted.org/packages/24/56/0b3f1b66d592be6efec23a795b37732682520b47c53da5a32c33ed7d84e3/regex-2024.11.6-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0c32f75920cf99fe6b6c539c399a4a128452eaf1af27f39bce8909c9a3fd8cbe", size = 783997 }, + { url = "https://files.pythonhosted.org/packages/f9/a1/eb378dada8b91c0e4c5f08ffb56f25fcae47bf52ad18f9b2f33b83e6d498/regex-2024.11.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:982e6d21414e78e1f51cf595d7f321dcd14de1f2881c5dc6a6e23bbbbd68435e", size = 781725 }, + { url = "https://files.pythonhosted.org/packages/83/f2/033e7dec0cfd6dda93390089864732a3409246ffe8b042e9554afa9bff4e/regex-2024.11.6-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a7c2155f790e2fb448faed6dd241386719802296ec588a8b9051c1f5c481bc29", size = 789481 }, + { url = "https://files.pythonhosted.org/packages/83/23/15d4552ea28990a74e7696780c438aadd73a20318c47e527b47a4a5a596d/regex-2024.11.6-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:149f5008d286636e48cd0b1dd65018548944e495b0265b45e1bffecce1ef7f39", size = 852896 }, + { url = "https://files.pythonhosted.org/packages/e3/39/ed4416bc90deedbfdada2568b2cb0bc1fdb98efe11f5378d9892b2a88f8f/regex-2024.11.6-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:e5364a4502efca094731680e80009632ad6624084aff9a23ce8c8c6820de3e51", size = 860138 }, + { url = "https://files.pythonhosted.org/packages/93/2d/dd56bb76bd8e95bbce684326302f287455b56242a4f9c61f1bc76e28360e/regex-2024.11.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0a86e7eeca091c09e021db8eb72d54751e527fa47b8d5787caf96d9831bd02ad", size = 787692 }, + { url = "https://files.pythonhosted.org/packages/0b/55/31877a249ab7a5156758246b9c59539abbeba22461b7d8adc9e8475ff73e/regex-2024.11.6-cp312-cp312-win32.whl", hash = "sha256:32f9a4c643baad4efa81d549c2aadefaeba12249b2adc5af541759237eee1c54", size = 262135 }, + { url = "https://files.pythonhosted.org/packages/38/ec/ad2d7de49a600cdb8dd78434a1aeffe28b9d6fc42eb36afab4a27ad23384/regex-2024.11.6-cp312-cp312-win_amd64.whl", hash = "sha256:a93c194e2df18f7d264092dc8539b8ffb86b45b899ab976aa15d48214138e81b", size = 273567 }, + { url = "https://files.pythonhosted.org/packages/90/73/bcb0e36614601016552fa9344544a3a2ae1809dc1401b100eab02e772e1f/regex-2024.11.6-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a6ba92c0bcdf96cbf43a12c717eae4bc98325ca3730f6b130ffa2e3c3c723d84", size = 483525 }, + { url = "https://files.pythonhosted.org/packages/0f/3f/f1a082a46b31e25291d830b369b6b0c5576a6f7fb89d3053a354c24b8a83/regex-2024.11.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:525eab0b789891ac3be914d36893bdf972d483fe66551f79d3e27146191a37d4", size = 288324 }, + { url = "https://files.pythonhosted.org/packages/09/c9/4e68181a4a652fb3ef5099e077faf4fd2a694ea6e0f806a7737aff9e758a/regex-2024.11.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:086a27a0b4ca227941700e0b31425e7a28ef1ae8e5e05a33826e17e47fbfdba0", size = 284617 }, + { url = "https://files.pythonhosted.org/packages/fc/fd/37868b75eaf63843165f1d2122ca6cb94bfc0271e4428cf58c0616786dce/regex-2024.11.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bde01f35767c4a7899b7eb6e823b125a64de314a8ee9791367c9a34d56af18d0", size = 795023 }, + { url = "https://files.pythonhosted.org/packages/c4/7c/d4cd9c528502a3dedb5c13c146e7a7a539a3853dc20209c8e75d9ba9d1b2/regex-2024.11.6-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b583904576650166b3d920d2bcce13971f6f9e9a396c673187f49811b2769dc7", size = 833072 }, + { url = "https://files.pythonhosted.org/packages/4f/db/46f563a08f969159c5a0f0e722260568425363bea43bb7ae370becb66a67/regex-2024.11.6-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1c4de13f06a0d54fa0d5ab1b7138bfa0d883220965a29616e3ea61b35d5f5fc7", size = 823130 }, + { url = "https://files.pythonhosted.org/packages/db/60/1eeca2074f5b87df394fccaa432ae3fc06c9c9bfa97c5051aed70e6e00c2/regex-2024.11.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3cde6e9f2580eb1665965ce9bf17ff4952f34f5b126beb509fee8f4e994f143c", size = 796857 }, + { url = "https://files.pythonhosted.org/packages/10/db/ac718a08fcee981554d2f7bb8402f1faa7e868c1345c16ab1ebec54b0d7b/regex-2024.11.6-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0d7f453dca13f40a02b79636a339c5b62b670141e63efd511d3f8f73fba162b3", size = 784006 }, + { url = "https://files.pythonhosted.org/packages/c2/41/7da3fe70216cea93144bf12da2b87367590bcf07db97604edeea55dac9ad/regex-2024.11.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:59dfe1ed21aea057a65c6b586afd2a945de04fc7db3de0a6e3ed5397ad491b07", size = 781650 }, + { url = "https://files.pythonhosted.org/packages/a7/d5/880921ee4eec393a4752e6ab9f0fe28009435417c3102fc413f3fe81c4e5/regex-2024.11.6-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b97c1e0bd37c5cd7902e65f410779d39eeda155800b65fc4d04cc432efa9bc6e", size = 789545 }, + { url = "https://files.pythonhosted.org/packages/dc/96/53770115e507081122beca8899ab7f5ae28ae790bfcc82b5e38976df6a77/regex-2024.11.6-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f9d1e379028e0fc2ae3654bac3cbbef81bf3fd571272a42d56c24007979bafb6", size = 853045 }, + { url = "https://files.pythonhosted.org/packages/31/d3/1372add5251cc2d44b451bd94f43b2ec78e15a6e82bff6a290ef9fd8f00a/regex-2024.11.6-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:13291b39131e2d002a7940fb176e120bec5145f3aeb7621be6534e46251912c4", size = 860182 }, + { url = "https://files.pythonhosted.org/packages/ed/e3/c446a64984ea9f69982ba1a69d4658d5014bc7a0ea468a07e1a1265db6e2/regex-2024.11.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4f51f88c126370dcec4908576c5a627220da6c09d0bff31cfa89f2523843316d", size = 787733 }, + { url = "https://files.pythonhosted.org/packages/2b/f1/e40c8373e3480e4f29f2692bd21b3e05f296d3afebc7e5dcf21b9756ca1c/regex-2024.11.6-cp313-cp313-win32.whl", hash = "sha256:63b13cfd72e9601125027202cad74995ab26921d8cd935c25f09c630436348ff", size = 262122 }, + { url = "https://files.pythonhosted.org/packages/45/94/bc295babb3062a731f52621cdc992d123111282e291abaf23faa413443ea/regex-2024.11.6-cp313-cp313-win_amd64.whl", hash = "sha256:2b3361af3198667e99927da8b84c1b010752fa4b1115ee30beaa332cabc3ef1a", size = 273545 }, ] [[package]] @@ -1619,27 +1620,27 @@ wheels = [ [[package]] name = "ruff" -version = "0.6.9" +version = "0.9.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/26/0d/6148a48dab5662ca1d5a93b7c0d13c03abd3cc7e2f35db08410e47cef15d/ruff-0.6.9.tar.gz", hash = "sha256:b076ef717a8e5bc819514ee1d602bbdca5b4420ae13a9cf61a0c0a4f53a2baa2", size = 3095355 } +sdist = { url = "https://files.pythonhosted.org/packages/1e/7f/60fda2eec81f23f8aa7cbbfdf6ec2ca11eb11c273827933fb2541c2ce9d8/ruff-0.9.3.tar.gz", hash = "sha256:8293f89985a090ebc3ed1064df31f3b4b56320cdfcec8b60d3295bddb955c22a", size = 3586740 } wheels = [ - { url = "https://files.pythonhosted.org/packages/6e/8f/f7a0a0ef1818662efb32ed6df16078c95da7a0a3248d64c2410c1e27799f/ruff-0.6.9-py3-none-linux_armv6l.whl", hash = "sha256:064df58d84ccc0ac0fcd63bc3090b251d90e2a372558c0f057c3f75ed73e1ccd", size = 10440526 }, - { url = "https://files.pythonhosted.org/packages/8b/69/b179a5faf936a9e2ab45bb412a668e4661eded964ccfa19d533f29463ef6/ruff-0.6.9-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:140d4b5c9f5fc7a7b074908a78ab8d384dd7f6510402267bc76c37195c02a7ec", size = 10034612 }, - { url = "https://files.pythonhosted.org/packages/c7/ef/fd1b4be979c579d191eeac37b5cfc0ec906de72c8bcd8595e2c81bb700c1/ruff-0.6.9-py3-none-macosx_11_0_arm64.whl", hash = "sha256:53fd8ca5e82bdee8da7f506d7b03a261f24cd43d090ea9db9a1dc59d9313914c", size = 9706197 }, - { url = "https://files.pythonhosted.org/packages/29/61/b376d775deb5851cb48d893c568b511a6d3625ef2c129ad5698b64fb523c/ruff-0.6.9-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:645d7d8761f915e48a00d4ecc3686969761df69fb561dd914a773c1a8266e14e", size = 10751855 }, - { url = "https://files.pythonhosted.org/packages/13/d7/def9e5f446d75b9a9c19b24231a3a658c075d79163b08582e56fa5dcfa38/ruff-0.6.9-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:eae02b700763e3847595b9d2891488989cac00214da7f845f4bcf2989007d577", size = 10200889 }, - { url = "https://files.pythonhosted.org/packages/6c/d6/7f34160818bcb6e84ce293a5966cba368d9112ff0289b273fbb689046047/ruff-0.6.9-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7d5ccc9e58112441de8ad4b29dcb7a86dc25c5f770e3c06a9d57e0e5eba48829", size = 11038678 }, - { url = "https://files.pythonhosted.org/packages/13/34/a40ff8ae62fb1b26fb8e6fa7e64bc0e0a834b47317880de22edd6bfb54fb/ruff-0.6.9-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:417b81aa1c9b60b2f8edc463c58363075412866ae4e2b9ab0f690dc1e87ac1b5", size = 11808682 }, - { url = "https://files.pythonhosted.org/packages/2e/6d/25a4386ae4009fc798bd10ba48c942d1b0b3e459b5403028f1214b6dd161/ruff-0.6.9-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3c866b631f5fbce896a74a6e4383407ba7507b815ccc52bcedabb6810fdb3ef7", size = 11330446 }, - { url = "https://files.pythonhosted.org/packages/f7/f6/bdf891a9200d692c94ebcd06ae5a2fa5894e522f2c66c2a12dd5d8cb2654/ruff-0.6.9-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7b118afbb3202f5911486ad52da86d1d52305b59e7ef2031cea3425142b97d6f", size = 12483048 }, - { url = "https://files.pythonhosted.org/packages/a7/86/96f4252f41840e325b3fa6c48297e661abb9f564bd7dcc0572398c8daa42/ruff-0.6.9-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a67267654edc23c97335586774790cde402fb6bbdb3c2314f1fc087dee320bfa", size = 10936855 }, - { url = "https://files.pythonhosted.org/packages/45/87/801a52d26c8dbf73424238e9908b9ceac430d903c8ef35eab1b44fcfa2bd/ruff-0.6.9-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:3ef0cc774b00fec123f635ce5c547dac263f6ee9fb9cc83437c5904183b55ceb", size = 10713007 }, - { url = "https://files.pythonhosted.org/packages/be/27/6f7161d90320a389695e32b6ebdbfbedde28ccbf52451e4b723d7ce744ad/ruff-0.6.9-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:12edd2af0c60fa61ff31cefb90aef4288ac4d372b4962c2864aeea3a1a2460c0", size = 10274594 }, - { url = "https://files.pythonhosted.org/packages/00/52/dc311775e7b5f5b19831563cb1572ecce63e62681bccc609867711fae317/ruff-0.6.9-py3-none-musllinux_1_2_i686.whl", hash = "sha256:55bb01caeaf3a60b2b2bba07308a02fca6ab56233302406ed5245180a05c5625", size = 10608024 }, - { url = "https://files.pythonhosted.org/packages/98/b6/be0a1ddcbac65a30c985cf7224c4fce786ba2c51e7efeb5178fe410ed3cf/ruff-0.6.9-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:925d26471fa24b0ce5a6cdfab1bb526fb4159952385f386bdcc643813d472039", size = 10982085 }, - { url = "https://files.pythonhosted.org/packages/bb/a4/c84bc13d0b573cf7bb7d17b16d6d29f84267c92d79b2f478d4ce322e8e72/ruff-0.6.9-py3-none-win32.whl", hash = "sha256:eb61ec9bdb2506cffd492e05ac40e5bc6284873aceb605503d8494180d6fc84d", size = 8522088 }, - { url = "https://files.pythonhosted.org/packages/74/be/fc352bd8ca40daae8740b54c1c3e905a7efe470d420a268cd62150248c91/ruff-0.6.9-py3-none-win_amd64.whl", hash = "sha256:785d31851c1ae91f45b3d8fe23b8ae4b5170089021fbb42402d811135f0b7117", size = 9359275 }, - { url = "https://files.pythonhosted.org/packages/3e/14/fd026bc74ded05e2351681545a5f626e78ef831f8edce064d61acd2e6ec7/ruff-0.6.9-py3-none-win_arm64.whl", hash = "sha256:a9641e31476d601f83cd602608739a0840e348bda93fec9f1ee816f8b6798b93", size = 8679879 }, + { url = "https://files.pythonhosted.org/packages/f9/77/4fb790596d5d52c87fd55b7160c557c400e90f6116a56d82d76e95d9374a/ruff-0.9.3-py3-none-linux_armv6l.whl", hash = "sha256:7f39b879064c7d9670197d91124a75d118d00b0990586549949aae80cdc16624", size = 11656815 }, + { url = "https://files.pythonhosted.org/packages/a2/a8/3338ecb97573eafe74505f28431df3842c1933c5f8eae615427c1de32858/ruff-0.9.3-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:a187171e7c09efa4b4cc30ee5d0d55a8d6c5311b3e1b74ac5cb96cc89bafc43c", size = 11594821 }, + { url = "https://files.pythonhosted.org/packages/8e/89/320223c3421962762531a6b2dd58579b858ca9916fb2674874df5e97d628/ruff-0.9.3-py3-none-macosx_11_0_arm64.whl", hash = "sha256:c59ab92f8e92d6725b7ded9d4a31be3ef42688a115c6d3da9457a5bda140e2b4", size = 11040475 }, + { url = "https://files.pythonhosted.org/packages/b2/bd/1d775eac5e51409535804a3a888a9623e87a8f4b53e2491580858a083692/ruff-0.9.3-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2dc153c25e715be41bb228bc651c1e9b1a88d5c6e5ed0194fa0dfea02b026439", size = 11856207 }, + { url = "https://files.pythonhosted.org/packages/7f/c6/3e14e09be29587393d188454064a4aa85174910d16644051a80444e4fd88/ruff-0.9.3-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:646909a1e25e0dc28fbc529eab8eb7bb583079628e8cbe738192853dbbe43af5", size = 11420460 }, + { url = "https://files.pythonhosted.org/packages/ef/42/b7ca38ffd568ae9b128a2fa76353e9a9a3c80ef19746408d4ce99217ecc1/ruff-0.9.3-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5a5a46e09355695fbdbb30ed9889d6cf1c61b77b700a9fafc21b41f097bfbba4", size = 12605472 }, + { url = "https://files.pythonhosted.org/packages/a6/a1/3167023f23e3530fde899497ccfe239e4523854cb874458ac082992d206c/ruff-0.9.3-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:c4bb09d2bbb394e3730d0918c00276e79b2de70ec2a5231cd4ebb51a57df9ba1", size = 13243123 }, + { url = "https://files.pythonhosted.org/packages/d0/b4/3c600758e320f5bf7de16858502e849f4216cb0151f819fa0d1154874802/ruff-0.9.3-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:96a87ec31dc1044d8c2da2ebbed1c456d9b561e7d087734336518181b26b3aa5", size = 12744650 }, + { url = "https://files.pythonhosted.org/packages/be/38/266fbcbb3d0088862c9bafa8b1b99486691d2945a90b9a7316336a0d9a1b/ruff-0.9.3-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9bb7554aca6f842645022fe2d301c264e6925baa708b392867b7a62645304df4", size = 14458585 }, + { url = "https://files.pythonhosted.org/packages/63/a6/47fd0e96990ee9b7a4abda62de26d291bd3f7647218d05b7d6d38af47c30/ruff-0.9.3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cabc332b7075a914ecea912cd1f3d4370489c8018f2c945a30bcc934e3bc06a6", size = 12419624 }, + { url = "https://files.pythonhosted.org/packages/84/5d/de0b7652e09f7dda49e1a3825a164a65f4998175b6486603c7601279baad/ruff-0.9.3-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:33866c3cc2a575cbd546f2cd02bdd466fed65118e4365ee538a3deffd6fcb730", size = 11843238 }, + { url = "https://files.pythonhosted.org/packages/9e/be/3f341ceb1c62b565ec1fb6fd2139cc40b60ae6eff4b6fb8f94b1bb37c7a9/ruff-0.9.3-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:006e5de2621304c8810bcd2ee101587712fa93b4f955ed0985907a36c427e0c2", size = 11484012 }, + { url = "https://files.pythonhosted.org/packages/a3/c8/ff8acbd33addc7e797e702cf00bfde352ab469723720c5607b964491d5cf/ruff-0.9.3-py3-none-musllinux_1_2_i686.whl", hash = "sha256:ba6eea4459dbd6b1be4e6bfc766079fb9b8dd2e5a35aff6baee4d9b1514ea519", size = 12038494 }, + { url = "https://files.pythonhosted.org/packages/73/b1/8d9a2c0efbbabe848b55f877bc10c5001a37ab10aca13c711431673414e5/ruff-0.9.3-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:90230a6b8055ad47d3325e9ee8f8a9ae7e273078a66401ac66df68943ced029b", size = 12473639 }, + { url = "https://files.pythonhosted.org/packages/cb/44/a673647105b1ba6da9824a928634fe23186ab19f9d526d7bdf278cd27bc3/ruff-0.9.3-py3-none-win32.whl", hash = "sha256:eabe5eb2c19a42f4808c03b82bd313fc84d4e395133fb3fc1b1516170a31213c", size = 9834353 }, + { url = "https://files.pythonhosted.org/packages/c3/01/65cadb59bf8d4fbe33d1a750103e6883d9ef302f60c28b73b773092fbde5/ruff-0.9.3-py3-none-win_amd64.whl", hash = "sha256:040ceb7f20791dfa0e78b4230ee9dce23da3b64dd5848e40e3bf3ab76468dcf4", size = 10821444 }, + { url = "https://files.pythonhosted.org/packages/69/cb/b3fe58a136a27d981911cba2f18e4b29f15010623b79f0f2510fd0d31fd3/ruff-0.9.3-py3-none-win_arm64.whl", hash = "sha256:800d773f6d4d33b0a3c60e2c6ae8f4c202ea2de056365acfa519aa48acf28e0b", size = 10038168 }, ] [[package]] @@ -1729,11 +1730,11 @@ wheels = [ [[package]] name = "smmap" -version = "5.0.1" +version = "5.0.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/88/04/b5bf6d21dc4041000ccba7eb17dd3055feb237e7ffc2c20d3fae3af62baa/smmap-5.0.1.tar.gz", hash = "sha256:dceeb6c0028fdb6734471eb07c0cd2aae706ccaecab45965ee83f11c8d3b1f62", size = 22291 } +sdist = { url = "https://files.pythonhosted.org/packages/44/cd/a040c4b3119bbe532e5b0732286f805445375489fceaec1f48306068ee3b/smmap-5.0.2.tar.gz", hash = "sha256:26ea65a03958fa0c8a1c7e8c7a58fdc77221b8910f6be2131affade476898ad5", size = 22329 } wheels = [ - { url = "https://files.pythonhosted.org/packages/a7/a5/10f97f73544edcdef54409f1d839f6049a0d79df68adbc1ceb24d1aaca42/smmap-5.0.1-py3-none-any.whl", hash = "sha256:e6d8668fa5f93e706934a62d7b4db19c8d9eb8cf2adbb75ef1b675aa332b69da", size = 24282 }, + { url = "https://files.pythonhosted.org/packages/04/be/d09147ad1ec7934636ad912901c5fd7667e1c858e19d355237db0d0cd5e4/smmap-5.0.2-py3-none-any.whl", hash = "sha256:b30115f0def7d7531d22a0fb6502488d879e75b260a9db4d0819cfb25403af5e", size = 24303 }, ] [[package]] @@ -1758,14 +1759,14 @@ sdist = { url = "https://files.pythonhosted.org/packages/7e/ee/6748afd822a2cc26f [[package]] name = "tinycss2" -version = "1.3.0" +version = "1.4.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "webencodings" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/44/6f/38d2335a2b70b9982d112bb177e3dbe169746423e33f718bf5e9c7b3ddd3/tinycss2-1.3.0.tar.gz", hash = "sha256:152f9acabd296a8375fbca5b84c961ff95971fcfc32e79550c8df8e29118c54d", size = 67360 } +sdist = { url = "https://files.pythonhosted.org/packages/7a/fd/7a5ee21fd08ff70d3d33a5781c255cbe779659bd03278feb98b19ee550f4/tinycss2-1.4.0.tar.gz", hash = "sha256:10c0972f6fc0fbee87c3edb76549357415e94548c1ae10ebccdea16fb404a9b7", size = 87085 } wheels = [ - { url = "https://files.pythonhosted.org/packages/2c/4d/0db5b8a613d2a59bbc29bc5bb44a2f8070eb9ceab11c50d477502a8a0092/tinycss2-1.3.0-py3-none-any.whl", hash = "sha256:54a8dbdffb334d536851be0226030e9505965bb2f30f21a4a82c55fb2a80fae7", size = 22532 }, + { url = "https://files.pythonhosted.org/packages/e6/34/ebdc18bae6aa14fbee1a08b63c015c72b64868ff7dae68808ab500c492e2/tinycss2-1.4.0-py3-none-any.whl", hash = "sha256:3a49cf47b7675da0b15d0c6e1df8df4ebd96e9394bb905a5775adb0d884c5289", size = 26610 }, ] [[package]] @@ -1788,11 +1789,11 @@ wheels = [ [[package]] name = "urllib3" -version = "2.2.3" +version = "2.3.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ed/63/22ba4ebfe7430b76388e7cd448d5478814d3032121827c12a2cc287e2260/urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9", size = 300677 } +sdist = { url = "https://files.pythonhosted.org/packages/aa/63/e53da845320b757bf29ef6a9062f5c669fe997973f966045cb019c3f4b66/urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d", size = 307268 } wheels = [ - { url = "https://files.pythonhosted.org/packages/ce/d9/5f4c13cecde62396b0d3fe530a50ccea91e7dfc1ccf0e09c228841bb5ba8/urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac", size = 126338 }, + { url = "https://files.pythonhosted.org/packages/c8/19/4ec628951a74043532ca2cf5d97b7b14863931476d117c471e8e2b1eb39f/urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df", size = 128369 }, ] [[package]] @@ -1823,29 +1824,29 @@ wheels = [ [[package]] name = "watchdog" -version = "5.0.3" +version = "6.0.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a2/48/a86139aaeab2db0a2482676f64798d8ac4d2dbb457523f50ab37bf02ce2c/watchdog-5.0.3.tar.gz", hash = "sha256:108f42a7f0345042a854d4d0ad0834b741d421330d5f575b81cb27b883500176", size = 129556 } +sdist = { url = "https://files.pythonhosted.org/packages/db/7d/7f3d619e951c88ed75c6037b246ddcf2d322812ee8ea189be89511721d54/watchdog-6.0.0.tar.gz", hash = "sha256:9ddf7c82fda3ae8e24decda1338ede66e1c99883db93711d8fb941eaa2d8c282", size = 131220 } wheels = [ - { url = "https://files.pythonhosted.org/packages/70/34/946f08602f8b8e6af45bc725e4a8013975a34883ab5570bd0d827a4c9829/watchdog-5.0.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:f01f4a3565a387080dc49bdd1fefe4ecc77f894991b88ef927edbfa45eb10818", size = 96650 }, - { url = "https://files.pythonhosted.org/packages/96/2b/b84e35d49e8b0bad77e5d086fc1e2c6c833bbfe74d53144cfe8b26117eff/watchdog-5.0.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:91b522adc25614cdeaf91f7897800b82c13b4b8ac68a42ca959f992f6990c490", size = 88653 }, - { url = "https://files.pythonhosted.org/packages/d5/3f/41b5d77c10f450b79921c17b7d0b416616048867bfe63acaa072a619a0cb/watchdog-5.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d52db5beb5e476e6853da2e2d24dbbbed6797b449c8bf7ea118a4ee0d2c9040e", size = 89286 }, - { url = "https://files.pythonhosted.org/packages/1c/9b/8b206a928c188fdeb7b12e1c795199534cd44bdef223b8470129016009dd/watchdog-5.0.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:94d11b07c64f63f49876e0ab8042ae034674c8653bfcdaa8c4b32e71cfff87e8", size = 96739 }, - { url = "https://files.pythonhosted.org/packages/e1/26/129ca9cd0f8016672f37000010c2fedc0b86816e894ebdc0af9bb04a6439/watchdog-5.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:349c9488e1d85d0a58e8cb14222d2c51cbc801ce11ac3936ab4c3af986536926", size = 88708 }, - { url = "https://files.pythonhosted.org/packages/8f/b3/5e10ec32f0c429cdb55b1369066d6e83faf9985b3a53a4e37bb5c5e29aa0/watchdog-5.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:53a3f10b62c2d569e260f96e8d966463dec1a50fa4f1b22aec69e3f91025060e", size = 89309 }, - { url = "https://files.pythonhosted.org/packages/54/c4/49af4ab00bcfb688e9962eace2edda07a2cf89b9699ea536da48e8585cff/watchdog-5.0.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:950f531ec6e03696a2414b6308f5c6ff9dab7821a768c9d5788b1314e9a46ca7", size = 96740 }, - { url = "https://files.pythonhosted.org/packages/96/a4/b24de77cc9ae424c1687c9d4fb15aa560d7d7b28ba559aca72f781d0202b/watchdog-5.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ae6deb336cba5d71476caa029ceb6e88047fc1dc74b62b7c4012639c0b563906", size = 88711 }, - { url = "https://files.pythonhosted.org/packages/a4/71/3f2e9fe8403386b99d788868955b3a790f7a09721501a7e1eb58f514ffaa/watchdog-5.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1021223c08ba8d2d38d71ec1704496471ffd7be42cfb26b87cd5059323a389a1", size = 89319 }, - { url = "https://files.pythonhosted.org/packages/60/33/7cb71c9df9a77b6927ee5f48d25e1de5562ce0fa7e0c56dcf2b0472e64a2/watchdog-5.0.3-py3-none-manylinux2014_aarch64.whl", hash = "sha256:dd021efa85970bd4824acacbb922066159d0f9e546389a4743d56919b6758b91", size = 79335 }, - { url = "https://files.pythonhosted.org/packages/f6/91/320bc1496cf951a3cf93a7ffd18a581f0792c304be963d943e0e608c2919/watchdog-5.0.3-py3-none-manylinux2014_armv7l.whl", hash = "sha256:78864cc8f23dbee55be34cc1494632a7ba30263951b5b2e8fc8286b95845f82c", size = 79334 }, - { url = "https://files.pythonhosted.org/packages/8b/2c/567c5e042ed667d3544c43d48a65cf853450a2d2a9089d9523a65f195e94/watchdog-5.0.3-py3-none-manylinux2014_i686.whl", hash = "sha256:1e9679245e3ea6498494b3028b90c7b25dbb2abe65c7d07423ecfc2d6218ff7c", size = 79333 }, - { url = "https://files.pythonhosted.org/packages/c3/f0/64059fe162ef3274662e67bbdea6c45b3cd53e846d5bd1365fcdc3dc1d15/watchdog-5.0.3-py3-none-manylinux2014_ppc64.whl", hash = "sha256:9413384f26b5d050b6978e6fcd0c1e7f0539be7a4f1a885061473c5deaa57221", size = 79334 }, - { url = "https://files.pythonhosted.org/packages/f6/d9/19b7d02965be2801e2d0f6f4bde23e4ae172620071b65430fa0c2f8441ac/watchdog-5.0.3-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:294b7a598974b8e2c6123d19ef15de9abcd282b0fbbdbc4d23dfa812959a9e05", size = 79333 }, - { url = "https://files.pythonhosted.org/packages/cb/a1/5393ac6d0b095d3a44946b09258e9b5f22cb2fb67bcfa419dd868478826c/watchdog-5.0.3-py3-none-manylinux2014_s390x.whl", hash = "sha256:26dd201857d702bdf9d78c273cafcab5871dd29343748524695cecffa44a8d97", size = 79332 }, - { url = "https://files.pythonhosted.org/packages/a0/58/edec25190b6403caf4426dd418234f2358a106634b7d6aa4aec6939b104f/watchdog-5.0.3-py3-none-manylinux2014_x86_64.whl", hash = "sha256:0f9332243355643d567697c3e3fa07330a1d1abf981611654a1f2bf2175612b7", size = 79334 }, - { url = "https://files.pythonhosted.org/packages/97/69/cfb2d17ba8aabc73be2e2d03c8c319b1f32053a02c4b571852983aa24ff2/watchdog-5.0.3-py3-none-win32.whl", hash = "sha256:c66f80ee5b602a9c7ab66e3c9f36026590a0902db3aea414d59a2f55188c1f49", size = 79320 }, - { url = "https://files.pythonhosted.org/packages/91/b4/2b5b59358dadfa2c8676322f955b6c22cde4937602f40490e2f7403e548e/watchdog-5.0.3-py3-none-win_amd64.whl", hash = "sha256:f00b4cf737f568be9665563347a910f8bdc76f88c2970121c86243c8cfdf90e9", size = 79325 }, - { url = "https://files.pythonhosted.org/packages/38/b8/0aa69337651b3005f161f7f494e59188a1d8d94171666900d26d29d10f69/watchdog-5.0.3-py3-none-win_ia64.whl", hash = "sha256:49f4d36cb315c25ea0d946e018c01bb028048023b9e103d3d3943f58e109dd45", size = 79324 }, + { url = "https://files.pythonhosted.org/packages/e0/24/d9be5cd6642a6aa68352ded4b4b10fb0d7889cb7f45814fb92cecd35f101/watchdog-6.0.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6eb11feb5a0d452ee41f824e271ca311a09e250441c262ca2fd7ebcf2461a06c", size = 96393 }, + { url = "https://files.pythonhosted.org/packages/63/7a/6013b0d8dbc56adca7fdd4f0beed381c59f6752341b12fa0886fa7afc78b/watchdog-6.0.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ef810fbf7b781a5a593894e4f439773830bdecb885e6880d957d5b9382a960d2", size = 88392 }, + { url = "https://files.pythonhosted.org/packages/d1/40/b75381494851556de56281e053700e46bff5b37bf4c7267e858640af5a7f/watchdog-6.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:afd0fe1b2270917c5e23c2a65ce50c2a4abb63daafb0d419fde368e272a76b7c", size = 89019 }, + { url = "https://files.pythonhosted.org/packages/39/ea/3930d07dafc9e286ed356a679aa02d777c06e9bfd1164fa7c19c288a5483/watchdog-6.0.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:bdd4e6f14b8b18c334febb9c4425a878a2ac20efd1e0b231978e7b150f92a948", size = 96471 }, + { url = "https://files.pythonhosted.org/packages/12/87/48361531f70b1f87928b045df868a9fd4e253d9ae087fa4cf3f7113be363/watchdog-6.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c7c15dda13c4eb00d6fb6fc508b3c0ed88b9d5d374056b239c4ad1611125c860", size = 88449 }, + { url = "https://files.pythonhosted.org/packages/5b/7e/8f322f5e600812e6f9a31b75d242631068ca8f4ef0582dd3ae6e72daecc8/watchdog-6.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6f10cb2d5902447c7d0da897e2c6768bca89174d0c6e1e30abec5421af97a5b0", size = 89054 }, + { url = "https://files.pythonhosted.org/packages/68/98/b0345cabdce2041a01293ba483333582891a3bd5769b08eceb0d406056ef/watchdog-6.0.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:490ab2ef84f11129844c23fb14ecf30ef3d8a6abafd3754a6f75ca1e6654136c", size = 96480 }, + { url = "https://files.pythonhosted.org/packages/85/83/cdf13902c626b28eedef7ec4f10745c52aad8a8fe7eb04ed7b1f111ca20e/watchdog-6.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:76aae96b00ae814b181bb25b1b98076d5fc84e8a53cd8885a318b42b6d3a5134", size = 88451 }, + { url = "https://files.pythonhosted.org/packages/fe/c4/225c87bae08c8b9ec99030cd48ae9c4eca050a59bf5c2255853e18c87b50/watchdog-6.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a175f755fc2279e0b7312c0035d52e27211a5bc39719dd529625b1930917345b", size = 89057 }, + { url = "https://files.pythonhosted.org/packages/a9/c7/ca4bf3e518cb57a686b2feb4f55a1892fd9a3dd13f470fca14e00f80ea36/watchdog-6.0.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:7607498efa04a3542ae3e05e64da8202e58159aa1fa4acddf7678d34a35d4f13", size = 79079 }, + { url = "https://files.pythonhosted.org/packages/5c/51/d46dc9332f9a647593c947b4b88e2381c8dfc0942d15b8edc0310fa4abb1/watchdog-6.0.0-py3-none-manylinux2014_armv7l.whl", hash = "sha256:9041567ee8953024c83343288ccc458fd0a2d811d6a0fd68c4c22609e3490379", size = 79078 }, + { url = "https://files.pythonhosted.org/packages/d4/57/04edbf5e169cd318d5f07b4766fee38e825d64b6913ca157ca32d1a42267/watchdog-6.0.0-py3-none-manylinux2014_i686.whl", hash = "sha256:82dc3e3143c7e38ec49d61af98d6558288c415eac98486a5c581726e0737c00e", size = 79076 }, + { url = "https://files.pythonhosted.org/packages/ab/cc/da8422b300e13cb187d2203f20b9253e91058aaf7db65b74142013478e66/watchdog-6.0.0-py3-none-manylinux2014_ppc64.whl", hash = "sha256:212ac9b8bf1161dc91bd09c048048a95ca3a4c4f5e5d4a7d1b1a7d5752a7f96f", size = 79077 }, + { url = "https://files.pythonhosted.org/packages/2c/3b/b8964e04ae1a025c44ba8e4291f86e97fac443bca31de8bd98d3263d2fcf/watchdog-6.0.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:e3df4cbb9a450c6d49318f6d14f4bbc80d763fa587ba46ec86f99f9e6876bb26", size = 79078 }, + { url = "https://files.pythonhosted.org/packages/62/ae/a696eb424bedff7407801c257d4b1afda455fe40821a2be430e173660e81/watchdog-6.0.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:2cce7cfc2008eb51feb6aab51251fd79b85d9894e98ba847408f662b3395ca3c", size = 79077 }, + { url = "https://files.pythonhosted.org/packages/b5/e8/dbf020b4d98251a9860752a094d09a65e1b436ad181faf929983f697048f/watchdog-6.0.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:20ffe5b202af80ab4266dcd3e91aae72bf2da48c0d33bdb15c66658e685e94e2", size = 79078 }, + { url = "https://files.pythonhosted.org/packages/07/f6/d0e5b343768e8bcb4cda79f0f2f55051bf26177ecd5651f84c07567461cf/watchdog-6.0.0-py3-none-win32.whl", hash = "sha256:07df1fdd701c5d4c8e55ef6cf55b8f0120fe1aef7ef39a1c6fc6bc2e606d517a", size = 79065 }, + { url = "https://files.pythonhosted.org/packages/db/d9/c495884c6e548fce18a8f40568ff120bc3a4b7b99813081c8ac0c936fa64/watchdog-6.0.0-py3-none-win_amd64.whl", hash = "sha256:cbafb470cf848d93b5d013e2ecb245d4aa1c8fd0504e863ccefa32445359d680", size = 79070 }, + { url = "https://files.pythonhosted.org/packages/33/e8/e40370e6d74ddba47f002a32919d91310d6074130fe4e17dabcafc15cbf1/watchdog-6.0.0-py3-none-win_ia64.whl", hash = "sha256:a1914259fa9e1454315171103c6a30961236f508b9b623eae470268bbcc6a22f", size = 79067 }, ] [[package]] @@ -1859,56 +1860,56 @@ wheels = [ [[package]] name = "websockets" -version = "13.1" +version = "14.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e2/73/9223dbc7be3dcaf2a7bbf756c351ec8da04b1fa573edaf545b95f6b0c7fd/websockets-13.1.tar.gz", hash = "sha256:a3b3366087c1bc0a2795111edcadddb8b3b59509d5db5d7ea3fdd69f954a8878", size = 158549 } +sdist = { url = "https://files.pythonhosted.org/packages/94/54/8359678c726243d19fae38ca14a334e740782336c9f19700858c4eb64a1e/websockets-14.2.tar.gz", hash = "sha256:5059ed9c54945efb321f097084b4c7e52c246f2c869815876a69d1efc4ad6eb5", size = 164394 } wheels = [ - { url = "https://files.pythonhosted.org/packages/b2/f0/cf0b8a30d86b49e267ac84addbebbc7a48a6e7bb7c19db80f62411452311/websockets-13.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:61fc0dfcda609cda0fc9fe7977694c0c59cf9d749fbb17f4e9483929e3c48a19", size = 157813 }, - { url = "https://files.pythonhosted.org/packages/bf/e7/22285852502e33071a8cf0ac814f8988480ec6db4754e067b8b9d0e92498/websockets-13.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ceec59f59d092c5007e815def4ebb80c2de330e9588e101cf8bd94c143ec78a5", size = 155469 }, - { url = "https://files.pythonhosted.org/packages/68/d4/c8c7c1e5b40ee03c5cc235955b0fb1ec90e7e37685a5f69229ad4708dcde/websockets-13.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c1dca61c6db1166c48b95198c0b7d9c990b30c756fc2923cc66f68d17dc558fd", size = 155717 }, - { url = "https://files.pythonhosted.org/packages/c9/e4/c50999b9b848b1332b07c7fd8886179ac395cb766fda62725d1539e7bc6c/websockets-13.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:308e20f22c2c77f3f39caca508e765f8725020b84aa963474e18c59accbf4c02", size = 165379 }, - { url = "https://files.pythonhosted.org/packages/bc/49/4a4ad8c072f18fd79ab127650e47b160571aacfc30b110ee305ba25fffc9/websockets-13.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:62d516c325e6540e8a57b94abefc3459d7dab8ce52ac75c96cad5549e187e3a7", size = 164376 }, - { url = "https://files.pythonhosted.org/packages/af/9b/8c06d425a1d5a74fd764dd793edd02be18cf6fc3b1ccd1f29244ba132dc0/websockets-13.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87c6e35319b46b99e168eb98472d6c7d8634ee37750d7693656dc766395df096", size = 164753 }, - { url = "https://files.pythonhosted.org/packages/d5/5b/0acb5815095ff800b579ffc38b13ab1b915b317915023748812d24e0c1ac/websockets-13.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:5f9fee94ebafbc3117c30be1844ed01a3b177bb6e39088bc6b2fa1dc15572084", size = 165051 }, - { url = "https://files.pythonhosted.org/packages/30/93/c3891c20114eacb1af09dedfcc620c65c397f4fd80a7009cd12d9457f7f5/websockets-13.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:7c1e90228c2f5cdde263253fa5db63e6653f1c00e7ec64108065a0b9713fa1b3", size = 164489 }, - { url = "https://files.pythonhosted.org/packages/28/09/af9e19885539759efa2e2cd29b8b3f9eecef7ecefea40d46612f12138b36/websockets-13.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:6548f29b0e401eea2b967b2fdc1c7c7b5ebb3eeb470ed23a54cd45ef078a0db9", size = 164438 }, - { url = "https://files.pythonhosted.org/packages/b6/08/6f38b8e625b3d93de731f1d248cc1493327f16cb45b9645b3e791782cff0/websockets-13.1-cp311-cp311-win32.whl", hash = "sha256:c11d4d16e133f6df8916cc5b7e3e96ee4c44c936717d684a94f48f82edb7c92f", size = 158710 }, - { url = "https://files.pythonhosted.org/packages/fb/39/ec8832ecb9bb04a8d318149005ed8cee0ba4e0205835da99e0aa497a091f/websockets-13.1-cp311-cp311-win_amd64.whl", hash = "sha256:d04f13a1d75cb2b8382bdc16ae6fa58c97337253826dfe136195b7f89f661557", size = 159137 }, - { url = "https://files.pythonhosted.org/packages/df/46/c426282f543b3c0296cf964aa5a7bb17e984f58dde23460c3d39b3148fcf/websockets-13.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:9d75baf00138f80b48f1eac72ad1535aac0b6461265a0bcad391fc5aba875cfc", size = 157821 }, - { url = "https://files.pythonhosted.org/packages/aa/85/22529867010baac258da7c45848f9415e6cf37fef00a43856627806ffd04/websockets-13.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:9b6f347deb3dcfbfde1c20baa21c2ac0751afaa73e64e5b693bb2b848efeaa49", size = 155480 }, - { url = "https://files.pythonhosted.org/packages/29/2c/bdb339bfbde0119a6e84af43ebf6275278698a2241c2719afc0d8b0bdbf2/websockets-13.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:de58647e3f9c42f13f90ac7e5f58900c80a39019848c5547bc691693098ae1bd", size = 155715 }, - { url = "https://files.pythonhosted.org/packages/9f/d0/8612029ea04c5c22bf7af2fd3d63876c4eaeef9b97e86c11972a43aa0e6c/websockets-13.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1b54689e38d1279a51d11e3467dd2f3a50f5f2e879012ce8f2d6943f00e83f0", size = 165647 }, - { url = "https://files.pythonhosted.org/packages/56/04/1681ed516fa19ca9083f26d3f3a302257e0911ba75009533ed60fbb7b8d1/websockets-13.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cf1781ef73c073e6b0f90af841aaf98501f975d306bbf6221683dd594ccc52b6", size = 164592 }, - { url = "https://files.pythonhosted.org/packages/38/6f/a96417a49c0ed132bb6087e8e39a37db851c70974f5c724a4b2a70066996/websockets-13.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d23b88b9388ed85c6faf0e74d8dec4f4d3baf3ecf20a65a47b836d56260d4b9", size = 165012 }, - { url = "https://files.pythonhosted.org/packages/40/8b/fccf294919a1b37d190e86042e1a907b8f66cff2b61e9befdbce03783e25/websockets-13.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3c78383585f47ccb0fcf186dcb8a43f5438bd7d8f47d69e0b56f71bf431a0a68", size = 165311 }, - { url = "https://files.pythonhosted.org/packages/c1/61/f8615cf7ce5fe538476ab6b4defff52beb7262ff8a73d5ef386322d9761d/websockets-13.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:d6d300f8ec35c24025ceb9b9019ae9040c1ab2f01cddc2bcc0b518af31c75c14", size = 164692 }, - { url = "https://files.pythonhosted.org/packages/5c/f1/a29dd6046d3a722d26f182b783a7997d25298873a14028c4760347974ea3/websockets-13.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a9dcaf8b0cc72a392760bb8755922c03e17a5a54e08cca58e8b74f6902b433cf", size = 164686 }, - { url = "https://files.pythonhosted.org/packages/0f/99/ab1cdb282f7e595391226f03f9b498f52109d25a2ba03832e21614967dfa/websockets-13.1-cp312-cp312-win32.whl", hash = "sha256:2f85cf4f2a1ba8f602298a853cec8526c2ca42a9a4b947ec236eaedb8f2dc80c", size = 158712 }, - { url = "https://files.pythonhosted.org/packages/46/93/e19160db48b5581feac8468330aa11b7292880a94a37d7030478596cc14e/websockets-13.1-cp312-cp312-win_amd64.whl", hash = "sha256:38377f8b0cdeee97c552d20cf1865695fcd56aba155ad1b4ca8779a5b6ef4ac3", size = 159145 }, - { url = "https://files.pythonhosted.org/packages/51/20/2b99ca918e1cbd33c53db2cace5f0c0cd8296fc77558e1908799c712e1cd/websockets-13.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a9ab1e71d3d2e54a0aa646ab6d4eebfaa5f416fe78dfe4da2839525dc5d765c6", size = 157828 }, - { url = "https://files.pythonhosted.org/packages/b8/47/0932a71d3d9c0e9483174f60713c84cee58d62839a143f21a2bcdbd2d205/websockets-13.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:b9d7439d7fab4dce00570bb906875734df13d9faa4b48e261c440a5fec6d9708", size = 155487 }, - { url = "https://files.pythonhosted.org/packages/a9/60/f1711eb59ac7a6c5e98e5637fef5302f45b6f76a2c9d64fd83bbb341377a/websockets-13.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:327b74e915cf13c5931334c61e1a41040e365d380f812513a255aa804b183418", size = 155721 }, - { url = "https://files.pythonhosted.org/packages/6a/e6/ba9a8db7f9d9b0e5f829cf626ff32677f39824968317223605a6b419d445/websockets-13.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:325b1ccdbf5e5725fdcb1b0e9ad4d2545056479d0eee392c291c1bf76206435a", size = 165609 }, - { url = "https://files.pythonhosted.org/packages/c1/22/4ec80f1b9c27a0aebd84ccd857252eda8418ab9681eb571b37ca4c5e1305/websockets-13.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:346bee67a65f189e0e33f520f253d5147ab76ae42493804319b5716e46dddf0f", size = 164556 }, - { url = "https://files.pythonhosted.org/packages/27/ac/35f423cb6bb15600438db80755609d27eda36d4c0b3c9d745ea12766c45e/websockets-13.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:91a0fa841646320ec0d3accdff5b757b06e2e5c86ba32af2e0815c96c7a603c5", size = 164993 }, - { url = "https://files.pythonhosted.org/packages/31/4e/98db4fd267f8be9e52e86b6ee4e9aa7c42b83452ea0ea0672f176224b977/websockets-13.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:18503d2c5f3943e93819238bf20df71982d193f73dcecd26c94514f417f6b135", size = 165360 }, - { url = "https://files.pythonhosted.org/packages/3f/15/3f0de7cda70ffc94b7e7024544072bc5b26e2c1eb36545291abb755d8cdb/websockets-13.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:a9cd1af7e18e5221d2878378fbc287a14cd527fdd5939ed56a18df8a31136bb2", size = 164745 }, - { url = "https://files.pythonhosted.org/packages/a1/6e/66b6b756aebbd680b934c8bdbb6dcb9ce45aad72cde5f8a7208dbb00dd36/websockets-13.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:70c5be9f416aa72aab7a2a76c90ae0a4fe2755c1816c153c1a2bcc3333ce4ce6", size = 164732 }, - { url = "https://files.pythonhosted.org/packages/35/c6/12e3aab52c11aeb289e3dbbc05929e7a9d90d7a9173958477d3ef4f8ce2d/websockets-13.1-cp313-cp313-win32.whl", hash = "sha256:624459daabeb310d3815b276c1adef475b3e6804abaf2d9d2c061c319f7f187d", size = 158709 }, - { url = "https://files.pythonhosted.org/packages/41/d8/63d6194aae711d7263df4498200c690a9c39fb437ede10f3e157a6343e0d/websockets-13.1-cp313-cp313-win_amd64.whl", hash = "sha256:c518e84bb59c2baae725accd355c8dc517b4a3ed8db88b4bc93c78dae2974bf2", size = 159144 }, - { url = "https://files.pythonhosted.org/packages/56/27/96a5cd2626d11c8280656c6c71d8ab50fe006490ef9971ccd154e0c42cd2/websockets-13.1-py3-none-any.whl", hash = "sha256:a9a396a6ad26130cdae92ae10c36af09d9bfe6cafe69670fd3b6da9b07b4044f", size = 152134 }, + { url = "https://files.pythonhosted.org/packages/15/b6/504695fb9a33df0ca56d157f5985660b5fc5b4bf8c78f121578d2d653392/websockets-14.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:3bdc8c692c866ce5fefcaf07d2b55c91d6922ac397e031ef9b774e5b9ea42166", size = 163088 }, + { url = "https://files.pythonhosted.org/packages/81/26/ebfb8f6abe963c795122439c6433c4ae1e061aaedfc7eff32d09394afbae/websockets-14.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c93215fac5dadc63e51bcc6dceca72e72267c11def401d6668622b47675b097f", size = 160745 }, + { url = "https://files.pythonhosted.org/packages/a1/c6/1435ad6f6dcbff80bb95e8986704c3174da8866ddb751184046f5c139ef6/websockets-14.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1c9b6535c0e2cf8a6bf938064fb754aaceb1e6a4a51a80d884cd5db569886910", size = 160995 }, + { url = "https://files.pythonhosted.org/packages/96/63/900c27cfe8be1a1f2433fc77cd46771cf26ba57e6bdc7cf9e63644a61863/websockets-14.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0a52a6d7cf6938e04e9dceb949d35fbdf58ac14deea26e685ab6368e73744e4c", size = 170543 }, + { url = "https://files.pythonhosted.org/packages/00/8b/bec2bdba92af0762d42d4410593c1d7d28e9bfd952c97a3729df603dc6ea/websockets-14.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9f05702e93203a6ff5226e21d9b40c037761b2cfb637187c9802c10f58e40473", size = 169546 }, + { url = "https://files.pythonhosted.org/packages/6b/a9/37531cb5b994f12a57dec3da2200ef7aadffef82d888a4c29a0d781568e4/websockets-14.2-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:22441c81a6748a53bfcb98951d58d1af0661ab47a536af08920d129b4d1c3473", size = 169911 }, + { url = "https://files.pythonhosted.org/packages/60/d5/a6eadba2ed9f7e65d677fec539ab14a9b83de2b484ab5fe15d3d6d208c28/websockets-14.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:efd9b868d78b194790e6236d9cbc46d68aba4b75b22497eb4ab64fa640c3af56", size = 170183 }, + { url = "https://files.pythonhosted.org/packages/76/57/a338ccb00d1df881c1d1ee1f2a20c9c1b5b29b51e9e0191ee515d254fea6/websockets-14.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:1a5a20d5843886d34ff8c57424cc65a1deda4375729cbca4cb6b3353f3ce4142", size = 169623 }, + { url = "https://files.pythonhosted.org/packages/64/22/e5f7c33db0cb2c1d03b79fd60d189a1da044e2661f5fd01d629451e1db89/websockets-14.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:34277a29f5303d54ec6468fb525d99c99938607bc96b8d72d675dee2b9f5bf1d", size = 169583 }, + { url = "https://files.pythonhosted.org/packages/aa/2e/2b4662237060063a22e5fc40d46300a07142afe30302b634b4eebd717c07/websockets-14.2-cp311-cp311-win32.whl", hash = "sha256:02687db35dbc7d25fd541a602b5f8e451a238ffa033030b172ff86a93cb5dc2a", size = 163969 }, + { url = "https://files.pythonhosted.org/packages/94/a5/0cda64e1851e73fc1ecdae6f42487babb06e55cb2f0dc8904b81d8ef6857/websockets-14.2-cp311-cp311-win_amd64.whl", hash = "sha256:862e9967b46c07d4dcd2532e9e8e3c2825e004ffbf91a5ef9dde519ee2effb0b", size = 164408 }, + { url = "https://files.pythonhosted.org/packages/c1/81/04f7a397653dc8bec94ddc071f34833e8b99b13ef1a3804c149d59f92c18/websockets-14.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:1f20522e624d7ffbdbe259c6b6a65d73c895045f76a93719aa10cd93b3de100c", size = 163096 }, + { url = "https://files.pythonhosted.org/packages/ec/c5/de30e88557e4d70988ed4d2eabd73fd3e1e52456b9f3a4e9564d86353b6d/websockets-14.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:647b573f7d3ada919fd60e64d533409a79dcf1ea21daeb4542d1d996519ca967", size = 160758 }, + { url = "https://files.pythonhosted.org/packages/e5/8c/d130d668781f2c77d106c007b6c6c1d9db68239107c41ba109f09e6c218a/websockets-14.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6af99a38e49f66be5a64b1e890208ad026cda49355661549c507152113049990", size = 160995 }, + { url = "https://files.pythonhosted.org/packages/a6/bc/f6678a0ff17246df4f06765e22fc9d98d1b11a258cc50c5968b33d6742a1/websockets-14.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:091ab63dfc8cea748cc22c1db2814eadb77ccbf82829bac6b2fbe3401d548eda", size = 170815 }, + { url = "https://files.pythonhosted.org/packages/d8/b2/8070cb970c2e4122a6ef38bc5b203415fd46460e025652e1ee3f2f43a9a3/websockets-14.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b374e8953ad477d17e4851cdc66d83fdc2db88d9e73abf755c94510ebddceb95", size = 169759 }, + { url = "https://files.pythonhosted.org/packages/81/da/72f7caabd94652e6eb7e92ed2d3da818626e70b4f2b15a854ef60bf501ec/websockets-14.2-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a39d7eceeea35db85b85e1169011bb4321c32e673920ae9c1b6e0978590012a3", size = 170178 }, + { url = "https://files.pythonhosted.org/packages/31/e0/812725b6deca8afd3a08a2e81b3c4c120c17f68c9b84522a520b816cda58/websockets-14.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0a6f3efd47ffd0d12080594f434faf1cd2549b31e54870b8470b28cc1d3817d9", size = 170453 }, + { url = "https://files.pythonhosted.org/packages/66/d3/8275dbc231e5ba9bb0c4f93144394b4194402a7a0c8ffaca5307a58ab5e3/websockets-14.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:065ce275e7c4ffb42cb738dd6b20726ac26ac9ad0a2a48e33ca632351a737267", size = 169830 }, + { url = "https://files.pythonhosted.org/packages/a3/ae/e7d1a56755ae15ad5a94e80dd490ad09e345365199600b2629b18ee37bc7/websockets-14.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e9d0e53530ba7b8b5e389c02282f9d2aa47581514bd6049d3a7cffe1385cf5fe", size = 169824 }, + { url = "https://files.pythonhosted.org/packages/b6/32/88ccdd63cb261e77b882e706108d072e4f1c839ed723bf91a3e1f216bf60/websockets-14.2-cp312-cp312-win32.whl", hash = "sha256:20e6dd0984d7ca3037afcb4494e48c74ffb51e8013cac71cf607fffe11df7205", size = 163981 }, + { url = "https://files.pythonhosted.org/packages/b3/7d/32cdb77990b3bdc34a306e0a0f73a1275221e9a66d869f6ff833c95b56ef/websockets-14.2-cp312-cp312-win_amd64.whl", hash = "sha256:44bba1a956c2c9d268bdcdf234d5e5ff4c9b6dc3e300545cbe99af59dda9dcce", size = 164421 }, + { url = "https://files.pythonhosted.org/packages/82/94/4f9b55099a4603ac53c2912e1f043d6c49d23e94dd82a9ce1eb554a90215/websockets-14.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:6f1372e511c7409a542291bce92d6c83320e02c9cf392223272287ce55bc224e", size = 163102 }, + { url = "https://files.pythonhosted.org/packages/8e/b7/7484905215627909d9a79ae07070057afe477433fdacb59bf608ce86365a/websockets-14.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4da98b72009836179bb596a92297b1a61bb5a830c0e483a7d0766d45070a08ad", size = 160766 }, + { url = "https://files.pythonhosted.org/packages/a3/a4/edb62efc84adb61883c7d2c6ad65181cb087c64252138e12d655989eec05/websockets-14.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8a86a269759026d2bde227652b87be79f8a734e582debf64c9d302faa1e9f03", size = 160998 }, + { url = "https://files.pythonhosted.org/packages/f5/79/036d320dc894b96af14eac2529967a6fc8b74f03b83c487e7a0e9043d842/websockets-14.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:86cf1aaeca909bf6815ea714d5c5736c8d6dd3a13770e885aafe062ecbd04f1f", size = 170780 }, + { url = "https://files.pythonhosted.org/packages/63/75/5737d21ee4dd7e4b9d487ee044af24a935e36a9ff1e1419d684feedcba71/websockets-14.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9b0f6c3ba3b1240f602ebb3971d45b02cc12bd1845466dd783496b3b05783a5", size = 169717 }, + { url = "https://files.pythonhosted.org/packages/2c/3c/bf9b2c396ed86a0b4a92ff4cdaee09753d3ee389be738e92b9bbd0330b64/websockets-14.2-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:669c3e101c246aa85bc8534e495952e2ca208bd87994650b90a23d745902db9a", size = 170155 }, + { url = "https://files.pythonhosted.org/packages/75/2d/83a5aca7247a655b1da5eb0ee73413abd5c3a57fc8b92915805e6033359d/websockets-14.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:eabdb28b972f3729348e632ab08f2a7b616c7e53d5414c12108c29972e655b20", size = 170495 }, + { url = "https://files.pythonhosted.org/packages/79/dd/699238a92761e2f943885e091486378813ac8f43e3c84990bc394c2be93e/websockets-14.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2066dc4cbcc19f32c12a5a0e8cc1b7ac734e5b64ac0a325ff8353451c4b15ef2", size = 169880 }, + { url = "https://files.pythonhosted.org/packages/c8/c9/67a8f08923cf55ce61aadda72089e3ed4353a95a3a4bc8bf42082810e580/websockets-14.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ab95d357cd471df61873dadf66dd05dd4709cae001dd6342edafc8dc6382f307", size = 169856 }, + { url = "https://files.pythonhosted.org/packages/17/b1/1ffdb2680c64e9c3921d99db460546194c40d4acbef999a18c37aa4d58a3/websockets-14.2-cp313-cp313-win32.whl", hash = "sha256:a9e72fb63e5f3feacdcf5b4ff53199ec8c18d66e325c34ee4c551ca748623bbc", size = 163974 }, + { url = "https://files.pythonhosted.org/packages/14/13/8b7fc4cb551b9cfd9890f0fd66e53c18a06240319915533b033a56a3d520/websockets-14.2-cp313-cp313-win_amd64.whl", hash = "sha256:b439ea828c4ba99bb3176dc8d9b933392a2413c0f6b149fdcba48393f573377f", size = 164420 }, + { url = "https://files.pythonhosted.org/packages/7b/c8/d529f8a32ce40d98309f4470780631e971a5a842b60aec864833b3615786/websockets-14.2-py3-none-any.whl", hash = "sha256:7a6ceec4ea84469f15cf15807a747e9efe57e369c384fa86e022b3bea679b79b", size = 157416 }, ] [[package]] name = "werkzeug" -version = "3.0.4" +version = "3.1.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "markupsafe" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/0f/e2/6dbcaab07560909ff8f654d3a2e5a60552d937c909455211b1b36d7101dc/werkzeug-3.0.4.tar.gz", hash = "sha256:34f2371506b250df4d4f84bfe7b0921e4762525762bbd936614909fe25cd7306", size = 803966 } +sdist = { url = "https://files.pythonhosted.org/packages/9f/69/83029f1f6300c5fb2471d621ab06f6ec6b3324685a2ce0f9777fd4a8b71e/werkzeug-3.1.3.tar.gz", hash = "sha256:60723ce945c19328679790e3282cc758aa4a6040e4bb330f53d30fa546d44746", size = 806925 } wheels = [ - { url = "https://files.pythonhosted.org/packages/4b/84/997bbf7c2bf2dc3f09565c6d0b4959fefe5355c18c4096cfd26d83e0785b/werkzeug-3.0.4-py3-none-any.whl", hash = "sha256:02c9eb92b7d6c06f31a782811505d2157837cea66aaede3e217c7c27c039476c", size = 227554 }, + { url = "https://files.pythonhosted.org/packages/52/24/ab44c871b0f07f491e5d2ad12c9bd7358e527510618cb1b803a88e986db1/werkzeug-3.1.3-py3-none-any.whl", hash = "sha256:54b78bf3716d19a65be4fceccc0d1d7b89e608834989dfae50ea87564639213e", size = 224498 }, ] [[package]] From d5a248733a21b2f5657044b2eb9ff27ae017c165 Mon Sep 17 00:00:00 2001 From: cswimr Date: Sun, 26 Jan 2025 13:09:15 +0000 Subject: [PATCH 09/53] fix(pterodactyl): fix a ruff violation --- pterodactyl/mcsrvstatus.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pterodactyl/mcsrvstatus.py b/pterodactyl/mcsrvstatus.py index e51827a..0d06f64 100644 --- a/pterodactyl/mcsrvstatus.py +++ b/pterodactyl/mcsrvstatus.py @@ -3,8 +3,8 @@ import aiohttp async def get_status(host: str, port: int = 25565) -> tuple[bool, dict]: async with aiohttp.ClientSession() as session: - async with session.get(f'https://api.mcsrvstat.us/2/{host}:{port}') as response: - response = await response.json() - if response['online']: + async with session.get(f"https://api.mcsrvstat.us/2/{host}:{port}") as response: + response = await response.json() # noqa: PLW2901 + if response["online"]: return (True, response) return (False, response) From 5c5a2f28b21a459e3391e005a10b5501171011b8 Mon Sep 17 00:00:00 2001 From: cswimr Date: Sun, 26 Jan 2025 13:16:26 +0000 Subject: [PATCH 10/53] chore(repo): reformat pyproject.toml and disable a stupid linting rule --- pyproject.toml | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 160f994..7c337dc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -2,8 +2,8 @@ name = "seacogs" version = "0.1.0" description = "My assorted cogs for Red-DiscordBot." -authors = [{name = "cswimr", email = "seaswimmerthefsh@gmail.com"}] -license = {file="LICENSE"} +authors = [{ name = "cswimr", email = "seaswimmerthefsh@gmail.com" }] +license = { file = "LICENSE" } readme = "README.md" requires-python = ">=3.11" dependencies = [ @@ -33,11 +33,7 @@ documentation = [ ] [tool.uv] -dev-dependencies = [ - "pylint>=3.3.1", - "ruff>=0.6.9", - "sqlite-web>=0.6.4", -] +dev-dependencies = ["pylint>=3.3.1", "ruff>=0.6.9", "sqlite-web>=0.6.4"] [tool.uv.sources] py-dactyl = { git = "https://github.com/cswimr/pydactyl" } @@ -84,8 +80,22 @@ target-version = "py311" # Enable Pyflakes (`F`) and a subset of the pycodestyle (`E`) codes by default. # Unlike Flake8, Ruff doesn't enable pycodestyle warnings (`W`) or # McCabe complexity (`C901`) by default. -select = ["I", "N", "F", "W", "E", "G", "INP", "T20", "PLC", "PLE", "PLW", "PLR", "LOG"] -ignore = ["PLR0912", "PLR0915", "PLR2004"] +select = [ + "I", + "N", + "F", + "W", + "E", + "G", + "INP", + "T20", + "PLC", + "PLE", + "PLW", + "PLR", + "LOG", +] +ignore = ["PLR0912", "PLR0915", "PLR2004", "PLR0913"] # Allow fix for all enabled rules (when `--fix`) is provided. fixable = ["ALL"] From 7f2a81e3500d6572832ffea2377e7759544d0b73 Mon Sep 17 00:00:00 2001 From: cswimr Date: Sun, 26 Jan 2025 13:16:54 +0000 Subject: [PATCH 11/53] fix(bible): ruff fixes --- bible/bible.py | 22 +++++++++++----------- bible/models.py | 16 ++++++++-------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/bible/bible.py b/bible/bible.py index a1da890..0a976ec 100644 --- a/bible/bible.py +++ b/bible/bible.py @@ -27,7 +27,7 @@ class Bible(commands.Cog): __author__ = ["[cswimr](https://www.coastalcommits.com/cswimr)"] __git__ = "https://www.coastalcommits.com/cswimr/SeaCogs" - __version__ = "1.1.2" + __version__ = "1.1.3" __documentation__ = "https://seacogs.coastalcommits.com/pterodactyl/" def __init__(self, bot: Red): @@ -97,14 +97,14 @@ class Bible(commands.Cog): if response.status == 503: raise bible.errors.ServiceUnavailableError() return Version( - bible_id, - data["data"]["abbreviation"], - data["data"]["language"]["name"], - data["data"]["abbreviationLocal"], - data["data"]["language"]["nameLocal"], - data["data"]["description"], - data["data"]["descriptionLocal"], - data["data"]["copyright"], + bible_id=bible_id, + abbreviation=data["data"]["abbreviation"], + language=data["data"]["language"]["name"], + abbreviation_local=data["data"]["abbreviationLocal"], + language_local=data["data"]["language"]["nameLocal"], + description=data["data"]["description"], + description_local=data["data"]["descriptionLocal"], + version_copyright=data["data"]["copyright"], ) async def _get_passage( @@ -270,7 +270,7 @@ class Bible(commands.Cog): description=passage["content"].replace("¶ ", ""), color=await ctx.embed_color(), ) - embed.set_footer(text=f"{ctx.prefix}bible passage - Powered by API.Bible - {version.abbreviationLocal} ({version.languageLocal}, {version.descriptionLocal})", icon_url="attachment://icon.png") + embed.set_footer(text=f"{ctx.prefix}bible passage - Powered by API.Bible - {version.abbreviation_local} ({version.language_local}, {version.description_local})", icon_url="attachment://icon.png") await ctx.send(embed=embed, file=icon) else: await ctx.send(f"## {passage['reference']}\n{passage['content']}") @@ -309,7 +309,7 @@ class Bible(commands.Cog): description=passage["content"].replace("¶ ", ""), color=await ctx.embed_color(), ) - embed.set_footer(text=f"{ctx.prefix}bible random - Powered by API.Bible - {version.abbreviationLocal} ({version.languageLocal}, {version.descriptionLocal})", icon_url="attachment://icon.png") + embed.set_footer(text=f"{ctx.prefix}bible random - Powered by API.Bible - {version.abbreviation_local} ({version.language_local}, {version.description_local})", icon_url="attachment://icon.png") await ctx.send(embed=embed, file=icon) else: await ctx.send(f"## {passage['reference']}\n{passage['content']}") diff --git a/bible/models.py b/bible/models.py index 97500be..b8e3b09 100644 --- a/bible/models.py +++ b/bible/models.py @@ -4,23 +4,23 @@ class Version: bible_id, abbreviation, language, - abbreviationLocal, - languageLocal, + abbreviation_local, + language_local, description, - descriptionLocal, + description_local, version_copyright, ): self.bible_id = bible_id self.abbreviation = abbreviation self.language = language - self.abbreviationLocal = abbreviationLocal - self.languageLocal = languageLocal + self.abbreviation_local = abbreviation_local + self.language_local = language_local self.description = description - self.descriptionLocal = descriptionLocal + self.description_local = description_local self.copyright = version_copyright def __str__(self): - return self.abbreviationLocal + return self.abbreviation_local def __repr__(self): - return f'bible.models.Version("{self.bible_id}", "{self.abbreviation}", "{self.language}", "{self.abbreviationLocal}", "{self.languageLocal}", "{self.description}", "{self.descriptionLocal}", "{self.copyright}")' + return f'bible.models.Version("{self.bible_id}", "{self.abbreviation}", "{self.language}", "{self.abbreviation_local}", "{self.language_local}", "{self.description}", "{self.description_local}", "{self.copyright}")' From 0f47a15291ff009bff7183653d0aa8e854e90285 Mon Sep 17 00:00:00 2001 From: cswimr Date: Sun, 26 Jan 2025 13:18:04 +0000 Subject: [PATCH 12/53] fix(emojiinfo): ruff fixes & rename logger --- emojiinfo/emojiinfo.py | 35 ++++++++++++++--------------------- 1 file changed, 14 insertions(+), 21 deletions(-) diff --git a/emojiinfo/emojiinfo.py b/emojiinfo/emojiinfo.py index 3dd8188..f1f947a 100644 --- a/emojiinfo/emojiinfo.py +++ b/emojiinfo/emojiinfo.py @@ -16,13 +16,13 @@ class EmojiInfo(commands.Cog): __author__ = ["[cswimr](https://www.coastalcommits.com/cswimr)"] __git__ = "https://www.coastalcommits.com/cswimr/SeaCogs" - __version__ = "1.0.1" + __version__ = "1.0.2" __documentation__ = "https://seacogs.coastalcommits.com/emojiinfo/" def __init__(self, bot: Red) -> None: super().__init__() self.bot: Red = bot - self.logger: RedTraceLogger = getLogger(name="red.SeaCogs.Emoji") + self.logger: RedTraceLogger = getLogger(name="red.SeaCogs.EmojiInfo") def format_help_for_context(self, ctx: commands.Context) -> str: pre_processed = super().format_help_for_context(ctx) or "" @@ -35,7 +35,6 @@ class EmojiInfo(commands.Cog): ] return "\n".join(text) - async def fetch_twemoji(self, unicode_emoji) -> str: base_url = "https://cdn.jsdelivr.net/gh/jdecked/twemoji@latest/assets/72x72/" emoji_codepoint = "-".join([hex(ord(char))[2:] for char in unicode_emoji]) @@ -76,35 +75,26 @@ class EmojiInfo(commands.Cog): aliases = f"{bold('Aliases:')} {', '.join(emoji.aliases)}\n" if emoji.aliases else "" group = f"{bold('Group:')} {emoji.group}\n" - return ( - f"{name}" - f"{emoji_id}" - f"{bold('Native:')} {emoji.is_unicode_emoji()}\n" - f"{group}" - f"{aliases}" - f"{bold('Animated:')} {emoji.animated}\n" - f"{bold('Markdown:')} {markdown}\n" - f"{bold('URL:')} [Click Here]({emoji_url})" - ), emoji_url + return (f"{name}{emoji_id}{bold('Native:')} {emoji.is_unicode_emoji()}\n{group}{aliases}{bold('Animated:')} {emoji.animated}\n{bold('Markdown:')} {markdown}\n{bold('URL:')} [Click Here]({emoji_url})"), emoji_url @app_commands.command(name="emoji") - @app_commands.describe( - emoji="What emoji would you like to get information on?", - ephemeral="Would you like the response to be hidden?" - ) + @app_commands.describe(emoji="What emoji would you like to get information on?", ephemeral="Would you like the response to be hidden?") async def emoji_slash(self, interaction: discord.Interaction, emoji: str, ephemeral: bool = True) -> None: """Retrieve information about an emoji.""" await interaction.response.defer(ephemeral=ephemeral) try: emoji: PartialEmoji = PartialEmoji.from_str(self, value=emoji) - string, emoji_url, = await self.get_emoji_info(emoji) + ( + string, + emoji_url, + ) = await self.get_emoji_info(emoji) self.logger.verbose(f"Emoji:\n{string}") except (IndexError, UnboundLocalError): return await interaction.followup.send("Please provide a valid emoji!") if await self.bot.embed_requested(channel=interaction.channel): - embed = embed = discord.Embed(title="Emoji Information", description=string, color = await self.fetch_primary_color(emoji_url) or await self.bot.get_embed_color(interaction.channel)) + embed = discord.Embed(title="Emoji Information", description=string, color=await self.fetch_primary_color(emoji_url) or await self.bot.get_embed_color(interaction.channel)) embed.set_thumbnail(url=emoji_url) await interaction.followup.send(embed=embed) @@ -116,13 +106,16 @@ class EmojiInfo(commands.Cog): """Retrieve information about an emoji.""" try: emoji: PartialEmoji = PartialEmoji.from_str(self, value=emoji) - string, emoji_url, = await self.get_emoji_info(emoji) + ( + string, + emoji_url, + ) = await self.get_emoji_info(emoji) self.logger.verbose(f"Emoji:\n{string}") except (IndexError, UnboundLocalError): return await ctx.send("Please provide a valid emoji!") if await ctx.embed_requested(): - embed = embed = discord.Embed(title="Emoji Information", description=string, color = await self.fetch_primary_color(emoji_url) or await ctx.embed_color) + embed = discord.Embed(title="Emoji Information", description=string, color=await self.fetch_primary_color(emoji_url) or await ctx.embed_color) embed.set_thumbnail(url=emoji_url) await ctx.send(embed=embed) From 0c43e3d2c95316c68be4beb37b0799db3e3789ec Mon Sep 17 00:00:00 2001 From: cswimr Date: Sun, 26 Jan 2025 13:21:28 +0000 Subject: [PATCH 13/53] fix(backup): update for red 3.5.14 & reformat --- backup/backup.py | 108 ++++++++++++----------------------------------- backup/info.json | 22 ++++++---- 2 files changed, 41 insertions(+), 89 deletions(-) diff --git a/backup/backup.py b/backup/backup.py index dfc5397..4ba184f 100644 --- a/backup/backup.py +++ b/backup/backup.py @@ -23,7 +23,7 @@ class Backup(commands.Cog): __author__ = ["[cswimr](https://www.coastalcommits.com/cswimr)"] __git__ = "https://www.coastalcommits.com/cswimr/SeaCogs" - __version__ = "1.1.1" + __version__ = "1.1.2" __documentation__ = "https://seacogs.coastalcommits.com/backup/" def __init__(self, bot: Red): @@ -53,11 +53,7 @@ class Backup(commands.Cog): """Export your installed repositories and cogs to a file.""" downloader = ctx.bot.get_cog("Downloader") if downloader is None: - await ctx.send( - error( - f"You do not have the `Downloader` cog loaded. Please run `{ctx.prefix}load downloader` and try again." - ) - ) + await ctx.send(error(f"You do not have the `Downloader` cog loaded. Please run `{ctx.prefix}load downloader` and try again.")) return all_repos = list(downloader._repo_manager.repos) @@ -88,9 +84,7 @@ class Backup(commands.Cog): export_data.append(repo_dict) - await ctx.send( - file=text_to_file(json.dumps(export_data, indent=4), "backup.json") - ) + await ctx.send(file=text_to_file(json.dumps(export_data, indent=4), "backup.json")) @backup.command(name="import") @commands.is_owner() @@ -107,11 +101,7 @@ class Backup(commands.Cog): downloader = ctx.bot.get_cog("Downloader") if downloader is None: - await ctx.send( - error( - f"You do not have the `Downloader` cog loaded. Please run `{ctx.prefix}load downloader` and try again." - ) - ) + await ctx.send(error(f"You do not have the `Downloader` cog loaded. Please run `{ctx.prefix}load downloader` and try again.")) return repo_s = [] @@ -133,32 +123,20 @@ class Backup(commands.Cog): repo_e.append("PyLav cogs are not supported.") continue if name.startswith(".") or name.endswith("."): - repo_e.append( - f"Invalid repository name: {name}\nRepository names cannot start or end with a dot." - ) + repo_e.append(f"Invalid repository name: {name}\nRepository names cannot start or end with a dot.") continue if re.match(r"^[a-zA-Z0-9_\-\.]+$", name) is None: - repo_e.append( - f"Invalid repository name: {name}\nRepository names may only contain letters, numbers, underscores, hyphens, and dots." - ) + repo_e.append(f"Invalid repository name: {name}\nRepository names may only contain letters, numbers, underscores, hyphens, and dots.") continue try: - repository = await downloader._repo_manager.add_repo( - url, name, branch - ) - repo_s.append( - f"Added repository {name} from {url} on branch {branch}." - ) - self.logger.debug( - "Added repository %s from %s on branch %s", name, url, branch - ) + repository = await downloader._repo_manager.add_repo(url, name, branch) + repo_s.append(f"Added repository {name} from {url} on branch {branch}.") + self.logger.debug("Added repository %s from %s on branch %s", name, url, branch) except errors.ExistingGitRepo: repo_e.append(f"Repository {name} already exists.") - repository = downloader._repo_manager.get_repo( - name - ) + repository = downloader._repo_manager.get_repo(name) self.logger.debug("Repository %s already exists", name) except errors.AuthenticationError as err: @@ -172,9 +150,7 @@ class Backup(commands.Cog): continue except errors.CloningError as err: - repo_e.append( - f"Cloning error while adding repository {name}. See logs for more information." - ) + repo_e.append(f"Cloning error while adding repository {name}. See logs for more information.") self.logger.exception( "Something went wrong whilst cloning %s (to revision %s)", url, @@ -184,9 +160,7 @@ class Backup(commands.Cog): continue except OSError: - repo_e.append( - f"OS error while adding repository {name}. See logs for more information." - ) + repo_e.append(f"OS error while adding repository {name}. See logs for more information.") self.logger.exception( "Something went wrong trying to add repo %s under name %s", url, @@ -212,17 +186,13 @@ class Backup(commands.Cog): with contextlib.suppress(commands.ExtensionNotLoaded): await ctx.bot.unload_extension(cog) await ctx.bot.remove_loaded_package(cog) - await downloader._delete_cog( - poss_installed_path - ) + await downloader._delete_cog(poss_installed_path) uninstall_s.append(f"Uninstalled {cog}") self.logger.debug("Uninstalled %s", cog) else: uninstall_e.append(f"Failed to uninstall {cog}") self.logger.warning("Failed to uninstall %s", cog) - await downloader._remove_from_installed( - cog_modules - ) + await downloader._remove_from_installed(cog_modules) for cog in cogs: cog_name = cog["name"] @@ -236,25 +206,15 @@ class Backup(commands.Cog): if cog_name == "backup" and "cswimr/SeaCogs" in url: continue - async with repository.checkout( - commit, exit_to_rev=repository.branch - ): - cogs_c, message = ( - await downloader._filter_incorrect_cogs_by_names( - repository, [cog_name] - ) - ) + async with repository.checkout(commit, exit_to_rev=repository.branch): + cogs_c, message = await downloader._filter_incorrect_cogs_by_names(repository, [cog_name]) if not cogs_c: install_e.append(message) self.logger.error(message) continue - failed_reqs = await downloader._install_requirements( - cogs_c - ) + failed_reqs = await downloader._install_requirements(cogs_c) if failed_reqs: - install_e.append( - f"Failed to install {cog_name} due to missing requirements: {failed_reqs}" - ) + install_e.append(f"Failed to install {cog_name} due to missing requirements: {failed_reqs}") self.logger.error( "Failed to install %s due to missing requirements: %s", cog_name, @@ -262,51 +222,37 @@ class Backup(commands.Cog): ) continue - installed_cogs, failed_cogs = await downloader._install_cogs( - cogs_c - ) + installed_cogs, failed_cogs = await downloader._install_cogs(cogs_c) if repository.available_libraries: - installed_libs, failed_libs = ( - await repository.install_libraries( - target_dir=downloader.SHAREDLIB_PATH, - req_target_dir=downloader.LIB_PATH, - ) + installed_libs, failed_libs = await repository.install_libraries( + target_dir=downloader.SHAREDLIB_PATH, + req_target_dir=downloader.LIB_PATH, ) else: installed_libs = None failed_libs = None if cog_pinned: - for cog in installed_cogs: + for cog in installed_cogs: # noqa: PLW2901 cog.pinned = True - await downloader._save_to_installed( - installed_cogs + installed_libs - if installed_libs - else installed_cogs - ) + await downloader._save_to_installed(installed_cogs + installed_libs if installed_libs else installed_cogs) if installed_cogs: installed_cog_name = installed_cogs[0].name install_s.append(f"Installed {installed_cog_name}") self.logger.debug("Installed %s", installed_cog_name) if installed_libs: for lib in installed_libs: - install_s.append( - f"Installed {lib.name} required for {cog_name}" - ) - self.logger.debug( - "Installed %s required for %s", lib.name, cog_name - ) + install_s.append(f"Installed {lib.name} required for {cog_name}") + self.logger.debug("Installed %s required for %s", lib.name, cog_name) if failed_cogs: failed_cog_name = failed_cogs[0].name install_e.append(f"Failed to install {failed_cog_name}") self.logger.error("Failed to install %s", failed_cog_name) if failed_libs: for lib in failed_libs: - install_e.append( - f"Failed to install {lib.name} required for {cog_name}" - ) + install_e.append(f"Failed to install {lib.name} required for {cog_name}") self.logger.error( "Failed to install %s required for %s", lib.name, diff --git a/backup/info.json b/backup/info.json index 2e465b0..288ece1 100644 --- a/backup/info.json +++ b/backup/info.json @@ -1,15 +1,21 @@ { - "author" : ["cswimr"], - "install_msg" : "Thank you for installing Backup!\nYou can find the source code of this cog [here](https://coastalcommits.com/cswimr/SeaCogs).", - "name" : "Backup", - "short" : "A utility to make reinstalling repositories and cogs after migrating the bot far easier.", - "description" : "A utility to make reinstalling repositories and cogs after migrating the bot far easier.", - "end_user_data_statement" : "This cog does not store end user data.", + "author": [ + "cswimr" + ], + "install_msg": "Thank you for installing Backup!\nYou can find the source code of this cog [here](https://coastalcommits.com/cswimr/SeaCogs).", + "name": "Backup", + "short": "A utility to make reinstalling repositories and cogs after migrating the bot far easier.", + "description": "A utility to make reinstalling repositories and cogs after migrating the bot far easier.", + "end_user_data_statement": "This cog does not store end user data.", "hidden": false, "disabled": false, "min_bot_version": "3.5.6", - "max_bot_version": "3.5.13", - "min_python_version": [3, 9, 0], + "max_bot_version": "3.5.14", + "min_python_version": [ + 3, + 9, + 0 + ], "tags": [ "utility", "backup", From dbff8d0d2a20877160df13d2bb6e6c95abed7a66 Mon Sep 17 00:00:00 2001 From: cswimr Date: Sun, 26 Jan 2025 13:42:48 +0000 Subject: [PATCH 14/53] chore(repo): enable some more ruff rules --- pyproject.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index 7c337dc..dae9ead 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -94,6 +94,9 @@ select = [ "PLW", "PLR", "LOG", + "SLF", + "ERA", + "FIX", ] ignore = ["PLR0912", "PLR0915", "PLR2004", "PLR0913"] From 6f0fee827524dd65726a1575e52877cb80086801 Mon Sep 17 00:00:00 2001 From: cswimr Date: Sun, 26 Jan 2025 13:42:57 +0000 Subject: [PATCH 15/53] fix(backup): disable SLF001 --- backup/backup.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/backup/backup.py b/backup/backup.py index 4ba184f..2aafb8c 100644 --- a/backup/backup.py +++ b/backup/backup.py @@ -17,6 +17,9 @@ from redbot.core.bot import Red from redbot.core.utils.chat_formatting import bold, error, humanize_list, text_to_file +# Disable Ruff & Pylint complaining about accessing private members +# That's kind of necessary for this cog to function because the Downloader cog has a limited public API +# ruff: noqa: SLF001 # Private member access # pylint: disable=protected-access class Backup(commands.Cog): """A utility to make reinstalling repositories and cogs after migrating the bot far easier.""" @@ -74,7 +77,7 @@ class Backup(commands.Cog): if cog.repo_name == repo.name: cog_dict = { "name": cog.name, - # "loaded": cog.name in ctx.bot.extensions.keys(), + # "loaded": cog.name in ctx.bot.extensions.keys(), # noqa: ERA001 # this functionality was planned but never implemented due to Red limitations # and the possibility of restoration functionality being added to Core "pinned": cog.pinned, From 0b60a2df66bfd34790bb31b63e99ac44ab87daf7 Mon Sep 17 00:00:00 2001 From: cswimr Date: Sun, 26 Jan 2025 14:03:28 +0000 Subject: [PATCH 16/53] chore(repo): enable more ruff rules --- pyproject.toml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index dae9ead..fbe8028 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -97,6 +97,8 @@ select = [ "SLF", "ERA", "FIX", + "PERF", + "C4", ] ignore = ["PLR0912", "PLR0915", "PLR2004", "PLR0913"] From 2543563af1f50f9bf8f6ea2b618e2e07cd247624 Mon Sep 17 00:00:00 2001 From: cswimr Date: Sun, 26 Jan 2025 14:10:33 +0000 Subject: [PATCH 17/53] fix(hotreload): ruff fix --- hotreload/hotreload.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hotreload/hotreload.py b/hotreload/hotreload.py index 8a48501..254ae7f 100644 --- a/hotreload/hotreload.py +++ b/hotreload/hotreload.py @@ -52,7 +52,7 @@ class HotReload(commands.Cog): async def get_paths(self) -> tuple[Path]: """Retrieve user defined paths.""" - cog_manager = self.bot._cog_mgr + cog_manager = self.bot._cog_mgr # noqa: SLF001 # We have to use this private method because there is no public API to get user defined paths cog_paths = await cog_manager.user_defined_paths() return (Path(path) for path in cog_paths) From 4ad73ec6ee8f4cadb1836305b9d70f9a86eac546 Mon Sep 17 00:00:00 2001 From: cswimr Date: Sun, 26 Jan 2025 14:10:43 +0000 Subject: [PATCH 18/53] fix(pterodactyl): ruff fix --- pterodactyl/pterodactyl.py | 169 +++++++++++++++++++------------------ 1 file changed, 86 insertions(+), 83 deletions(-) diff --git a/pterodactyl/pterodactyl.py b/pterodactyl/pterodactyl.py index fc49e3f..a0be73e 100644 --- a/pterodactyl/pterodactyl.py +++ b/pterodactyl/pterodactyl.py @@ -67,20 +67,21 @@ class Pterodactyl(commands.Cog): self.update_topic.cancel() self.task.cancel() self.retry_counter = 0 - await self.client._session.close() # pylint: disable=protected-access + await self.client._session.close() # pylint: disable=protected-access # noqa: SLF001 def get_task(self) -> asyncio.Task: from pterodactyl.websocket import establish_websocket_connection + task = self.bot.loop.create_task(establish_websocket_connection(self), name="Pterodactyl Websocket Connection") task.add_done_callback(self.error_callback) return task - def error_callback(self, fut) -> None: #NOTE - Thanks flame442 and zephyrkul for helping me figure this out + def error_callback(self, fut) -> None: # NOTE - Thanks flame442 and zephyrkul for helping me figure this out try: fut.result() except asyncio.CancelledError: logger.info("WebSocket task has been cancelled.") - except Exception as e: # pylint: disable=broad-exception-caught + except Exception as e: # pylint: disable=broad-exception-caught logger.error("WebSocket task has failed: %s", e, exc_info=e) self.task.cancel() if self.retry_counter < 5: @@ -141,23 +142,27 @@ class Pterodactyl(commands.Cog): if await config.api_endpoint() == "minecraft": status, response = await mcsrvstatus.get_status(await config.topic_hostname(), await config.topic_port()) if status: - placeholders.update({ - "I": response['ip'], - "M": str(response['players']['max']), - "P": str(response['players']['online']), - "V": response['version'], - "D": response['motd']['clean'][0] if response['motd']['clean'] else "unset", - }) + placeholders.update( + { + "I": response["ip"], + "M": str(response["players"]["max"]), + "P": str(response["players"]["online"]), + "V": response["version"], + "D": response["motd"]["clean"][0] if response["motd"]["clean"] else "unset", + } + ) else: - placeholders.update({ - "I": response['ip'], - "M": "0", - "P": "0", - "V": "Server Offline", - "D": "Server Offline", - }) + placeholders.update( + { + "I": response["ip"], + "M": "0", + "P": "0", + "V": "Server Offline", + "D": "Server Offline", + } + ) for key, value in placeholders.items(): - topic = topic.replace('.$' + key, value) + topic = topic.replace(".$" + key, value) return topic async def get_chat_command(self, message: discord.Message) -> str: @@ -166,21 +171,21 @@ class Pterodactyl(commands.Cog): "C": str(message.author.color), "D": message.author.discriminator, "I": str(message.author.id), - "M": message.content.replace('"','').replace("\n", " "), + "M": message.content.replace('"', "").replace("\n", " "), "N": message.author.display_name, "U": message.author.name, "V": await config.invite() or "use [p]pterodactyl config invite to change me", } for key, value in placeholders.items(): - command = command.replace('.$' + key, value) + command = command.replace(".$" + key, value) return command async def get_player_list(self) -> Optional[Tuple[str, list]]: if await config.api_endpoint() == "minecraft": status, response = await mcsrvstatus.get_status(await config.topic_hostname(), await config.topic_port()) - if status and 'list' in response['players']: - output_str = '\n'.join(response['players']['list']) - return output_str, response['players']['list'] + if status and "list" in response["players"]: + output_str = "\n".join(response["players"]["list"]) + return output_str, response["players"]["list"] return None async def get_player_list_embed(self, ctx: Union[commands.Context, discord.Interaction]) -> Optional[discord.Embed]: @@ -191,7 +196,7 @@ class Pterodactyl(commands.Cog): return embed return None - async def power(self, ctx: Union[discord.Interaction, commands.Context], action: str, action_ing: str, warning: str = '') -> None: + async def power(self, ctx: Union[discord.Interaction, commands.Context], action: str, action_ing: str, warning: str = "") -> None: if isinstance(ctx, discord.Interaction): ctx = await self.bot.get_context(ctx) @@ -236,7 +241,7 @@ class Pterodactyl(commands.Cog): self.task = self.get_task() @commands.Cog.listener() - async def on_red_api_tokens_update(self, service_name: str, api_tokens: Mapping[str,str]): # pylint: disable=unused-argument + async def on_red_api_tokens_update(self, service_name: str, api_tokens: Mapping[str, str]): # pylint: disable=unused-argument if service_name == "pterodactyl": logger.info("Configuration value set: api_key\nRestarting task...") self.task.cancel() @@ -245,7 +250,7 @@ class Pterodactyl(commands.Cog): slash_pterodactyl = app_commands.Group(name="pterodactyl", description="Pterodactyl allows you to manage your Pterodactyl Panel from Discord.") - @slash_pterodactyl.command(name = "command", description = "Send a command to the server console.") + @slash_pterodactyl.command(name="command", description="Send a command to the server console.") async def slash_pterodactyl_command(self, interaction: discord.Interaction, command: str) -> None: """Send a command to the server console. @@ -255,7 +260,7 @@ class Pterodactyl(commands.Cog): The command to send to the server.""" return await self.send_command(interaction, command) - @slash_pterodactyl.command(name = "players", description = "Retrieve a list of players on the server.") + @slash_pterodactyl.command(name="players", description="Retrieve a list of players on the server.") async def slash_pterodactyl_players(self, interaction: discord.Interaction) -> None: """Retrieve a list of players on the server.""" e = await self.get_player_list_embed(interaction) @@ -264,13 +269,8 @@ class Pterodactyl(commands.Cog): else: await interaction.response.send_message("No players online.", ephemeral=True) - @slash_pterodactyl.command(name = "power", description = "Send power actions to the server.") - @app_commands.choices(action=[ - Choice(name="Start", value="start"), - Choice(name="Stop", value="stop"), - Choice(name="Restart", value="restart"), - Choice(name="⚠️ Kill ⚠️", value="kill") - ]) + @slash_pterodactyl.command(name="power", description="Send power actions to the server.") + @app_commands.choices(action=[Choice(name="Start", value="start"), Choice(name="Stop", value="stop"), Choice(name="Restart", value="restart"), Choice(name="⚠️ Kill ⚠️", value="kill")]) async def slash_pterodactyl_power(self, interaction: discord.Interaction, action: app_commands.Choice[str]) -> None: """Send power actions to the server. @@ -284,11 +284,11 @@ class Pterodactyl(commands.Cog): return await self.power(interaction, action.value, "stopping...") return await self.power(interaction, action.value, f"{action.value}ing...") - @commands.group(autohelp = True, name = "pterodactyl", aliases = ["ptero"]) + @commands.group(autohelp=True, name="pterodactyl", aliases=["ptero"]) async def pterodactyl(self, ctx: commands.Context) -> None: """Pterodactyl allows you to manage your Pterodactyl Panel from Discord.""" - @pterodactyl.command(name = "players", aliases=["list", "online", "playerlist", "who"]) + @pterodactyl.command(name="players", aliases=["list", "online", "playerlist", "who"]) async def pterodactyl_players(self, ctx: commands.Context) -> None: """Retrieve a list of players on the server.""" e = await self.get_player_list_embed(ctx) @@ -297,43 +297,43 @@ class Pterodactyl(commands.Cog): else: await ctx.send("No players online.") - @pterodactyl.command(name = "command", aliases = ["cmd", "execute", "exec"]) + @pterodactyl.command(name="command", aliases=["cmd", "execute", "exec"]) @commands.admin() async def pterodactyl_command(self, ctx: commands.Context, *, command: str) -> None: """Send a command to the server console.""" return await self.send_command(ctx, command) - @pterodactyl.group(autohelp = True, name = "power") + @pterodactyl.group(autohelp=True, name="power") @commands.admin() async def pterodactyl_power(self, ctx: commands.Context) -> None: """Send power actions to the server.""" - @pterodactyl_power.command(name = "start") + @pterodactyl_power.command(name="start") async def pterodactyl_power_start(self, ctx: commands.Context) -> Optional[discord.Message]: """Start the server.""" return await self.power(ctx, "start", "starting...") - @pterodactyl_power.command(name = "stop") + @pterodactyl_power.command(name="stop") async def pterodactyl_power_stop(self, ctx: commands.Context) -> Optional[discord.Message]: """Stop the server.""" return await self.power(ctx, "stop", "stopping...") - @pterodactyl_power.command(name = "restart") + @pterodactyl_power.command(name="restart") async def pterodactyl_power_restart(self, ctx: commands.Context) -> Optional[discord.Message]: """Restart the server.""" return await self.power(ctx, "restart", "restarting...") - @pterodactyl_power.command(name = "kill") + @pterodactyl_power.command(name="kill") async def pterodactyl_power_kill(self, ctx: commands.Context) -> Optional[discord.Message]: """Kill the server.""" return await self.power(ctx, "kill", "stopping... (forcefully killed)", warning="**⚠️ Forcefully killing the server process can corrupt data in some cases. ⚠️**\n") - @pterodactyl.group(autohelp = True, name = "config", aliases = ["settings", "set"]) + @pterodactyl.group(autohelp=True, name="config", aliases=["settings", "set"]) @commands.is_owner() async def pterodactyl_config(self, ctx: commands.Context) -> None: """Configure Pterodactyl settings.""" - @pterodactyl_config.command(name = "url") + @pterodactyl_config.command(name="url") async def pterodactyl_config_base_url(self, ctx: commands.Context, *, base_url: str) -> None: """Set the base URL of your Pterodactyl Panel. @@ -346,7 +346,7 @@ class Pterodactyl(commands.Cog): self.retry_counter = 0 self.task = self.get_task() - @pterodactyl_config.command(name = "serverid") + @pterodactyl_config.command(name="serverid") async def pterodactyl_config_server_id(self, ctx: commands.Context, *, server_id: str) -> None: """Set the ID of your server.""" await config.server_id.set(server_id) @@ -356,45 +356,45 @@ class Pterodactyl(commands.Cog): self.retry_counter = 0 self.task = self.get_task() - @pterodactyl_config.group(name = "console") + @pterodactyl_config.group(name="console") async def pterodactyl_config_console(self, ctx: commands.Context): """Configure console settings.""" - @pterodactyl_config_console.command(name = "channel") + @pterodactyl_config_console.command(name="channel") async def pterodactyl_config_console_channel(self, ctx: commands.Context, channel: discord.TextChannel) -> None: """Set the channel to send console output to.""" await config.console_channel.set(channel.id) await ctx.send(f"Console channel set to {channel.mention}") - @pterodactyl_config_console.command(name = "commands") + @pterodactyl_config_console.command(name="commands") async def pterodactyl_config_console_commands(self, ctx: commands.Context, enabled: bool) -> None: """Enable or disable console commands.""" await config.console_commands_enabled.set(enabled) await ctx.send(f"Console commands set to {enabled}") - @pterodactyl_config.command(name = "invite") + @pterodactyl_config.command(name="invite") async def pterodactyl_config_invite(self, ctx: commands.Context, invite: str) -> None: """Set the invite link for your server.""" await config.invite.set(invite) await ctx.send(f"Invite link set to {invite}") - @pterodactyl_config.group(name = "topic") + @pterodactyl_config.group(name="topic") async def pterodactyl_config_topic(self, ctx: commands.Context): """Set the topic for the console and chat channels.""" - @pterodactyl_config_topic.command(name = "host", aliases = ["hostname", "ip"]) + @pterodactyl_config_topic.command(name="host", aliases=["hostname", "ip"]) async def pterodactyl_config_topic_host(self, ctx: commands.Context, host: str) -> None: """Set the hostname or IP address of your server.""" await config.topic_hostname.set(host) await ctx.send(f"Hostname/IP set to `{host}`") - @pterodactyl_config_topic.command(name = "port") + @pterodactyl_config_topic.command(name="port") async def pterodactyl_config_topic_port(self, ctx: commands.Context, port: int) -> None: """Set the port of your server.""" await config.topic_port.set(port) await ctx.send(f"Port set to `{port}`") - @pterodactyl_config_topic.command(name = "text") + @pterodactyl_config_topic.command(name="text") async def pterodactyl_config_topic_text(self, ctx: commands.Context, *, text: str) -> None: """Set the text for the console and chat channels. @@ -410,17 +410,17 @@ class Pterodactyl(commands.Cog): await config.topic.set(text) await ctx.send(f"Topic set to:\n{box(text, 'yaml')}") - @pterodactyl_config.group(name = "chat") + @pterodactyl_config.group(name="chat") async def pterodactyl_config_chat(self, ctx: commands.Context): """Configure chat settings.""" - @pterodactyl_config_chat.command(name = "channel") + @pterodactyl_config_chat.command(name="channel") async def pterodactyl_config_chat_channel(self, ctx: commands.Context, channel: discord.TextChannel) -> None: """Set the channel to send chat output to.""" await config.chat_channel.set(channel.id) await ctx.send(f"Chat channel set to {channel.mention}") - @pterodactyl_config_chat.command(name = "command") + @pterodactyl_config_chat.command(name="command") async def pterodactyl_config_chat_command(self, ctx: commands.Context, *, command: str) -> None: """Set the command that will be used to send messages from Discord. @@ -429,11 +429,11 @@ class Pterodactyl(commands.Cog): await config.chat_command.set(command) await ctx.send(f"Chat command set to:\n{box(command, 'json')}") - @pterodactyl_config.group(name = "regex") + @pterodactyl_config.group(name="regex") async def pterodactyl_config_regex(self, ctx: commands.Context) -> None: """Set regex patterns.""" - @pterodactyl_config_regex.command(name = "chat") + @pterodactyl_config_regex.command(name="chat") async def pterodactyl_config_regex_chat(self, ctx: commands.Context, *, regex: str) -> None: """Set the regex pattern to match chat messages on the server. @@ -441,7 +441,7 @@ class Pterodactyl(commands.Cog): await config.chat_regex.set(regex) await ctx.send(f"Chat regex set to:\n{box(regex, 'regex')}") - @pterodactyl_config_regex.command(name = "server") + @pterodactyl_config_regex.command(name="server") async def pterodactyl_config_regex_server(self, ctx: commands.Context, *, regex: str) -> None: """Set the regex pattern to match server messages on the server. @@ -449,7 +449,7 @@ class Pterodactyl(commands.Cog): await config.server_regex.set(regex) await ctx.send(f"Server regex set to:\n{box(regex, 'regex')}") - @pterodactyl_config_regex.command(name = "join") + @pterodactyl_config_regex.command(name="join") async def pterodactyl_config_regex_join(self, ctx: commands.Context, *, regex: str) -> None: """Set the regex pattern to match join messages on the server. @@ -457,7 +457,7 @@ class Pterodactyl(commands.Cog): await config.join_regex.set(regex) await ctx.send(f"Join regex set to:\n{box(regex, 'regex')}") - @pterodactyl_config_regex.command(name = "leave") + @pterodactyl_config_regex.command(name="leave") async def pterodactyl_config_regex_leave(self, ctx: commands.Context, *, regex: str) -> None: """Set the regex pattern to match leave messages on the server. @@ -465,7 +465,7 @@ class Pterodactyl(commands.Cog): await config.leave_regex.set(regex) await ctx.send(f"Leave regex set to:\n{box(regex, 'regex')}") - @pterodactyl_config_regex.command(name = "achievement") + @pterodactyl_config_regex.command(name="achievement") async def pterodactyl_config_regex_achievement(self, ctx: commands.Context, *, regex: str) -> None: """Set the regex pattern to match achievement messages on the server. @@ -473,41 +473,41 @@ class Pterodactyl(commands.Cog): await config.achievement_regex.set(regex) await ctx.send(f"Achievement regex set to:\n{box(regex, 'regex')}") - @pterodactyl_config.group(name = "messages", aliases = ['msg', 'msgs', 'message']) + @pterodactyl_config.group(name="messages", aliases=["msg", "msgs", "message"]) async def pterodactyl_config_messages(self, ctx: commands.Context): """Configure message settings.""" - @pterodactyl_config_messages.command(name = "startup") + @pterodactyl_config_messages.command(name="startup") async def pterodactyl_config_messages_startup(self, ctx: commands.Context, *, message: str) -> None: """Set the message that will be sent when the server starts.""" await config.startup_msg.set(message) await ctx.send(f"Startup message set to: {message}") - @pterodactyl_config_messages.command(name = "shutdown") + @pterodactyl_config_messages.command(name="shutdown") async def pterodactyl_config_messages_shutdown(self, ctx: commands.Context, *, message: str) -> None: """Set the message that will be sent when the server stops.""" await config.shutdown_msg.set(message) await ctx.send(f"Shutdown message set to: {message}") - @pterodactyl_config_messages.command(name = "join") + @pterodactyl_config_messages.command(name="join") async def pterodactyl_config_messages_join(self, ctx: commands.Context, *, message: str) -> None: """Set the message that will be sent when a user joins the server. This is only shown in embeds.""" await config.join_msg.set(message) await ctx.send(f"Join message set to: {message}") - @pterodactyl_config_messages.command(name = "leave") + @pterodactyl_config_messages.command(name="leave") async def pterodactyl_config_messages_leave(self, ctx: commands.Context, *, message: str) -> None: """Set the message that will be sent when a user leaves the server. This is only shown in embeds.""" await config.leave_msg.set(message) await ctx.send(f"Leave message set to: {message}") - @pterodactyl_config.command(name = "ip") + @pterodactyl_config.command(name="ip") async def pterodactyl_config_mask_ip(self, ctx: commands.Context, mask: bool) -> None: """Mask the IP addresses of users in console messages.""" await config.mask_ip.set(mask) await ctx.send(f"IP masking set to {mask}") - @pterodactyl_config.command(name = "api") + @pterodactyl_config.command(name="api") async def pterodactyl_config_api(self, ctx: commands.Context, endpoint: str) -> None: """Set the API endpoint for retrieving user avatars. @@ -516,11 +516,14 @@ class Pterodactyl(commands.Cog): await config.api_endpoint.set(endpoint) await ctx.send(f"API endpoint set to {endpoint}") - @pterodactyl_config_regex.group(name = "blacklist", aliases = ['block', 'blocklist'],) + @pterodactyl_config_regex.group( + name="blacklist", + aliases=["block", "blocklist"], + ) async def pterodactyl_config_regex_blacklist(self, ctx: commands.Context): """Blacklist regex patterns.""" - @pterodactyl_config_regex_blacklist.command(name = "add") + @pterodactyl_config_regex_blacklist.command(name="add") async def pterodactyl_config_regex_blacklist_add(self, ctx: commands.Context, name: str, *, regex: str) -> None: """Add a regex pattern to the blacklist.""" async with config.regex_blacklist() as blacklist: @@ -538,7 +541,7 @@ class Pterodactyl(commands.Cog): else: await msg.edit(content="Cancelled.") - @pterodactyl_config_regex_blacklist.command(name = "remove") + @pterodactyl_config_regex_blacklist.command(name="remove") async def pterodactyl_config_regex_blacklist_remove(self, ctx: commands.Context, name: str) -> None: """Remove a regex pattern from the blacklist.""" async with config.regex_blacklist() as blacklist: @@ -555,7 +558,7 @@ class Pterodactyl(commands.Cog): else: await ctx.send(f"Name `{name}` does not exist in the blacklist.") - @pterodactyl_config.command(name = 'view', aliases = ['show']) + @pterodactyl_config.command(name="view", aliases=["show"]) async def pterodactyl_config_view(self, ctx: commands.Context) -> None: """View the current configuration.""" base_url = await config.base_url() @@ -580,7 +583,7 @@ class Pterodactyl(commands.Cog): topic_text = await config.topic() topic_hostname = await config.topic_hostname() topic_port = await config.topic_port() - embed = discord.Embed(color = await ctx.embed_color(), title="Pterodactyl Configuration") + embed = discord.Embed(color=await ctx.embed_color(), title="Pterodactyl Configuration") embed.description = f"""**Base URL:** {base_url} **Server ID:** `{server_id}` **Console Channel:** <#{console_channel}> @@ -596,19 +599,19 @@ class Pterodactyl(commands.Cog): **Topic Hostname:** `{topic_hostname}` **Topic Port:** `{topic_port}` - **Topic Text:** {box(topic_text, 'yaml')} + **Topic Text:** {box(topic_text, "yaml")} - **Chat Command:** {box(chat_command, 'json')} - **Chat Regex:** {box(chat_regex, 're')} - **Server Regex:** {box(server_regex, 're')} - **Join Regex:** {box(join_regex, 're')} - **Leave Regex:** {box(leave_regex, 're')} - **Achievement Regex:** {box(achievement_regex, 're')}""" + **Chat Command:** {box(chat_command, "json")} + **Chat Regex:** {box(chat_regex, "re")} + **Server Regex:** {box(server_regex, "re")} + **Join Regex:** {box(join_regex, "re")} + **Leave Regex:** {box(leave_regex, "re")} + **Achievement Regex:** {box(achievement_regex, "re")}""" await ctx.send(embed=embed) if not len(regex_blacklist) == 0: - regex_blacklist_embed = discord.Embed(color = await ctx.embed_color(), title="Regex Blacklist") + regex_blacklist_embed = discord.Embed(color=await ctx.embed_color(), title="Regex Blacklist") for name, regex in regex_blacklist.items(): - regex_blacklist_embed.add_field(name=name, value=box(regex, 're'), inline=False) + regex_blacklist_embed.add_field(name=name, value=box(regex, "re"), inline=False) await ctx.send(embed=regex_blacklist_embed) def get_bool_str(self, inp: bool) -> str: From 9df7f15bbe99ce4b27909b6819b881c37a71bf99 Mon Sep 17 00:00:00 2001 From: cswimr Date: Sun, 26 Jan 2025 14:11:37 +0000 Subject: [PATCH 19/53] chore(repo): enable even more ruff rules --- pyproject.toml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index fbe8028..eea078e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -87,6 +87,8 @@ select = [ "W", "E", "G", + "A", + "COM", "INP", "T20", "PLC", @@ -99,8 +101,11 @@ select = [ "FIX", "PERF", "C4", + "EM", + "RET", + "RSE", ] -ignore = ["PLR0912", "PLR0915", "PLR2004", "PLR0913"] +ignore = ["PLR0912", "PLR0915", "PLR2004", "PLR0913", "EM101"] # Allow fix for all enabled rules (when `--fix`) is provided. fixable = ["ALL"] From ea5f51892ae92bfd5d18ac038f26461dcab1751f Mon Sep 17 00:00:00 2001 From: cswimr Date: Sun, 26 Jan 2025 14:13:37 +0000 Subject: [PATCH 20/53] style(repo): ruff fixes --- backup/backup.py | 2 +- bible/bible.py | 34 +++++++++++++++++----------------- emojiinfo/emojiinfo.py | 16 ++++++++-------- hotreload/hotreload.py | 2 +- nerdify/nerdify.py | 8 ++++---- pterodactyl/pterodactyl.py | 10 ++++++---- pterodactyl/websocket.py | 5 ++--- 7 files changed, 39 insertions(+), 38 deletions(-) diff --git a/backup/backup.py b/backup/backup.py index 2aafb8c..66928bd 100644 --- a/backup/backup.py +++ b/backup/backup.py @@ -183,7 +183,7 @@ class Backup(commands.Cog): continue cog_modules.append(cog_module) - for cog in set(cog.name for cog in cog_modules): + for cog in {cog.name for cog in cog_modules}: poss_installed_path = (await downloader.cog_install_path()) / cog if poss_installed_path.exists(): with contextlib.suppress(commands.ExtensionNotLoaded): diff --git a/bible/bible.py b/bible/bible.py index 0a976ec..c3af117 100644 --- a/bible/bible.py +++ b/bible/bible.py @@ -91,11 +91,11 @@ class Bible(commands.Cog): response.status, ) if response.status == 401: - raise bible.errors.UnauthorizedError() + raise bible.errors.UnauthorizedError if response.status == 403: - raise bible.errors.BibleAccessError() + raise bible.errors.BibleAccessError if response.status == 503: - raise bible.errors.ServiceUnavailableError() + raise bible.errors.ServiceUnavailableError return Version( bible_id=bible_id, abbreviation=data["data"]["abbreviation"], @@ -135,15 +135,15 @@ class Bible(commands.Cog): response.status, ) if response.status == 400: - raise bible.errors.InexplicableError() + raise bible.errors.InexplicableError if response.status == 401: - raise bible.errors.UnauthorizedError() + raise bible.errors.UnauthorizedError if response.status == 403: - raise bible.errors.BibleAccessError() + raise bible.errors.BibleAccessError if response.status == 404: - raise bible.errors.NotFoundError() + raise bible.errors.NotFoundError if response.status == 503: - raise bible.errors.ServiceUnavailableError() + raise bible.errors.ServiceUnavailableError fums_url = "https://fums.api.bible/f3" fums_params = { @@ -176,11 +176,11 @@ class Bible(commands.Cog): response.status, ) if response.status == 401: - raise bible.errors.UnauthorizedError() + raise bible.errors.UnauthorizedError if response.status == 403: - raise bible.errors.BibleAccessError() + raise bible.errors.BibleAccessError if response.status == 503: - raise bible.errors.ServiceUnavailableError() + raise bible.errors.ServiceUnavailableError return data["data"] async def _get_chapters(self, bible_id: str, book_id: str) -> dict: @@ -195,11 +195,11 @@ class Bible(commands.Cog): response.status, ) if response.status == 401: - raise bible.errors.UnauthorizedError() + raise bible.errors.UnauthorizedError if response.status == 403: - raise bible.errors.BibleAccessError() + raise bible.errors.BibleAccessError if response.status == 503: - raise bible.errors.ServiceUnavailableError() + raise bible.errors.ServiceUnavailableError return data["data"] async def _get_verses(self, bible_id: str, book_id: str, chapter: int) -> dict: @@ -214,11 +214,11 @@ class Bible(commands.Cog): response.status, ) if response.status == 401: - raise bible.errors.UnauthorizedError() + raise bible.errors.UnauthorizedError if response.status == 403: - raise bible.errors.BibleAccessError() + raise bible.errors.BibleAccessError if response.status == 503: - raise bible.errors.ServiceUnavailableError() + raise bible.errors.ServiceUnavailableError return data["data"] @commands.group(autohelp=True) diff --git a/emojiinfo/emojiinfo.py b/emojiinfo/emojiinfo.py index f1f947a..aae0a92 100644 --- a/emojiinfo/emojiinfo.py +++ b/emojiinfo/emojiinfo.py @@ -40,8 +40,7 @@ class EmojiInfo(commands.Cog): emoji_codepoint = "-".join([hex(ord(char))[2:] for char in unicode_emoji]) segments = emoji_codepoint.split("-") valid_segments = [seg for seg in segments if len(seg) >= 4] - emoji_url = f"{base_url}{valid_segments[0]}.png" - return emoji_url + return f"{base_url}{valid_segments[0]}.png" async def fetch_primary_color(self, emoji_url: str) -> discord.Color | None: async with aiohttp.ClientSession() as session: @@ -50,8 +49,7 @@ class EmojiInfo(commands.Cog): return None image = await response.read() dominant_color = ColorThief(io.BytesIO(image)).get_color(quality=1) - color = discord.Color.from_rgb(*dominant_color) - return color + return discord.Color.from_rgb(*dominant_color) async def get_emoji_info(self, emoji: PartialEmoji) -> tuple[str, str]: if emoji.is_unicode_emoji(): @@ -98,8 +96,9 @@ class EmojiInfo(commands.Cog): embed.set_thumbnail(url=emoji_url) await interaction.followup.send(embed=embed) - else: - await interaction.followup.send(content=string) + return None + await interaction.followup.send(content=string) + return None @commands.command(name="emoji") async def emoji(self, ctx: commands.Context, *, emoji: str) -> None: @@ -119,5 +118,6 @@ class EmojiInfo(commands.Cog): embed.set_thumbnail(url=emoji_url) await ctx.send(embed=embed) - else: - await ctx.send(content=string) + return None + await ctx.send(content=string) + return None diff --git a/hotreload/hotreload.py b/hotreload/hotreload.py index 254ae7f..3e9061b 100644 --- a/hotreload/hotreload.py +++ b/hotreload/hotreload.py @@ -105,5 +105,5 @@ class HotReloadHandler(RegexMatchingEventHandler): """Reload modified cog.""" core_logic = CoreLogic(bot=self.bot) self.logger.info("Reloading cogs: %s", humanize_list(cog_names, style="unit")) - await core_logic._reload(pkg_names=cog_names) + await core_logic._reload(pkg_names=cog_names) # noqa: SLF001 # We have to use this private method because there is no public API to reload other cogs self.logger.info("Reloaded cogs: %s", humanize_list(cog_names, style="unit")) diff --git a/nerdify/nerdify.py b/nerdify/nerdify.py index f5e92b5..346d37e 100644 --- a/nerdify/nerdify.py +++ b/nerdify/nerdify.py @@ -40,13 +40,13 @@ class Nerdify(commands.Cog): @commands.command(aliases=["nerd"]) async def nerdify( - self, ctx: commands.Context, *, text: Optional[str] = None + self, ctx: commands.Context, *, text: Optional[str] = None, ) -> None: """Nerdify the replied to message, previous message, or your own text.""" if not text: if hasattr(ctx.message, "reference") and ctx.message.reference: with suppress( - discord.Forbidden, discord.NotFound, discord.HTTPException + discord.Forbidden, discord.NotFound, discord.HTTPException, ): message_id = ctx.message.reference.message_id if message_id: @@ -62,7 +62,7 @@ class Nerdify(commands.Cog): ctx.channel, self.nerdify_text(text), allowed_mentions=discord.AllowedMentions( - everyone=False, users=False, roles=False + everyone=False, users=False, roles=False, ), ) @@ -77,7 +77,7 @@ class Nerdify(commands.Cog): return f'"{text}" 🤓' async def type_message( - self, destination: discord.abc.Messageable, content: str, **kwargs: Any + self, destination: discord.abc.Messageable, content: str, **kwargs: Any, ) -> Union[discord.Message, None]: """Simulate typing and sending a message to a destination. diff --git a/pterodactyl/pterodactyl.py b/pterodactyl/pterodactyl.py index a0be73e..5e93c9c 100644 --- a/pterodactyl/pterodactyl.py +++ b/pterodactyl/pterodactyl.py @@ -149,7 +149,7 @@ class Pterodactyl(commands.Cog): "P": str(response["players"]["online"]), "V": response["version"], "D": response["motd"]["clean"][0] if response["motd"]["clean"] else "unset", - } + }, ) else: placeholders.update( @@ -159,7 +159,7 @@ class Pterodactyl(commands.Cog): "P": "0", "V": "Server Offline", "D": "Server Offline", - } + }, ) for key, value in placeholders.items(): topic = topic.replace(".$" + key, value) @@ -187,6 +187,7 @@ class Pterodactyl(commands.Cog): output_str = "\n".join(response["players"]["list"]) return output_str, response["players"]["list"] return None + return None async def get_player_list_embed(self, ctx: Union[commands.Context, discord.Interaction]) -> Optional[discord.Embed]: player_list = await self.get_player_list() @@ -220,9 +221,10 @@ class Pterodactyl(commands.Cog): await self.websocket.send(json.dumps({"event": "set state", "args": [action]})) await message.edit(content=f"Server {action_ing}", view=None) + return None - else: - await message.edit(content="Cancelled.", view=None) + await message.edit(content="Cancelled.", view=None) + return None async def send_command(self, ctx: Union[discord.Interaction, commands.Context], command: str): channel = self.bot.get_channel(await config.console_channel()) diff --git a/pterodactyl/websocket.py b/pterodactyl/websocket.py index e5fd8db..00c5566 100644 --- a/pterodactyl/websocket.py +++ b/pterodactyl/websocket.py @@ -151,7 +151,7 @@ async def retrieve_websocket_credentials(coginstance: Pterodactyl) -> Optional[d Socket: %s Token: %s...""", websocket_credentials['data']['socket'], - websocket_credentials['data']['token'][:20] + websocket_credentials['data']['token'][:20], ) return websocket_credentials #NOTE - The token is truncated to prevent it from being logged in its entirety, for security reasons @@ -262,6 +262,5 @@ async def generate_achievement_embed(coginstance: Pterodactyl, username: str, ac def mask_ip(string: str) -> str: def check(match: re.Match[str]): ip = match.group(0) - masked_ip = '.'.join(r'\*' * len(octet) for octet in ip.split('.')) - return masked_ip + return '.'.join(r'\*' * len(octet) for octet in ip.split('.')) return re.sub(r'\b(?:\d{1,3}\.){3}\d{1,3}\b', check, string) From 65cfafc7b3ad9a804c11821eda0638713788f166 Mon Sep 17 00:00:00 2001 From: cswimr Date: Sun, 26 Jan 2025 14:16:39 +0000 Subject: [PATCH 21/53] style(emojiinfo): ruff fix --- emojiinfo/model.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/emojiinfo/model.py b/emojiinfo/model.py index cc8a468..5885afb 100644 --- a/emojiinfo/model.py +++ b/emojiinfo/model.py @@ -39,7 +39,7 @@ class PartialEmoji(discord.PartialEmoji): The group name of the emoji if it is a native emoji. """ - def __init__(self, *, name: str, animated: bool = False, id: int | None = None, group: str | None = None, aliases: list | None = None) -> None: # pylint: disable=redefined-builtin + def __init__(self, *, name: str, animated: bool = False, id: int | None = None, group: str | None = None, aliases: list | None = None) -> None: # pylint: disable=redefined-builtin # noqa: A002 super().__init__(name=name, animated=animated, id=id) self.group = group self.aliases = aliases @@ -72,9 +72,9 @@ class PartialEmoji(discord.PartialEmoji): match = cls._CUSTOM_EMOJI_RE.match(value) if match is not None: groups = match.groupdict() - animated = bool(groups['animated']) - emoji_id = int(groups['id']) - name = groups['name'] + animated = bool(groups["animated"]) + emoji_id = int(groups["id"]) + name = groups["name"] return cls(name=name, animated=animated, id=emoji_id) path: data_manager.Path = data_manager.bundled_data_path(coginstance) / "emojis.json" From 59d33ea87d326057b078fe4d668684f56a1fc671 Mon Sep 17 00:00:00 2001 From: cswimr Date: Sun, 26 Jan 2025 14:16:46 +0000 Subject: [PATCH 22/53] style(seautils): ruff fix --- seautils/seautils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/seautils/seautils.py b/seautils/seautils.py index 272112d..13d6d03 100644 --- a/seautils/seautils.py +++ b/seautils/seautils.py @@ -76,7 +76,7 @@ class SeaUtils(commands.Cog): @commands.command(aliases=["source", "src", "code", "showsource"]) @commands.is_owner() - async def showcode(self, ctx: commands.Context, *, object: str) -> None: # pylint: disable=redefined-builtin + async def showcode(self, ctx: commands.Context, *, object: str) -> None: # pylint: disable=redefined-builtin # noqa: A002 """Show the code for a particular object.""" try: if object.startswith("/") and (obj := ctx.bot.tree.get_command(object[1:])): From d51e3f17e9e7e7d6877e9fb153b326cc724c2957 Mon Sep 17 00:00:00 2001 From: cswimr Date: Sun, 26 Jan 2025 14:22:12 +0000 Subject: [PATCH 23/53] fix(antipolls): ruff fixes --- antipolls/antipolls.py | 22 +++++++++++----------- pyproject.toml | 2 +- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/antipolls/antipolls.py b/antipolls/antipolls.py index 15aecfd..b721d08 100644 --- a/antipolls/antipolls.py +++ b/antipolls/antipolls.py @@ -17,7 +17,7 @@ class AntiPolls(commands.Cog): __author__ = ["[cswimr](https://www.coastalcommits.com/cswimr)"] __git__ = "https://www.coastalcommits.com/cswimr/SeaCogs" - __version__ = "1.0.1" + __version__ = "1.0.2" __documentation__ = "https://seacogs.coastalcommits.com/antipolls/" def __init__(self, bot: Red): @@ -45,11 +45,11 @@ class AntiPolls(commands.Cog): ] return "\n".join(text) - async def red_delete_data_for_user(self, **kwargs): # pylint: disable=unused-argument + async def red_delete_data_for_user(self, **kwargs): # pylint: disable=unused-argument """Nothing to delete.""" return - @commands.Cog.listener('on_message') + @commands.Cog.listener("on_message") async def polls_listener(self, message: discord.Message) -> None: if message.guild is None: return self.logger.verbose("Message in direct messages ignored") @@ -62,13 +62,13 @@ class AntiPolls(commands.Cog): guild_config = await self.config.guild(message.guild).all() - if guild_config['manage_messages'] is True and message.author.guild_permissions.manage_messages: + if guild_config["manage_messages"] is True and message.author.guild_permissions.manage_messages: return self.logger.verbose("Message from user with Manage Messages permission ignored") - if message.channel.id in guild_config['channel_whitelist']: + if message.channel.id in guild_config["channel_whitelist"]: return self.logger.verbose("Message in whitelisted channel %s ignored", message.channel.id) - if any(role.id in guild_config['role_whitelist'] for role in message.author.roles): + if any(role.id in guild_config["role_whitelist"] for role in message.author.roles): return self.logger.verbose("Message from whitelisted role %s ignored", message.author.roles) if not message.content and not message.embeds and not message.attachments and not message.stickers: @@ -80,7 +80,7 @@ class AntiPolls(commands.Cog): return self.logger.error("Failed to delete message: %s", e) return self.logger.trace("Deleted poll message %s", message.id) - self.logger.verbose("Message %s is not a poll, ignoring", message.id) + return self.logger.verbose("Message %s is not a poll, ignoring", message.id) @commands.group(name="antipolls", aliases=["ap"]) @commands.guild_only() @@ -123,13 +123,13 @@ class AntiPolls(commands.Cog): await ctx.send(f"The following roles were not in the whitelist: {humanize_list([role.mention for role in failed])}", delete_after=10) @antipolls_roles.command(name="list") - async def antipolls_roles_list(self, ctx: commands.Context) -> None: + async def antipolls_roles_list(self, ctx: commands.Context) -> discord.Message: """List roles in the whitelist.""" role_whitelist = await self.config.guild(ctx.guild).role_whitelist() if not role_whitelist: return await ctx.send("No roles in the whitelist.") roles = [ctx.guild.get_role(role) for role in role_whitelist] - await ctx.send(humanize_list([role.mention for role in roles])) + return await ctx.send(humanize_list([role.mention for role in roles])) @antipolls.group(name="channels") async def antipolls_channels(self, ctx: commands.Context) -> None: @@ -166,13 +166,13 @@ class AntiPolls(commands.Cog): await ctx.send(f"The following channels were not in the whitelist: {humanize_list([channel.mention for channel in failed])}", delete_after=10) @antipolls_channels.command(name="list") - async def antipolls_channels_list(self, ctx: commands.Context) -> None: + async def antipolls_channels_list(self, ctx: commands.Context) -> discord.Message: """List channels in the whitelist.""" channel_whitelist = await self.config.guild(ctx.guild).channel_whitelist() if not channel_whitelist: return await ctx.send("No channels in the whitelist.") channels = [ctx.guild.get_channel(channel) for channel in channel_whitelist] - await ctx.send(humanize_list([channel.mention for channel in channels])) + return await ctx.send(humanize_list([channel.mention for channel in channels])) @antipolls.command(name="managemessages") async def antipolls_managemessages(self, ctx: commands.Context, enabled: bool) -> None: diff --git a/pyproject.toml b/pyproject.toml index eea078e..94aa6c5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -105,7 +105,7 @@ select = [ "RET", "RSE", ] -ignore = ["PLR0912", "PLR0915", "PLR2004", "PLR0913", "EM101"] +ignore = ["PLR0911", "PLR0912", "PLR0915", "PLR2004", "PLR0913", "EM101"] # Allow fix for all enabled rules (when `--fix`) is provided. fixable = ["ALL"] From ff9e20be919b46a9d263ad1bd9bad2aa589aed61 Mon Sep 17 00:00:00 2001 From: cswimr Date: Sun, 26 Jan 2025 15:04:05 +0000 Subject: [PATCH 24/53] fix(pterodactyl): update pterodactyl for the new version of websockets & fix a few minor bugs --- pterodactyl/logger.py | 4 +- pterodactyl/pterodactyl.py | 16 ++++--- pterodactyl/websocket.py | 96 ++++++++++++++++++++++---------------- 3 files changed, 66 insertions(+), 50 deletions(-) diff --git a/pterodactyl/logger.py b/pterodactyl/logger.py index 64b005f..8600903 100644 --- a/pterodactyl/logger.py +++ b/pterodactyl/logger.py @@ -1,8 +1,8 @@ from red_commons import logging from red_commons.logging import getLogger -logger = getLogger('red.SeaCogs.Pterodactyl') -websocket_logger = getLogger('red.SeaCogs.Pterodactyl.websocket') +logger = getLogger("red.SeaCogs.Pterodactyl") +websocket_logger = getLogger("red.SeaCogs.Pterodactyl.Websocket") if logger.level >= logging.VERBOSE: websocket_logger.setLevel(logging.logging.INFO) elif logger.level < logging.VERBOSE: diff --git a/pterodactyl/pterodactyl.py b/pterodactyl/pterodactyl.py index 5e93c9c..18e229f 100644 --- a/pterodactyl/pterodactyl.py +++ b/pterodactyl/pterodactyl.py @@ -22,14 +22,14 @@ class Pterodactyl(commands.Cog): __author__ = ["[cswimr](https://www.coastalcommits.com/cswimr)"] __git__ = "https://www.coastalcommits.com/cswimr/SeaCogs" - __version__ = "2.0.4" + __version__ = "2.0.5" __documentation__ = "https://seacogs.coastalcommits.com/pterodactyl/" def __init__(self, bot: Red): self.bot = bot self.client: Optional[PterodactylClient] = None self.task: Optional[asyncio.Task] = None - self.websocket: Optional[websockets.WebSocketClientProtocol] = None + self.websocket: Optional[websockets.ClientConnection] = None self.retry_counter: int = 0 register_config(config) self.task = self.get_task() @@ -51,15 +51,18 @@ class Pterodactyl(commands.Cog): api_key = pterodactyl_keys.get("api_key") if api_key is None: self.task.cancel() - raise ValueError("Pterodactyl API key not set. Please set it using `[p]set api`.") + logger.error("Pterodactyl API key not set. Please set it using `[p]set api`.") + return base_url = await config.base_url() if base_url is None: self.task.cancel() - raise ValueError("Pterodactyl base URL not set. Please set it using `[p]pterodactyl config url`.") + logger.error("Pterodactyl base URL not set. Please set it using `[p]pterodactyl config url`.") + return server_id = await config.server_id() if server_id is None: self.task.cancel() - raise ValueError("Pterodactyl server ID not set. Please set it using `[p]pterodactyl config serverid`.") + logger.error("Pterodactyl server ID not set. Please set it using `[p]pterodactyl config serverid`.") + return self.client = PterodactylClient(base_url, api_key).client @@ -67,7 +70,6 @@ class Pterodactyl(commands.Cog): self.update_topic.cancel() self.task.cancel() self.retry_counter = 0 - await self.client._session.close() # pylint: disable=protected-access # noqa: SLF001 def get_task(self) -> asyncio.Task: from pterodactyl.websocket import establish_websocket_connection @@ -76,7 +78,7 @@ class Pterodactyl(commands.Cog): task.add_done_callback(self.error_callback) return task - def error_callback(self, fut) -> None: # NOTE - Thanks flame442 and zephyrkul for helping me figure this out + def error_callback(self, fut) -> None: # NOTE Thanks flame442 and zephyrkul for helping me figure this out try: fut.result() except asyncio.CancelledError: diff --git a/pterodactyl/websocket.py b/pterodactyl/websocket.py index 00c5566..4392744 100644 --- a/pterodactyl/websocket.py +++ b/pterodactyl/websocket.py @@ -6,10 +6,10 @@ from typing import Optional, Tuple, Union import aiohttp import discord -import websockets from pydactyl import PterodactylClient from redbot.core.data_manager import bundled_data_path from redbot.core.utils.chat_formatting import bold, pagify +from websockets.asyncio.client import connect from pterodactyl.config import config from pterodactyl.logger import logger, websocket_logger @@ -19,46 +19,46 @@ from pterodactyl.pterodactyl import Pterodactyl async def establish_websocket_connection(coginstance: Pterodactyl) -> None: await coginstance.bot.wait_until_red_ready() base_url = await config.base_url() - base_url = base_url[:-1] if base_url.endswith('/') else base_url + base_url = base_url[:-1] if base_url.endswith("/") else base_url logger.info("Establishing WebSocket connection") websocket_credentials = await retrieve_websocket_credentials(coginstance) - async with websockets.connect(websocket_credentials['data']['socket'], origin=base_url, ping_timeout=60, logger=websocket_logger) as websocket: + async with connect(websocket_credentials["data"]["socket"], origin=base_url, ping_timeout=60, logger=websocket_logger) as websocket: logger.info("WebSocket connection established") - auth_message = json.dumps({"event": "auth", "args": [websocket_credentials['data']['token']]}) + auth_message = json.dumps({"event": "auth", "args": [websocket_credentials["data"]["token"]]}) await websocket.send(auth_message) logger.info("Authentication message sent") coginstance.websocket = websocket - while True: # pylint: disable=too-many-nested-blocks + while True: # pylint: disable=too-many-nested-blocks message = json.loads(await websocket.recv()) - if message['event'] in ('token expiring', 'token expired'): + if message["event"] in ("token expiring", "token expired"): logger.info("Received token expiring/expired event. Refreshing token.") websocket_credentials = await retrieve_websocket_credentials(coginstance) - auth_message = json.dumps({"event": "auth", "args": [websocket_credentials['data']['token']]}) + auth_message = json.dumps({"event": "auth", "args": [websocket_credentials["data"]["token"]]}) await websocket.send(auth_message) logger.info("Authentication message sent") - if message['event'] == 'auth success': + if message["event"] == "auth success": logger.info("WebSocket authentication successful") - if message['event'] == 'console output' and await config.console_channel() is not None: + if message["event"] == "console output" and await config.console_channel() is not None: regex_blacklist: dict = await config.regex_blacklist() - matches = [re.search(regex, message['args'][0]) for regex in regex_blacklist.values()] + matches = [re.search(regex, message["args"][0]) for regex in regex_blacklist.values()] - if await config.current_status() in ('running', '') and not any(matches): - content = remove_ansi_escape_codes(message['args'][0]) + if await config.current_status() in ("running", "") and not any(matches): + content = remove_ansi_escape_codes(message["args"][0]) if await config.mask_ip() is True: content = mask_ip(content) console_channel = coginstance.bot.get_channel(await config.console_channel()) chat_channel = coginstance.bot.get_channel(await config.chat_channel()) if console_channel is not None: - if content.startswith('['): + if content.startswith("["): pagified_content = pagify(content, delims=[" ", "\n"]) for page in pagified_content: await console_channel.send(content=page, allowed_mentions=discord.AllowedMentions.none()) @@ -66,23 +66,23 @@ async def establish_websocket_connection(coginstance: Pterodactyl) -> None: server_message = await check_if_server_message(content) if server_message: if chat_channel is not None: - await chat_channel.send(server_message if len(server_message) < 2000 else server_message[:1997] + '...', allowed_mentions=discord.AllowedMentions.none()) + await chat_channel.send(server_message if len(server_message) < 2000 else server_message[:1997] + "...", allowed_mentions=discord.AllowedMentions.none()) chat_message = await check_if_chat_message(content) if chat_message: - info = await get_info(chat_message['username']) + info = await get_info(chat_message["username"]) if info is not None: - await send_chat_discord(coginstance, chat_message['username'], chat_message['message'], info['data']['player']['avatar']) + await send_chat_discord(coginstance, chat_message["username"], chat_message["message"], info["data"]["player"]["avatar"]) else: - await send_chat_discord(coginstance, chat_message['username'], chat_message['message'], 'https://seafsh.cc/u/j3AzqQ.png') + await send_chat_discord(coginstance, chat_message["username"], chat_message["message"], "https://seafsh.cc/u/j3AzqQ.png") join_message = await check_if_join_message(content) if join_message: if chat_channel is not None: if coginstance.bot.embed_requested(chat_channel): - embed, img = await generate_join_leave_embed(coginstance=coginstance, username=join_message,join=True) + embed, img = await generate_join_leave_embed(coginstance=coginstance, username=join_message, join=True) if img: - with open(img, 'rb') as file: + with open(img, "rb") as file: await chat_channel.send(embed=embed, file=file) else: await chat_channel.send(embed=embed) @@ -93,9 +93,9 @@ async def establish_websocket_connection(coginstance: Pterodactyl) -> None: if leave_message: if chat_channel is not None: if coginstance.bot.embed_requested(chat_channel): - embed, img = await generate_join_leave_embed(coginstance=coginstance, username=leave_message,join=False) + embed, img = await generate_join_leave_embed(coginstance=coginstance, username=leave_message, join=False) if img: - with open(img, 'rb') as file: + with open(img, "rb") as file: await chat_channel.send(embed=embed, file=file) else: await chat_channel.send(embed=embed) @@ -106,13 +106,13 @@ async def establish_websocket_connection(coginstance: Pterodactyl) -> None: if achievement_message: if chat_channel is not None: if coginstance.bot.embed_requested(chat_channel): - await chat_channel.send(embed=await generate_achievement_embed(coginstance, achievement_message['username'], achievement_message['achievement'], achievement_message['challenge'])) + await chat_channel.send(embed=await generate_achievement_embed(coginstance, achievement_message["username"], achievement_message["achievement"], achievement_message["challenge"])) else: await chat_channel.send(f"{achievement_message['username']} has {'completed the challenge' if achievement_message['challenge'] else 'made the advancement'} {achievement_message['achievement']}") - if message['event'] == 'status': + if message["event"] == "status": old_status = await config.current_status() - current_status = message['args'][0] + current_status = message["args"][0] if old_status != current_status: await config.current_status.set(current_status) if await config.console_channel() is not None: @@ -120,15 +120,16 @@ async def establish_websocket_connection(coginstance: Pterodactyl) -> None: if console is not None: await console.send(f"Server status changed! `{current_status}`") if await config.chat_channel() is not None: - if current_status == 'running' and await config.startup_msg() is not None: + if current_status == "running" and await config.startup_msg() is not None: chat = coginstance.bot.get_channel(await config.chat_channel()) if chat is not None: await chat.send(await config.startup_msg()) - if current_status == 'stopping' and await config.shutdown_msg() is not None: + if current_status == "stopping" and await config.shutdown_msg() is not None: chat = coginstance.bot.get_channel(await config.chat_channel()) if chat is not None: await chat.send(await config.shutdown_msg()) + async def retrieve_websocket_credentials(coginstance: Pterodactyl) -> Optional[dict]: pterodactyl_keys = await coginstance.bot.get_shared_api_tokens("pterodactyl") api_key = pterodactyl_keys.get("api_key") @@ -147,19 +148,22 @@ async def retrieve_websocket_credentials(coginstance: Pterodactyl) -> Optional[d client = PterodactylClient(base_url, api_key).client coginstance.client = client websocket_credentials = client.servers.get_websocket(server_id) - logger.debug("""Websocket connection details retrieved: + logger.debug( + """Websocket connection details retrieved: Socket: %s Token: %s...""", - websocket_credentials['data']['socket'], - websocket_credentials['data']['token'][:20], - ) + websocket_credentials["data"]["socket"], + websocket_credentials["data"]["token"][:20], + ) return websocket_credentials - #NOTE - The token is truncated to prevent it from being logged in its entirety, for security reasons + # NOTE - The token is truncated to prevent it from being logged in its entirety, for security reasons + def remove_ansi_escape_codes(text: str) -> str: - ansi_escape = re.compile(r'\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])') - #NOTE - https://chat.openai.com/share/d92f9acf-d776-4fd6-a53f-b14ac15dd540 - return ansi_escape.sub('', text) + ansi_escape = re.compile(r"\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])") + # NOTE - https://chat.openai.com/share/d92f9acf-d776-4fd6-a53f-b14ac15dd540 + return ansi_escape.sub("", text) + async def check_if_server_message(text: str) -> Union[bool, str]: regex = await config.server_regex() @@ -169,6 +173,7 @@ async def check_if_server_message(text: str) -> Union[bool, str]: return match.group(1) return False + async def check_if_chat_message(text: str) -> Union[bool, dict]: regex = await config.chat_regex() match: Optional[re.Match[str]] = re.match(regex, text) @@ -178,6 +183,7 @@ async def check_if_chat_message(text: str) -> Union[bool, dict]: return groups return False + async def check_if_join_message(text: str) -> Union[bool, str]: regex = await config.join_regex() match: Optional[re.Match[str]] = re.match(regex, text) @@ -186,6 +192,7 @@ async def check_if_join_message(text: str) -> Union[bool, str]: return match.group(1) return False + async def check_if_leave_message(text: str) -> Union[bool, str]: regex = await config.leave_regex() match: Optional[re.Match[str]] = re.match(regex, text) @@ -194,6 +201,7 @@ async def check_if_leave_message(text: str) -> Union[bool, str]: return match.group(1) return False + async def check_if_achievement_message(text: str) -> Union[bool, dict]: regex = await config.achievement_regex() match: Optional[re.Match[str]] = re.match(regex, text) @@ -207,6 +215,7 @@ async def check_if_achievement_message(text: str) -> Union[bool, dict]: return groups return False + async def get_info(username: str) -> Optional[dict]: logger.verbose("Retrieving player info for %s", username) endpoint = await config.api_endpoint() @@ -218,6 +227,7 @@ async def get_info(username: str) -> Optional[dict]: logger.warning("Failed to retrieve player info for %s: %s", username, response.status) return None + async def send_chat_discord(coginstance: Pterodactyl, username: str, message: str, avatar_url: str) -> None: logger.trace("Sending chat message to Discord") channel = coginstance.bot.get_channel(await config.chat_channel()) @@ -231,6 +241,7 @@ async def send_chat_discord(coginstance: Pterodactyl, username: str, message: st else: logger.warning("Chat channel not set. Skipping sending chat message to Discord") + async def generate_join_leave_embed(coginstance: Pterodactyl, username: str, join: bool) -> Tuple[discord.Embed, Optional[Union[str, Path]]]: embed = discord.Embed() embed.color = discord.Color.green() if join else discord.Color.red() @@ -238,29 +249,32 @@ async def generate_join_leave_embed(coginstance: Pterodactyl, username: str, joi info = await get_info(username) if info: img = None - embed.set_author(name=username, icon_url=info['data']['player']['avatar']) + embed.set_author(name=username, icon_url=info["data"]["player"]["avatar"]) else: img = bundled_data_path(coginstance) / "unknown.png" - embed.set_author(name=username, icon_url='attachment://unknown.png') + embed.set_author(name=username, icon_url="attachment://unknown.png") embed.timestamp = discord.utils.utcnow() return embed, img + async def generate_achievement_embed(coginstance: Pterodactyl, username: str, achievement: str, challenge: bool) -> Tuple[discord.Embed, Optional[Union[str, Path]]]: embed = discord.Embed() - embed.color = discord.Color.from_str('#a800a7') if challenge else discord.Color.from_str('#54fb54') + embed.color = discord.Color.from_str("#a800a7") if challenge else discord.Color.from_str("#54fb54") embed.description = f"{bold(username)} has {'completed the challenge' if challenge else 'made the advancement'} {bold(achievement)}" info = await get_info(username) if info: img = None - embed.set_author(name=username, icon_url=info['data']['player']['avatar']) + embed.set_author(name=username, icon_url=info["data"]["player"]["avatar"]) else: img = bundled_data_path(coginstance) / "unknown.png" - embed.set_author(name=username, icon_url='attachment://unknown.png') + embed.set_author(name=username, icon_url="attachment://unknown.png") embed.timestamp = discord.utils.utcnow() return embed, img + def mask_ip(string: str) -> str: def check(match: re.Match[str]): ip = match.group(0) - return '.'.join(r'\*' * len(octet) for octet in ip.split('.')) - return re.sub(r'\b(?:\d{1,3}\.){3}\d{1,3}\b', check, string) + return ".".join(r"\*" * len(octet) for octet in ip.split(".")) + + return re.sub(r"\b(?:\d{1,3}\.){3}\d{1,3}\b", check, string) From ccf9389e1378ace5225f9ed1ce56a571ad785098 Mon Sep 17 00:00:00 2001 From: cswimr Date: Sun, 26 Jan 2025 10:06:14 -0500 Subject: [PATCH 25/53] feat(hotreload): Channel Notifications (#51) # Channel Notifications This PR adds the ability for HotReload to send messages to a configurable discord channel when reloading a cog. Messages are only sent after the cog is reloaded to prevent slowdowns. - [x] By submitting this pull request, I permit [cswimr](https://www.coastalcommits.com/cswimr) to license my work under the [Mozilla Public License Version 2.0](https://www.coastalcommits.com/cswimr/SeaCogs/src/branch/main/LICENSE). Reviewed-on: https://www.coastalcommits.com/cswimr/SeaCogs/pulls/51 --- hotreload/hotreload.py | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/hotreload/hotreload.py b/hotreload/hotreload.py index 3e9061b..185c90d 100644 --- a/hotreload/hotreload.py +++ b/hotreload/hotreload.py @@ -3,7 +3,7 @@ from pathlib import Path from typing import Sequence from red_commons.logging import RedTraceLogger, getLogger -from redbot.core import commands +from redbot.core import Config, checks, commands from redbot.core.bot import Red from redbot.core.core_commands import CoreLogic from redbot.core.utils.chat_formatting import bold, humanize_list @@ -16,14 +16,16 @@ class HotReload(commands.Cog): __author__ = ["[cswimr](https://www.coastalcommits.com/cswimr)"] __git__ = "https://www.coastalcommits.com/cswimr/SeaCogs" - __version__ = "1.1.2" + __version__ = "1.2.0" __documentation__ = "https://seacogs.coastalcommits.com/hotreload/" def __init__(self, bot: Red) -> None: super().__init__() self.bot: Red = bot + self.config = Config.get_conf(self, identifier=294518358420750336, force_registration=True) self.logger: RedTraceLogger = getLogger(name="red.SeaCogs.HotReload") self.observer = None + self.config.register_global(notify_channel=None) watchdog_loggers = [getLogger(name="watchdog.observers.inotify_buffer")] for watchdog_logger in watchdog_loggers: watchdog_logger.setLevel("INFO") # SHUT UP!!!! @@ -61,17 +63,29 @@ class HotReload(commands.Cog): self.observer = Observer() paths = await self.get_paths() for path in paths: - self.observer.schedule(event_handler=HotReloadHandler(bot=self.bot, path=path), path=path, recursive=True) + self.observer.schedule(event_handler=HotReloadHandler(cog=self, path=path), path=path, recursive=True) self.observer.start() self.logger.info("Started observer. Watching for file changes.") + @checks.is_owner() + @commands.group(name="hotreload") + async def hotreload_group(self, ctx: commands.Context) -> None: + """HotReload configuration commands.""" + pass + + @hotreload_group.command(name="notifychannel") + async def hotreload_notifychannel(self, ctx: commands.Context, channel: commands.TextChannelConverter) -> None: + """Set the channel to send notifications to.""" + await self.config.notify_channel.set(channel.id) + await ctx.send(f"Notifications will be sent to {channel.mention}.") + class HotReloadHandler(RegexMatchingEventHandler): """Handler for file changes.""" - def __init__(self, bot: Red, path: Path) -> None: + def __init__(self, cog: HotReload, path: Path) -> None: super().__init__(regexes=[r".*\.py$"]) - self.bot: Red = bot + self.cog: HotReload = cog self.path: Path = path self.logger: RedTraceLogger = getLogger(name="red.SeaCogs.HotReload.Observer") @@ -99,11 +113,15 @@ class HotReloadHandler(RegexMatchingEventHandler): self.logger.info("File %s has been %s%s.", event.src_path, event.event_type, dest) - run_coroutine_threadsafe(self.reload_cogs(cogs_to_reload), loop=self.bot.loop) + run_coroutine_threadsafe(self.reload_cogs(cogs_to_reload), loop=self.cog.bot.loop) async def reload_cogs(self, cog_names: Sequence[str]) -> None: """Reload modified cog.""" - core_logic = CoreLogic(bot=self.bot) + core_logic = CoreLogic(bot=self.cog.bot) self.logger.info("Reloading cogs: %s", humanize_list(cog_names, style="unit")) await core_logic._reload(pkg_names=cog_names) # noqa: SLF001 # We have to use this private method because there is no public API to reload other cogs self.logger.info("Reloaded cogs: %s", humanize_list(cog_names, style="unit")) + + channel = self.cog.bot.get_channel(await self.cog.config.notify_channel()) + if channel: + await channel.send(f"Reloaded cogs: {humanize_list(cog_names, style='unit')}") From b22d81f5146455b26de39c6dafbb9ee8c8bedb30 Mon Sep 17 00:00:00 2001 From: cswimr Date: Sun, 26 Jan 2025 15:18:05 +0000 Subject: [PATCH 26/53] feat(hotreload): handle multiple observers --- hotreload/hotreload.py | 40 ++++++++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/hotreload/hotreload.py b/hotreload/hotreload.py index 185c90d..dcc2d97 100644 --- a/hotreload/hotreload.py +++ b/hotreload/hotreload.py @@ -6,9 +6,9 @@ from red_commons.logging import RedTraceLogger, getLogger from redbot.core import Config, checks, commands from redbot.core.bot import Red from redbot.core.core_commands import CoreLogic -from redbot.core.utils.chat_formatting import bold, humanize_list +from redbot.core.utils.chat_formatting import bold, box, humanize_list from watchdog.events import FileSystemEvent, FileSystemMovedEvent, RegexMatchingEventHandler -from watchdog.observers import Observer +from watchdog.observers import Observer, ObserverType class HotReload(commands.Cog): @@ -16,7 +16,7 @@ class HotReload(commands.Cog): __author__ = ["[cswimr](https://www.coastalcommits.com/cswimr)"] __git__ = "https://www.coastalcommits.com/cswimr/SeaCogs" - __version__ = "1.2.0" + __version__ = "1.3.0" __documentation__ = "https://seacogs.coastalcommits.com/hotreload/" def __init__(self, bot: Red) -> None: @@ -24,7 +24,7 @@ class HotReload(commands.Cog): self.bot: Red = bot self.config = Config.get_conf(self, identifier=294518358420750336, force_registration=True) self.logger: RedTraceLogger = getLogger(name="red.SeaCogs.HotReload") - self.observer = None + self.observers: list[ObserverType] = [] self.config.register_global(notify_channel=None) watchdog_loggers = [getLogger(name="watchdog.observers.inotify_buffer")] for watchdog_logger in watchdog_loggers: @@ -36,9 +36,9 @@ class HotReload(commands.Cog): async def cog_unload(self) -> None: """Stop the observer when the cog is unloaded.""" - if self.observer: - self.observer.stop() - self.observer.join() + for observer in self.observers: + observer.stop() + observer.join() self.logger.info("Stopped observer. No longer watching for file changes.") def format_help_for_context(self, ctx: commands.Context) -> str: @@ -60,12 +60,20 @@ class HotReload(commands.Cog): async def start_observer(self) -> None: """Start the observer to watch for file changes.""" - self.observer = Observer() + self.observers.append(Observer()) paths = await self.get_paths() - for path in paths: - self.observer.schedule(event_handler=HotReloadHandler(cog=self, path=path), path=path, recursive=True) - self.observer.start() - self.logger.info("Started observer. Watching for file changes.") + is_first = True + for observer in self.observers: + if not is_first: + observer.stop() + observer.join() + self.logger.debug("Stopped hanging observer.") + continue + for path in paths: + observer.schedule(event_handler=HotReloadHandler(cog=self, path=path), path=path, recursive=True) + observer.start() + self.logger.info("Started observer. Watching for file changes.") + is_first = False @checks.is_owner() @commands.group(name="hotreload") @@ -79,6 +87,14 @@ class HotReload(commands.Cog): await self.config.notify_channel.set(channel.id) await ctx.send(f"Notifications will be sent to {channel.mention}.") + @hotreload_group.command(name="list") + async def hotreload_list(self, ctx: commands.Context) -> None: + """List the currently active observers.""" + if not self.observers: + await ctx.send("No observers are currently active.") + return + await ctx.send(f"Currently active observers (If there are more than one of these, report an issue): {box(humanize_list(self.observers, style='unit'))}") + class HotReloadHandler(RegexMatchingEventHandler): """Handler for file changes.""" From 1993da084d558adced2accfe75416bedbe8d44f1 Mon Sep 17 00:00:00 2001 From: cswimr Date: Sun, 26 Jan 2025 15:28:21 +0000 Subject: [PATCH 27/53] docs(hotreload): add docs --- .docs/hotreload.md | 22 ++++++++++++++++++++++ hotreload/info.json | 24 ++++++++++++++++-------- 2 files changed, 38 insertions(+), 8 deletions(-) create mode 100644 .docs/hotreload.md diff --git a/.docs/hotreload.md b/.docs/hotreload.md new file mode 100644 index 0000000..76f5c86 --- /dev/null +++ b/.docs/hotreload.md @@ -0,0 +1,22 @@ +# HotReload + +HotReload automatically reloads cogs in local cog paths on file change. +This is useful for development, as it allows you to make changes to your cogs and see the changes reflected in Discord immediately, without having to manually `[p]reload` the cog. + +## Installation + +```bash +[p]repo add seacogs https://www.coastalcommits.com/cswimr/SeaCogs +[p]cog install seacogs hotreload +[p]cog load hotreload +``` + +## Commands + +### hotreload notifychannel + +Set the channel where hotreload will send notifications when a cog is reloaded. + +### hotreload list + +Debugging command that shows the list of currently active observers. May be expanded in the future to show watched file paths. diff --git a/hotreload/info.json b/hotreload/info.json index 87dc851..5527eb1 100644 --- a/hotreload/info.json +++ b/hotreload/info.json @@ -1,15 +1,23 @@ { - "author" : ["cswimr"], - "install_msg" : "Thank you for installing HotReload! This cog does not provide any commands, please see the [documentation](https://seacogs.coastalcommits.com/hotreload) for more information.", - "name" : "HotReload", - "short" : "Automatically reload cogs in local cog paths on file change.", - "description" : "Automatically reload cogs in local cog paths on file change.", - "end_user_data_statement" : "This cog does not store end user data.", + "author": [ + "cswimr" + ], + "install_msg": "Thank you for installing HotReload! Please see the [documentation](https://seacogs.coastalcommits.com/hotreload) to get started.", + "name": "HotReload", + "short": "Automatically reload cogs in local cog paths on file change.", + "description": "Automatically reload cogs in local cog paths on file change.", + "end_user_data_statement": "This cog does not store end user data.", "hidden": false, "disabled": false, "min_bot_version": "3.5.0", - "min_python_version": [3, 10, 0], - "requirements": ["watchdog"], + "min_python_version": [ + 3, + 10, + 0 + ], + "requirements": [ + "watchdog" + ], "tags": [ "utility", "development" From 9e489a4c915f0d1b380a9b8782db0334f96cf705 Mon Sep 17 00:00:00 2001 From: cswimr Date: Sun, 26 Jan 2025 15:29:03 +0000 Subject: [PATCH 28/53] docs(hotreload): add docs --- mkdocs.yml | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/mkdocs.yml b/mkdocs.yml index 9d61aee..81ab9ed 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -1,8 +1,8 @@ site_name: SeaCogs Documentation -site_url: !ENV [SITE_URL, 'https://seacogs.coastalcommits.com'] +site_url: !ENV [SITE_URL, "https://seacogs.coastalcommits.com"] repo_name: CoastalCommits repo_url: https://coastalcommits.com/cswimr/SeaCogs -edit_uri: !ENV [EDIT_URI, 'src/branch/main/.docs'] +edit_uri: !ENV [EDIT_URI, "src/branch/main/.docs"] copyright: Copyright © 2023-2024, cswimr docs_dir: .docs @@ -12,20 +12,21 @@ site_description: Documentation for my Red-DiscordBot Cogs. nav: - Home: index.md - Aurora: - - aurora/index.md - - Moderation Commands: aurora/moderation-commands.md - - Case Commands: aurora/case-commands.md - - Configuration: aurora/configuration.md + - aurora/index.md + - Moderation Commands: aurora/moderation-commands.md + - Case Commands: aurora/case-commands.md + - Configuration: aurora/configuration.md - Bible: bible.md - Backup: backup.md - EmojiInfo: emojiinfo.md + - HotReload: hotreload.md - Nerdify: nerdify.md - Pterodactyl: - - pterodactyl/index.md - - Installing Red: pterodactyl/installing-red.md - - Getting Started: pterodactyl/getting-started.md - - Configuration: pterodactyl/configuration.md - - Regex Examples: pterodactyl/regex.md + - pterodactyl/index.md + - Installing Red: pterodactyl/installing-red.md + - Getting Started: pterodactyl/getting-started.md + - Configuration: pterodactyl/configuration.md + - Regex Examples: pterodactyl/regex.md plugins: - git-authors @@ -72,7 +73,7 @@ markdown_extensions: theme: name: material palette: - - media: '(prefers-color-scheme: light)' + - media: "(prefers-color-scheme: light)" scheme: default primary: white accent: light blue @@ -80,7 +81,7 @@ theme: icon: material/toggle-switch name: Switch to dark mode - - media: '(prefers-color-scheme: dark)' + - media: "(prefers-color-scheme: dark)" scheme: slate primary: black accent: light blue From 19eca0b1b53fa10e15ee311dd1c5302f5e148b79 Mon Sep 17 00:00:00 2001 From: cswimr Date: Sun, 26 Jan 2025 15:33:34 +0000 Subject: [PATCH 29/53] docs: fixed incorrect command instructions --- .docs/aurora/index.md | 2 +- .docs/backup.md | 2 +- .docs/bible.md | 10 ++++++---- .docs/emojiinfo.md | 2 +- .docs/hotreload.md | 2 +- .docs/nerdify.md | 2 +- .docs/pterodactyl/index.md | 2 +- 7 files changed, 12 insertions(+), 10 deletions(-) diff --git a/.docs/aurora/index.md b/.docs/aurora/index.md index 4c6f321..0191f85 100644 --- a/.docs/aurora/index.md +++ b/.docs/aurora/index.md @@ -12,5 +12,5 @@ Aurora is a fully-featured moderation system. It is heavily inspired by Galactic ```bash [p]repo add seacogs https://www.coastalcommits.com/cswimr/SeaCogs [p]cog install seacogs aurora -[p]cog load aurora +[p]load aurora ``` diff --git a/.docs/backup.md b/.docs/backup.md index 4ddc56f..26c949d 100644 --- a/.docs/backup.md +++ b/.docs/backup.md @@ -7,7 +7,7 @@ Backup allows you to export a JSON list of all of your installed repositories an ```bash [p]repo add seacogs https://www.coastalcommits.com/cswimr/SeaCogs [p]cog install seacogs backup -[p]cog load backup +[p]load backup ``` ## Version Compatibility diff --git a/.docs/bible.md b/.docs/bible.md index 188f985..0db826b 100644 --- a/.docs/bible.md +++ b/.docs/bible.md @@ -8,7 +8,7 @@ This cog does require an api key to work. ```bash [p]repo add seacogs https://www.coastalcommits.com/cswimr/SeaCogs [p]cog install seacogs bible -[p]cog load bible +[p]load bible ``` ## Setup @@ -21,8 +21,9 @@ Then, you can use `[p]set api` to set the API key. Make sure your formatting mat ## Commands ### bible passage - - Usage: `[p]bible passage ` - - Aliases: `verse` + +- Usage: `[p]bible passage ` +- Aliases: `verse` Get a Bible passage. @@ -31,6 +32,7 @@ Example usage: `[p]bible passage John 3:16-3:17` ### bible random - - Usage: `[p]bible random` + +- Usage: `[p]bible random` Get a random Bible verse. diff --git a/.docs/emojiinfo.md b/.docs/emojiinfo.md index ef63ab6..fc010a5 100644 --- a/.docs/emojiinfo.md +++ b/.docs/emojiinfo.md @@ -7,7 +7,7 @@ EmojiInfo allows you to retrieve information about an emoji. ```bash [p]repo add seacogs https://www.coastalcommits.com/cswimr/SeaCogs [p]cog install seacogs emojiinfo -[p]cog load emojiinfo +[p]load emojiinfo ``` ## Commands diff --git a/.docs/hotreload.md b/.docs/hotreload.md index 76f5c86..e2d4cb3 100644 --- a/.docs/hotreload.md +++ b/.docs/hotreload.md @@ -8,7 +8,7 @@ This is useful for development, as it allows you to make changes to your cogs an ```bash [p]repo add seacogs https://www.coastalcommits.com/cswimr/SeaCogs [p]cog install seacogs hotreload -[p]cog load hotreload +[p]load hotreload ``` ## Commands diff --git a/.docs/nerdify.md b/.docs/nerdify.md index 87662b6..ceef1af 100644 --- a/.docs/nerdify.md +++ b/.docs/nerdify.md @@ -7,7 +7,7 @@ Nerdify allows you to nerdify other people's text. ```bash [p]repo add seacogs https://www.coastalcommits.com/cswimr/SeaCogs [p]cog install seacogs nerdify -[p]cog load nerdify +[p]load nerdify ``` ## Commands diff --git a/.docs/pterodactyl/index.md b/.docs/pterodactyl/index.md index cb69a5d..732b505 100644 --- a/.docs/pterodactyl/index.md +++ b/.docs/pterodactyl/index.md @@ -12,5 +12,5 @@ Pterodactyl allows for connecting to a Pterodactyl server through websockets. It ```bash [p]repo add seacogs https://www.coastalcommits.com/cswimr/SeaCogs [p]cog install seacogs pterodactyl -[p]cog load aurora +[p]load pterodactyl ``` From 76f0a4cdd41e14e92a615c6bead105b2e1e33c7c Mon Sep 17 00:00:00 2001 From: cswimr Date: Sun, 26 Jan 2025 21:09:38 +0000 Subject: [PATCH 30/53] chore(hotreload): support python 3.8+ instead of 3.10+ --- hotreload/info.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hotreload/info.json b/hotreload/info.json index 5527eb1..6028830 100644 --- a/hotreload/info.json +++ b/hotreload/info.json @@ -12,7 +12,7 @@ "min_bot_version": "3.5.0", "min_python_version": [ 3, - 10, + 8, 0 ], "requirements": [ From 70d75c688cc4d9bf65a753182e167bd4591ed93c Mon Sep 17 00:00:00 2001 From: cswimr Date: Sun, 26 Jan 2025 21:23:08 +0000 Subject: [PATCH 31/53] fix(hotreload): only import ObserverType for TYPE_CHECKING --- hotreload/hotreload.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/hotreload/hotreload.py b/hotreload/hotreload.py index dcc2d97..67b7145 100644 --- a/hotreload/hotreload.py +++ b/hotreload/hotreload.py @@ -1,6 +1,6 @@ from asyncio import run_coroutine_threadsafe from pathlib import Path -from typing import Sequence +from typing import TYPE_CHECKING, Sequence from red_commons.logging import RedTraceLogger, getLogger from redbot.core import Config, checks, commands @@ -8,7 +8,10 @@ from redbot.core.bot import Red from redbot.core.core_commands import CoreLogic from redbot.core.utils.chat_formatting import bold, box, humanize_list from watchdog.events import FileSystemEvent, FileSystemMovedEvent, RegexMatchingEventHandler -from watchdog.observers import Observer, ObserverType +from watchdog.observers import Observer + +if TYPE_CHECKING: + from watchdog.observers import ObserverType class HotReload(commands.Cog): @@ -16,7 +19,7 @@ class HotReload(commands.Cog): __author__ = ["[cswimr](https://www.coastalcommits.com/cswimr)"] __git__ = "https://www.coastalcommits.com/cswimr/SeaCogs" - __version__ = "1.3.0" + __version__ = "1.3.1" __documentation__ = "https://seacogs.coastalcommits.com/hotreload/" def __init__(self, bot: Red) -> None: From 5c6783452d4aded258b629181817e89f8cf839f9 Mon Sep 17 00:00:00 2001 From: cswimr Date: Sun, 26 Jan 2025 21:29:02 +0000 Subject: [PATCH 32/53] fix(hotreload): verify that a file path exists before creating an observer schedule for it --- hotreload/hotreload.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/hotreload/hotreload.py b/hotreload/hotreload.py index 67b7145..34a5073 100644 --- a/hotreload/hotreload.py +++ b/hotreload/hotreload.py @@ -19,7 +19,7 @@ class HotReload(commands.Cog): __author__ = ["[cswimr](https://www.coastalcommits.com/cswimr)"] __git__ = "https://www.coastalcommits.com/cswimr/SeaCogs" - __version__ = "1.3.1" + __version__ = "1.3.2" __documentation__ = "https://seacogs.coastalcommits.com/hotreload/" def __init__(self, bot: Red) -> None: @@ -73,6 +73,10 @@ class HotReload(commands.Cog): self.logger.debug("Stopped hanging observer.") continue for path in paths: + if not path.exists(): + self.logger.warning("Path %s does not exist. Skipping.", path) + continue + self.logger.debug("Adding observer schedule for path %s.", path) observer.schedule(event_handler=HotReloadHandler(cog=self, path=path), path=path, recursive=True) observer.start() self.logger.info("Started observer. Watching for file changes.") From 289da84b765e1378e17998ade6bb220fd7d5e5c8 Mon Sep 17 00:00:00 2001 From: cswimr Date: Sun, 26 Jan 2025 21:31:48 +0000 Subject: [PATCH 33/53] fix(hotreload): use 3.8-compatible typehints --- hotreload/hotreload.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/hotreload/hotreload.py b/hotreload/hotreload.py index 34a5073..9357fcd 100644 --- a/hotreload/hotreload.py +++ b/hotreload/hotreload.py @@ -1,6 +1,6 @@ from asyncio import run_coroutine_threadsafe from pathlib import Path -from typing import TYPE_CHECKING, Sequence +from typing import TYPE_CHECKING, List, Sequence, Tuple from red_commons.logging import RedTraceLogger, getLogger from redbot.core import Config, checks, commands @@ -19,7 +19,7 @@ class HotReload(commands.Cog): __author__ = ["[cswimr](https://www.coastalcommits.com/cswimr)"] __git__ = "https://www.coastalcommits.com/cswimr/SeaCogs" - __version__ = "1.3.2" + __version__ = "1.3.3" __documentation__ = "https://seacogs.coastalcommits.com/hotreload/" def __init__(self, bot: Red) -> None: @@ -27,7 +27,7 @@ class HotReload(commands.Cog): self.bot: Red = bot self.config = Config.get_conf(self, identifier=294518358420750336, force_registration=True) self.logger: RedTraceLogger = getLogger(name="red.SeaCogs.HotReload") - self.observers: list[ObserverType] = [] + self.observers: List[ObserverType] = [] self.config.register_global(notify_channel=None) watchdog_loggers = [getLogger(name="watchdog.observers.inotify_buffer")] for watchdog_logger in watchdog_loggers: @@ -55,7 +55,7 @@ class HotReload(commands.Cog): ] return "\n".join(text) - async def get_paths(self) -> tuple[Path]: + async def get_paths(self) -> Tuple[Path]: """Retrieve user defined paths.""" cog_manager = self.bot._cog_mgr # noqa: SLF001 # We have to use this private method because there is no public API to get user defined paths cog_paths = await cog_manager.user_defined_paths() From 666efaf8937bf9bf5a79db47edc7388a08de925c Mon Sep 17 00:00:00 2001 From: cswimr Date: Sun, 26 Jan 2025 22:27:22 +0000 Subject: [PATCH 34/53] chore(devcontainer): add DiD, forgejo runner, aliases --- .devcontainer/Dockerfile | 3 +++ .devcontainer/devcontainer.json | 7 ++++++- .devcontainer/home/.bash_aliases | 3 +++ 3 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 .devcontainer/home/.bash_aliases diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index c08c396..a14eb43 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,5 +1,6 @@ FROM ghcr.io/astral-sh/uv:0.5.24@sha256:2381d6aa60c326b71fd40023f921a0a3b8f91b14d5db6b90402e65a635053709 AS uv FROM python:3.11-slim@sha256:6ed5bff4d7d377e2a27d9285553b8c21cfccc4f00881de1b24c9bc8d90016e82 AS python +FROM code.forgejo.org/forgejo/runner:6.2.0 AS forgejo-runner FROM mcr.microsoft.com/vscode/devcontainers/base:bookworm@sha256:6155a486f236fd5127b76af33086029d64f64cf49dd504accb6e5f949098eb7e LABEL repository="www.coastalcommits.com/cswimr/SeaCogs" @@ -29,6 +30,8 @@ RUN apt-get update; \ COPY --from=uv --chown=vscode: /uv /uvx /bin/ COPY --from=python --chown=vscode: /usr/local /usr/local +COPY --from=forgejo-runner --chown=vscode: /bin/forgejo-runner /bin/forgejo-runner +COPY --chown=vscode: .devcontainer/home/* /home/vscode/ RUN ln -s /usr/local/bin/python3.11 /usr/local/bin/python; \ python --version; \ diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 06e81b7..e53bf4c 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -4,6 +4,9 @@ "context": "..", "dockerfile": "Dockerfile" }, + "features": { + "ghcr.io/devcontainers/features/docker-in-docker:2": {} + }, "customizations": { "vscode": { "extensions": [ @@ -29,7 +32,9 @@ "UV_PYTHON_DOWNLOADS": "never", "PROJECT_DIR": "/workspaces/SeaCogs" }, - "mounts": ["source=seacogs-persistent-data,target=/workspaces/SeaCogs/.data,type=volume"], + "mounts": [ + "source=seacogs-persistent-data,target=/workspaces/SeaCogs/.data,type=volume" + ], "postCreateCommand": "uv sync --frozen && sudo chown -R vscode:vscode /workspaces/SeaCogs/.data && uv run redbot-setup --no-prompt --instance-name=local --data-path=/workspaces/SeaCogs/.data --backend=json", "remoteUser": "vscode" } diff --git a/.devcontainer/home/.bash_aliases b/.devcontainer/home/.bash_aliases new file mode 100644 index 0000000..277fc5f --- /dev/null +++ b/.devcontainer/home/.bash_aliases @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +alias runactions="forgejo-runner exec --default-actions-url=https://www.coastalcommits.com --gitea-instance=https://www.coastalcommits.com" From 1ca452669cfeb676e970d5166718fab0156162a6 Mon Sep 17 00:00:00 2001 From: Renovate Date: Sun, 26 Jan 2025 17:36:59 -0500 Subject: [PATCH 35/53] chore(deps): pin code.forgejo.org/forgejo/runner docker tag to 936c4fe (#52) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [code.forgejo.org/forgejo/runner](https://forgejo.org) ([source](https://code.forgejo.org/forgejo/runner)) | stage | pinDigest | -> `936c4fe` | --- > ⚠️ **Warning** > > Some dependencies could not be looked up. Check the Dependency Dashboard for more information. --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). Reviewed-on: https://www.coastalcommits.com/cswimr/SeaCogs/pulls/52 Co-authored-by: Renovate Co-committed-by: Renovate --- .devcontainer/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index a14eb43..87d9dbe 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,6 +1,6 @@ FROM ghcr.io/astral-sh/uv:0.5.24@sha256:2381d6aa60c326b71fd40023f921a0a3b8f91b14d5db6b90402e65a635053709 AS uv FROM python:3.11-slim@sha256:6ed5bff4d7d377e2a27d9285553b8c21cfccc4f00881de1b24c9bc8d90016e82 AS python -FROM code.forgejo.org/forgejo/runner:6.2.0 AS forgejo-runner +FROM code.forgejo.org/forgejo/runner:6.2.0@sha256:936c4fef04f0e2bda86c325b8ef40359aeead4740a48b1d5a0c9a112f1185e45 AS forgejo-runner FROM mcr.microsoft.com/vscode/devcontainers/base:bookworm@sha256:6155a486f236fd5127b76af33086029d64f64cf49dd504accb6e5f949098eb7e LABEL repository="www.coastalcommits.com/cswimr/SeaCogs" From 7c2ff7681cffe0a43c94710c0bb4fd5991033475 Mon Sep 17 00:00:00 2001 From: Renovate Date: Wed, 29 Jan 2025 13:39:57 -0500 Subject: [PATCH 36/53] chore(deps): update code.forgejo.org/forgejo/runner docker tag to v6.2.1 (#56) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [code.forgejo.org/forgejo/runner](https://forgejo.org) ([source](https://code.forgejo.org/forgejo/runner)) | stage | patch | `6.2.0` -> `6.2.1` | --- > ⚠️ **Warning** > > Some dependencies could not be looked up. Check the Dependency Dashboard for more information. --- ### Release Notes
forgejo/runner (code.forgejo.org/forgejo/runner) ### [`v6.2.1`](https://code.forgejo.org/forgejo/runner/blob/HEAD/RELEASE-NOTES.md#621) [Compare Source](https://code.forgejo.org/forgejo/runner/compare/v6.2.0...v6.2.1) - LXC [templates are updated if needed](https://code.forgejo.org/forgejo/act/pulls/102).
--- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). Reviewed-on: https://www.coastalcommits.com/cswimr/SeaCogs/pulls/56 Co-authored-by: Renovate Co-committed-by: Renovate --- .devcontainer/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 87d9dbe..2e79139 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,6 +1,6 @@ FROM ghcr.io/astral-sh/uv:0.5.24@sha256:2381d6aa60c326b71fd40023f921a0a3b8f91b14d5db6b90402e65a635053709 AS uv FROM python:3.11-slim@sha256:6ed5bff4d7d377e2a27d9285553b8c21cfccc4f00881de1b24c9bc8d90016e82 AS python -FROM code.forgejo.org/forgejo/runner:6.2.0@sha256:936c4fef04f0e2bda86c325b8ef40359aeead4740a48b1d5a0c9a112f1185e45 AS forgejo-runner +FROM code.forgejo.org/forgejo/runner:6.2.1@sha256:fecc96a111a15811a6887ce488e75718089f24599e613e93db8e54fe70b706e8 AS forgejo-runner FROM mcr.microsoft.com/vscode/devcontainers/base:bookworm@sha256:6155a486f236fd5127b76af33086029d64f64cf49dd504accb6e5f949098eb7e LABEL repository="www.coastalcommits.com/cswimr/SeaCogs" From 3eeb2f90a65c97f6cb186f51427d58447d577675 Mon Sep 17 00:00:00 2001 From: cswimr Date: Wed, 29 Jan 2025 23:24:19 +0000 Subject: [PATCH 37/53] feat(hotreload): add pre-compilation this feature will detect syntax errors before reloading a cog and cancel the cog reload if it detects one. DOES NOT detect runtime/logic errors, only syntax errors. --- .docs/hotreload.md | 4 ++++ hotreload/hotreload.py | 48 +++++++++++++++++++++++++++++++++++++----- 2 files changed, 47 insertions(+), 5 deletions(-) diff --git a/.docs/hotreload.md b/.docs/hotreload.md index e2d4cb3..0144e5d 100644 --- a/.docs/hotreload.md +++ b/.docs/hotreload.md @@ -13,6 +13,10 @@ This is useful for development, as it allows you to make changes to your cogs an ## Commands +### hotreload compile + +Determines if the cog should try to compile a modified Python file before reloading the associated cog. Useful for catching syntax errors. Disabled by default. + ### hotreload notifychannel Set the channel where hotreload will send notifications when a cog is reloaded. diff --git a/hotreload/hotreload.py b/hotreload/hotreload.py index 9357fcd..ee223f2 100644 --- a/hotreload/hotreload.py +++ b/hotreload/hotreload.py @@ -1,5 +1,7 @@ +import py_compile from asyncio import run_coroutine_threadsafe from pathlib import Path +from tempfile import NamedTemporaryFile from typing import TYPE_CHECKING, List, Sequence, Tuple from red_commons.logging import RedTraceLogger, getLogger @@ -19,7 +21,7 @@ class HotReload(commands.Cog): __author__ = ["[cswimr](https://www.coastalcommits.com/cswimr)"] __git__ = "https://www.coastalcommits.com/cswimr/SeaCogs" - __version__ = "1.3.3" + __version__ = "1.4.0" __documentation__ = "https://seacogs.coastalcommits.com/hotreload/" def __init__(self, bot: Red) -> None: @@ -28,7 +30,7 @@ class HotReload(commands.Cog): self.config = Config.get_conf(self, identifier=294518358420750336, force_registration=True) self.logger: RedTraceLogger = getLogger(name="red.SeaCogs.HotReload") self.observers: List[ObserverType] = [] - self.config.register_global(notify_channel=None) + self.config.register_global(notify_channel=None, compile_before_reload=False) watchdog_loggers = [getLogger(name="watchdog.observers.inotify_buffer")] for watchdog_logger in watchdog_loggers: watchdog_logger.setLevel("INFO") # SHUT UP!!!! @@ -94,6 +96,12 @@ class HotReload(commands.Cog): await self.config.notify_channel.set(channel.id) await ctx.send(f"Notifications will be sent to {channel.mention}.") + @hotreload_group.command(name="compile") + async def hotreload_compile(self, ctx: commands.Context, compile_before_reload: bool) -> None: + """Set whether to compile modified files before reloading.""" + await self.config.compile_before_reload.set(compile_before_reload) + await ctx.send(f"I {'will' if compile_before_reload else 'will not'} compile modified files before hotreloading cogs.") + @hotreload_group.command(name="list") async def hotreload_list(self, ctx: commands.Context) -> None: """List the currently active observers.""" @@ -136,10 +144,19 @@ class HotReloadHandler(RegexMatchingEventHandler): self.logger.info("File %s has been %s%s.", event.src_path, event.event_type, dest) - run_coroutine_threadsafe(self.reload_cogs(cogs_to_reload), loop=self.cog.bot.loop) + run_coroutine_threadsafe( + coro=self.reload_cogs( + cog_names=cogs_to_reload, + paths=[Path(p) for p in (event.src_path, getattr(event, "dest_path", None)) if p], + ), + loop=self.cog.bot.loop, + ) + + async def reload_cogs(self, cog_names: Sequence[str], paths: Sequence[Path]) -> None: + """Reload modified cogs.""" + if not self.compile_modified_files(cog_names, paths): + return - async def reload_cogs(self, cog_names: Sequence[str]) -> None: - """Reload modified cog.""" core_logic = CoreLogic(bot=self.cog.bot) self.logger.info("Reloading cogs: %s", humanize_list(cog_names, style="unit")) await core_logic._reload(pkg_names=cog_names) # noqa: SLF001 # We have to use this private method because there is no public API to reload other cogs @@ -148,3 +165,24 @@ class HotReloadHandler(RegexMatchingEventHandler): channel = self.cog.bot.get_channel(await self.cog.config.notify_channel()) if channel: await channel.send(f"Reloaded cogs: {humanize_list(cog_names, style='unit')}") + + def compile_modified_files(self, cog_names: Sequence[str], paths: Sequence[Path]) -> bool: + """Compile modified files to ensure they are valid Python files.""" + for path in paths: + if not path.exists() or path.suffix != ".py": + self.logger.debug("Path %s does not exist or does not point to a Python file. Skipping compilation step.", path) + continue + + try: + with NamedTemporaryFile() as temp_file: + self.logger.debug("Attempting to compile %s", path) + py_compile.compile(file=path, cfile=temp_file.name, doraise=True) + self.logger.debug("Successfully compiled %s", path) + + except py_compile.PyCompileError as e: + e.__suppress_context__ = True + self.logger.exception("%s failed to compile. Not reloading cogs %s.", path, humanize_list(cog_names, style="unit")) + return False + except OSError: + self.logger.exception("Failed to create tempfile for compilation step. Skipping.") + return True From 89d5108ef263efe619fa961957002726e7003b58 Mon Sep 17 00:00:00 2001 From: cswimr Date: Wed, 29 Jan 2025 23:34:52 +0000 Subject: [PATCH 38/53] chore(repo): update pull request template --- .forgejo/pull_request_template.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.forgejo/pull_request_template.md b/.forgejo/pull_request_template.md index efe146e..33f957c 100644 --- a/.forgejo/pull_request_template.md +++ b/.forgejo/pull_request_template.md @@ -2,5 +2,5 @@ -- [ ] By submitting this pull request, I permit cswimr to license my work under +- [ ] By submitting this pull request, I permit [cswimr](https://www.coastalcommits.com/cswimr) to license my work under the [Mozilla Public License Version 2.0](https://www.coastalcommits.com/cswimr/SeaCogs/src/branch/main/LICENSE). From 034748b08e79a18175bbb28f706517cb3d32272a Mon Sep 17 00:00:00 2001 From: cswimr Date: Sat, 1 Feb 2025 16:56:34 +0000 Subject: [PATCH 39/53] chore(deps): update dependencies --- pyproject.toml | 28 ++++++++++++++-------------- uv.lock | 48 ++++++++++++++++++++++++------------------------ 2 files changed, 38 insertions(+), 38 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 94aa6c5..f5010a5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -10,30 +10,30 @@ dependencies = [ "aiosqlite>=0.20.0", "beautifulsoup4>=4.12.3", "colorthief>=0.2.1", - "markdownify>=0.13.1", - "numpy>=2.1.2", - "phx-class-registry>=5.0.0", + "markdownify>=0.14.1", + "numpy>=2.2.2", + "phx-class-registry>=5.1.1", "pillow>=10.4.0", - "pip>=24.3.1", + "pip>=25.0", "py-dactyl", - "pydantic>=2.9.2", + "pydantic>=2.10.6", "red-discordbot>=3.5.14", - "watchdog>=5.0.3", - "websockets>=13.1", + "watchdog>=6.0.0", + "websockets>=14.2", ] -[project.optional-dependencies] +[dependency-groups] documentation = [ "mkdocs>=1.6.1", - "mkdocs-git-authors-plugin>=0.9.0", - "mkdocs-git-revision-date-localized-plugin>=1.2.9", - "mkdocs-material[imaging]>=9.5.40", - "mkdocstrings[python]>=0.26.1", - "mkdocs-redirects>=1.2.1", + "mkdocs-git-authors-plugin>=0.9.2", + "mkdocs-git-revision-date-localized-plugin>=1.3.0", + "mkdocs-material[imaging]>=9.5.50", + "mkdocs-redirects>=1.2.2", + "mkdocstrings[python]>=0.27.0", ] [tool.uv] -dev-dependencies = ["pylint>=3.3.1", "ruff>=0.6.9", "sqlite-web>=0.6.4"] +dev-dependencies = ["pylint>=3.3.3", "ruff>=0.9.3", "sqlite-web>=0.6.4"] [tool.uv.sources] py-dactyl = { git = "https://github.com/cswimr/pydactyl" } diff --git a/uv.lock b/uv.lock index 28ccf8f..e2ad6a7 100644 --- a/uv.lock +++ b/uv.lock @@ -591,7 +591,7 @@ name = "importlib-metadata" version = "8.5.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "zipp" }, + { name = "zipp", marker = "python_full_version >= '3.12'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/cd/12/33e59336dca5be0c398a7482335911a33aa0e20776128f038019f1a95f1b/importlib_metadata-8.5.0.tar.gz", hash = "sha256:71522656f0abace1d072b9e5481a48f07c138e00f079c38c8f883823f9c26bd7", size = 55304 } wheels = [ @@ -1672,7 +1672,12 @@ dependencies = [ { name = "websockets" }, ] -[package.optional-dependencies] +[package.dev-dependencies] +dev = [ + { name = "pylint" }, + { name = "ruff" }, + { name = "sqlite-web" }, +] documentation = [ { name = "mkdocs" }, { name = "mkdocs-git-authors-plugin" }, @@ -1682,42 +1687,37 @@ documentation = [ { name = "mkdocstrings", extra = ["python"] }, ] -[package.dev-dependencies] -dev = [ - { name = "pylint" }, - { name = "ruff" }, - { name = "sqlite-web" }, -] - [package.metadata] requires-dist = [ { name = "aiosqlite", specifier = ">=0.20.0" }, { name = "beautifulsoup4", specifier = ">=4.12.3" }, { name = "colorthief", specifier = ">=0.2.1" }, - { name = "markdownify", specifier = ">=0.13.1" }, - { name = "mkdocs", marker = "extra == 'documentation'", specifier = ">=1.6.1" }, - { name = "mkdocs-git-authors-plugin", marker = "extra == 'documentation'", specifier = ">=0.9.0" }, - { name = "mkdocs-git-revision-date-localized-plugin", marker = "extra == 'documentation'", specifier = ">=1.2.9" }, - { name = "mkdocs-material", extras = ["imaging"], marker = "extra == 'documentation'", specifier = ">=9.5.40" }, - { name = "mkdocs-redirects", marker = "extra == 'documentation'", specifier = ">=1.2.1" }, - { name = "mkdocstrings", extras = ["python"], marker = "extra == 'documentation'", specifier = ">=0.26.1" }, - { name = "numpy", specifier = ">=2.1.2" }, - { name = "phx-class-registry", specifier = ">=5.0.0" }, + { name = "markdownify", specifier = ">=0.14.1" }, + { name = "numpy", specifier = ">=2.2.2" }, + { name = "phx-class-registry", specifier = ">=5.1.1" }, { name = "pillow", specifier = ">=10.4.0" }, - { name = "pip", specifier = ">=24.3.1" }, + { name = "pip", specifier = ">=25.0" }, { name = "py-dactyl", git = "https://github.com/cswimr/pydactyl" }, - { name = "pydantic", specifier = ">=2.9.2" }, + { name = "pydantic", specifier = ">=2.10.6" }, { name = "red-discordbot", specifier = ">=3.5.14" }, - { name = "watchdog", specifier = ">=5.0.3" }, - { name = "websockets", specifier = ">=13.1" }, + { name = "watchdog", specifier = ">=6.0.0" }, + { name = "websockets", specifier = ">=14.2" }, ] [package.metadata.requires-dev] dev = [ - { name = "pylint", specifier = ">=3.3.1" }, - { name = "ruff", specifier = ">=0.6.9" }, + { name = "pylint", specifier = ">=3.3.3" }, + { name = "ruff", specifier = ">=0.9.3" }, { name = "sqlite-web", specifier = ">=0.6.4" }, ] +documentation = [ + { name = "mkdocs", specifier = ">=1.6.1" }, + { name = "mkdocs-git-authors-plugin", specifier = ">=0.9.2" }, + { name = "mkdocs-git-revision-date-localized-plugin", specifier = ">=1.3.0" }, + { name = "mkdocs-material", extras = ["imaging"], specifier = ">=9.5.50" }, + { name = "mkdocs-redirects", specifier = ">=1.2.2" }, + { name = "mkdocstrings", extras = ["python"], specifier = ">=0.27.0" }, +] [[package]] name = "six" From ea0b7937f8482afcd3820c494c191fedc13716ac Mon Sep 17 00:00:00 2001 From: cswimr Date: Sat, 1 Feb 2025 16:56:49 +0000 Subject: [PATCH 40/53] chore(tooling): switch to zsh in the dev shell --- .devcontainer/devcontainer.json | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index e53bf4c..9bf34c9 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -9,6 +9,16 @@ }, "customizations": { "vscode": { + "settings": { + "python.terminal.activateEnvInCurrentTerminal": true, + "python.terminal.activateEnvironment": true, + "terminal.integrated.defaultProfile.linux": "zsh", + "terminal.integrated.profiles.linux": { + "zsh": { + "path": "/bin/zsh" + } + } + }, "extensions": [ "charliermarsh.ruff", "ms-azuretools.vscode-docker", @@ -35,6 +45,8 @@ "mounts": [ "source=seacogs-persistent-data,target=/workspaces/SeaCogs/.data,type=volume" ], - "postCreateCommand": "uv sync --frozen && sudo chown -R vscode:vscode /workspaces/SeaCogs/.data && uv run redbot-setup --no-prompt --instance-name=local --data-path=/workspaces/SeaCogs/.data --backend=json", + "postCreateCommand": { + "Setup Virtual Environment": "uv sync --frozen && sudo chown -R vscode:vscode /workspaces/SeaCogs/.data && uv run redbot-setup --no-prompt --instance-name=local --data-path=/workspaces/SeaCogs/.data --backend=json" + }, "remoteUser": "vscode" } From 2a5b924409143e1a87b75d7a337ce36053bea234 Mon Sep 17 00:00:00 2001 From: cswimr Date: Sat, 1 Feb 2025 16:57:45 +0000 Subject: [PATCH 41/53] feat(repo): make all cogs pylance-typechecking compliant at `basic` level, does not include Aurora as it's being rewritten in the `aurora/v3` branch --- .vscode/settings.json | 15 ++++- antipolls/antipolls.py | 19 +++++-- backup/backup.py | 13 +++-- bible/bible.py | 15 ++--- emojiinfo/emojiinfo.py | 28 ++++------ emojiinfo/model.py | 2 +- hotreload/hotreload.py | 41 +++++++------- nerdify/nerdify.py | 19 +++++-- pterodactyl/pterodactyl.py | 110 +++++++++++++++++++------------------ pterodactyl/websocket.py | 47 +++++++++------- seautils/seautils.py | 14 ++--- 11 files changed, 184 insertions(+), 139 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 9b76a06..68a52a5 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -11,11 +11,22 @@ "[jsonc]": { "editor.defaultFormatter": "vscode.json-language-features" }, - "editor.formatOnSave": true, "files.exclude": { "**/.git": true, "**/__pycache__": true, "**/.ruff_cache": true, "**/.mypy_cache": true - } + }, + "python.analysis.diagnosticSeverityOverrides": { + "reportAttributeAccessIssue": false, // disabled because `commands.group.command` is listed as Any / Unknown for some reason + "reportCallIssue": "information" + }, + "python.analysis.diagnosticMode": "workspace", + "python.analysis.supportDocstringTemplate": true, + "python.analysis.typeCheckingMode": "basic", + "python.analysis.typeEvaluation.enableReachabilityAnalysis": true, + "python.analysis.typeEvaluation.strictDictionaryInference": true, + "python.analysis.typeEvaluation.strictListInference": true, + "python.analysis.typeEvaluation.strictSetInference": true, + "editor.formatOnSave": true, } diff --git a/antipolls/antipolls.py b/antipolls/antipolls.py index b721d08..6f6dac6 100644 --- a/antipolls/antipolls.py +++ b/antipolls/antipolls.py @@ -17,7 +17,7 @@ class AntiPolls(commands.Cog): __author__ = ["[cswimr](https://www.coastalcommits.com/cswimr)"] __git__ = "https://www.coastalcommits.com/cswimr/SeaCogs" - __version__ = "1.0.2" + __version__ = "1.0.3" __documentation__ = "https://seacogs.coastalcommits.com/antipolls/" def __init__(self, bot: Red): @@ -82,7 +82,7 @@ class AntiPolls(commands.Cog): return self.logger.trace("Deleted poll message %s", message.id) return self.logger.verbose("Message %s is not a poll, ignoring", message.id) - @commands.group(name="antipolls", aliases=["ap"]) + @commands.group(name="antipolls", aliases=["ap"]) # type: ignore @commands.guild_only() @commands.admin_or_permissions(manage_guild=True) async def antipolls(self, ctx: commands.Context) -> None: @@ -95,6 +95,8 @@ class AntiPolls(commands.Cog): @antipolls_roles.command(name="add") async def antipolls_roles_add(self, ctx: commands.Context, *roles: discord.Role) -> None: """Add roles to the whitelist.""" + assert ctx.guild is not None # using `assert` here and in the rest of this file to satisfy typecheckers + # this is safe because the commands are part of a guild-only command group async with self.config.guild(ctx.guild).role_whitelist() as role_whitelist: role_whitelist: list failed: list[discord.Role] = [] @@ -110,6 +112,7 @@ class AntiPolls(commands.Cog): @antipolls_roles.command(name="remove") async def antipolls_roles_remove(self, ctx: commands.Context, *roles: discord.Role) -> None: """Remove roles from the whitelist.""" + assert ctx.guild is not None async with self.config.guild(ctx.guild).role_whitelist() as role_whitelist: role_whitelist: list failed: list[discord.Role] = [] @@ -125,10 +128,11 @@ class AntiPolls(commands.Cog): @antipolls_roles.command(name="list") async def antipolls_roles_list(self, ctx: commands.Context) -> discord.Message: """List roles in the whitelist.""" + assert ctx.guild is not None role_whitelist = await self.config.guild(ctx.guild).role_whitelist() if not role_whitelist: return await ctx.send("No roles in the whitelist.") - roles = [ctx.guild.get_role(role) for role in role_whitelist] + roles = [role for role in (ctx.guild.get_role(role) for role in role_whitelist) if role is not None] return await ctx.send(humanize_list([role.mention for role in roles])) @antipolls.group(name="channels") @@ -138,6 +142,7 @@ class AntiPolls(commands.Cog): @antipolls_channels.command(name="add") async def antipolls_channels_add(self, ctx: commands.Context, *channels: discord.TextChannel) -> None: """Add channels to the whitelist.""" + assert ctx.guild is not None async with self.config.guild(ctx.guild).channel_whitelist() as channel_whitelist: channel_whitelist: list failed: list[discord.TextChannel] = [] @@ -153,6 +158,7 @@ class AntiPolls(commands.Cog): @antipolls_channels.command(name="remove") async def antipolls_channels_remove(self, ctx: commands.Context, *channels: discord.TextChannel) -> None: """Remove channels from the whitelist.""" + assert ctx.guild is not None async with self.config.guild(ctx.guild).channel_whitelist() as channel_whitelist: channel_whitelist: list failed: list[discord.TextChannel] = [] @@ -168,14 +174,19 @@ class AntiPolls(commands.Cog): @antipolls_channels.command(name="list") async def antipolls_channels_list(self, ctx: commands.Context) -> discord.Message: """List channels in the whitelist.""" + assert ctx.guild is not None channel_whitelist = await self.config.guild(ctx.guild).channel_whitelist() if not channel_whitelist: return await ctx.send("No channels in the whitelist.") - channels = [ctx.guild.get_channel(channel) for channel in channel_whitelist] + channels = [channel for channel in (ctx.guild.get_channel(channel) for channel in channel_whitelist) if channel is not None] + for c in channels: + if not c: + channels.remove(c) return await ctx.send(humanize_list([channel.mention for channel in channels])) @antipolls.command(name="managemessages") async def antipolls_managemessages(self, ctx: commands.Context, enabled: bool) -> None: """Toggle Manage Messages permission check.""" + assert ctx.guild is not None await self.config.guild(ctx.guild).manage_messages.set(enabled) await ctx.tick() diff --git a/backup/backup.py b/backup/backup.py index 66928bd..803e863 100644 --- a/backup/backup.py +++ b/backup/backup.py @@ -26,7 +26,7 @@ class Backup(commands.Cog): __author__ = ["[cswimr](https://www.coastalcommits.com/cswimr)"] __git__ = "https://www.coastalcommits.com/cswimr/SeaCogs" - __version__ = "1.1.2" + __version__ = "1.1.3" __documentation__ = "https://seacogs.coastalcommits.com/backup/" def __init__(self, bot: Red): @@ -45,14 +45,15 @@ class Backup(commands.Cog): ] return "\n".join(text) - @commands.group(autohelp=True) + @commands.group(autohelp=True) # type: ignore @commands.is_owner() - async def backup(self, ctx: commands.Context): + async def backup(self, ctx: commands.Context) -> None: """Backup your installed cogs.""" + pass @backup.command(name="export") @commands.is_owner() - async def backup_export(self, ctx: commands.Context): + async def backup_export(self, ctx: commands.Context) -> None: """Export your installed repositories and cogs to a file.""" downloader = ctx.bot.get_cog("Downloader") if downloader is None: @@ -91,13 +92,13 @@ class Backup(commands.Cog): @backup.command(name="import") @commands.is_owner() - async def backup_import(self, ctx: commands.Context): + async def backup_import(self, ctx: commands.Context) -> None: """Import your installed repositories and cogs from an export file.""" try: export = json.loads(await ctx.message.attachments[0].read()) except (json.JSONDecodeError, IndexError): try: - export = json.loads(await ctx.message.reference.resolved.attachments[0].read()) + export = json.loads(await ctx.message.reference.resolved.attachments[0].read()) # type: ignore - this is fine to let error because it gets handled except (json.JSONDecodeError, IndexError, AttributeError): await ctx.send(error("Please provide a valid JSON export file.")) return diff --git a/bible/bible.py b/bible/bible.py index c3af117..cd95566 100644 --- a/bible/bible.py +++ b/bible/bible.py @@ -27,7 +27,7 @@ class Bible(commands.Cog): __author__ = ["[cswimr](https://www.coastalcommits.com/cswimr)"] __git__ = "https://www.coastalcommits.com/cswimr/SeaCogs" - __version__ = "1.1.3" + __version__ = "1.1.4" __documentation__ = "https://seacogs.coastalcommits.com/pterodactyl/" def __init__(self, bot: Red): @@ -145,6 +145,7 @@ class Bible(commands.Cog): if response.status == 503: raise bible.errors.ServiceUnavailableError + assert self.bot.user is not None # bot will always be logged in fums_url = "https://fums.api.bible/f3" fums_params = { "t": data["meta"]["fumsToken"], @@ -246,9 +247,9 @@ class Bible(commands.Cog): from_verse, to_verse = passage.replace(":", ".").split("-") if "." not in to_verse: to_verse = f"{from_verse.split('.')[0]}.{to_verse}" - passage = await self._get_passage(ctx, bible_id, f"{book_id}.{from_verse}-{book_id}.{to_verse}", True) + retrieved_passage = await self._get_passage(ctx, bible_id, f"{book_id}.{from_verse}-{book_id}.{to_verse}", True) else: - passage = await self._get_passage(ctx, bible_id, f"{book_id}.{passage.replace(':', '.')}", False) + retrieved_passage = await self._get_passage(ctx, bible_id, f"{book_id}.{passage.replace(':', '.')}", False) except ( bible.errors.BibleAccessError, bible.errors.NotFoundError, @@ -259,21 +260,21 @@ class Bible(commands.Cog): await ctx.send(e.message) return - if len(passage["content"]) > 4096: + if len(retrieved_passage["content"]) > 4096: await ctx.send("The passage is too long to send.") return if await ctx.embed_requested(): icon = self.get_icon(await ctx.embed_color()) embed = Embed( - title=f"{passage['reference']}", - description=passage["content"].replace("¶ ", ""), + title=f"{retrieved_passage['reference']}", + description=retrieved_passage["content"].replace("¶ ", ""), color=await ctx.embed_color(), ) embed.set_footer(text=f"{ctx.prefix}bible passage - Powered by API.Bible - {version.abbreviation_local} ({version.language_local}, {version.description_local})", icon_url="attachment://icon.png") await ctx.send(embed=embed, file=icon) else: - await ctx.send(f"## {passage['reference']}\n{passage['content']}") + await ctx.send(f"## {retrieved_passage['reference']}\n{retrieved_passage['content']}") @bible.command(name="random") async def bible_random(self, ctx: commands.Context): diff --git a/emojiinfo/emojiinfo.py b/emojiinfo/emojiinfo.py index aae0a92..96b533d 100644 --- a/emojiinfo/emojiinfo.py +++ b/emojiinfo/emojiinfo.py @@ -16,7 +16,7 @@ class EmojiInfo(commands.Cog): __author__ = ["[cswimr](https://www.coastalcommits.com/cswimr)"] __git__ = "https://www.coastalcommits.com/cswimr/SeaCogs" - __version__ = "1.0.2" + __version__ = "1.0.3" __documentation__ = "https://seacogs.coastalcommits.com/emojiinfo/" def __init__(self, bot: Red) -> None: @@ -69,7 +69,7 @@ class EmojiInfo(commands.Cog): else: emoji_id = "" markdown = f"`{emoji}`" - name = f"{bold('Name:')} {emoji.aliases.pop(0)}\n" + name = f"{bold('Name:')} {emoji.aliases.pop(0) if emoji.aliases else emoji.name}\n" aliases = f"{bold('Aliases:')} {', '.join(emoji.aliases)}\n" if emoji.aliases else "" group = f"{bold('Group:')} {emoji.group}\n" @@ -82,15 +82,13 @@ class EmojiInfo(commands.Cog): await interaction.response.defer(ephemeral=ephemeral) try: - emoji: PartialEmoji = PartialEmoji.from_str(self, value=emoji) - ( - string, - emoji_url, - ) = await self.get_emoji_info(emoji) + retrieved_emoji: PartialEmoji = PartialEmoji.from_str(self, value=emoji) + string, emoji_url = await self.get_emoji_info(retrieved_emoji) self.logger.verbose(f"Emoji:\n{string}") except (IndexError, UnboundLocalError): return await interaction.followup.send("Please provide a valid emoji!") + assert isinstance(interaction.channel, discord.TextChannel) if await self.bot.embed_requested(channel=interaction.channel): embed = discord.Embed(title="Emoji Information", description=string, color=await self.fetch_primary_color(emoji_url) or await self.bot.get_embed_color(interaction.channel)) embed.set_thumbnail(url=emoji_url) @@ -104,20 +102,18 @@ class EmojiInfo(commands.Cog): async def emoji(self, ctx: commands.Context, *, emoji: str) -> None: """Retrieve information about an emoji.""" try: - emoji: PartialEmoji = PartialEmoji.from_str(self, value=emoji) - ( - string, - emoji_url, - ) = await self.get_emoji_info(emoji) + retrieved_emoji: PartialEmoji = PartialEmoji.from_str(self, value=emoji) + string, emoji_url = await self.get_emoji_info(retrieved_emoji) self.logger.verbose(f"Emoji:\n{string}") except (IndexError, UnboundLocalError): - return await ctx.send("Please provide a valid emoji!") + await ctx.send("Please provide a valid emoji!") + return if await ctx.embed_requested(): - embed = discord.Embed(title="Emoji Information", description=string, color=await self.fetch_primary_color(emoji_url) or await ctx.embed_color) + embed = discord.Embed(title="Emoji Information", description=string, color=await self.fetch_primary_color(emoji_url) or await ctx.embed_color()) embed.set_thumbnail(url=emoji_url) await ctx.send(embed=embed) - return None + return await ctx.send(content=string) - return None + return diff --git a/emojiinfo/model.py b/emojiinfo/model.py index 5885afb..c553950 100644 --- a/emojiinfo/model.py +++ b/emojiinfo/model.py @@ -77,7 +77,7 @@ class PartialEmoji(discord.PartialEmoji): name = groups["name"] return cls(name=name, animated=animated, id=emoji_id) - path: data_manager.Path = data_manager.bundled_data_path(coginstance) / "emojis.json" + path = data_manager.bundled_data_path(coginstance) / "emojis.json" with open(path, "r", encoding="UTF-8") as file: emojis: dict = json.load(file) emoji_aliases = [] diff --git a/hotreload/hotreload.py b/hotreload/hotreload.py index ee223f2..579e7db 100644 --- a/hotreload/hotreload.py +++ b/hotreload/hotreload.py @@ -2,18 +2,18 @@ import py_compile from asyncio import run_coroutine_threadsafe from pathlib import Path from tempfile import NamedTemporaryFile -from typing import TYPE_CHECKING, List, Sequence, Tuple +from typing import Generator, List, Sequence +import discord from red_commons.logging import RedTraceLogger, getLogger from redbot.core import Config, checks, commands from redbot.core.bot import Red from redbot.core.core_commands import CoreLogic from redbot.core.utils.chat_formatting import bold, box, humanize_list +from typing_extensions import override from watchdog.events import FileSystemEvent, FileSystemMovedEvent, RegexMatchingEventHandler from watchdog.observers import Observer - -if TYPE_CHECKING: - from watchdog.observers import ObserverType +from watchdog.observers.api import BaseObserver class HotReload(commands.Cog): @@ -21,24 +21,26 @@ class HotReload(commands.Cog): __author__ = ["[cswimr](https://www.coastalcommits.com/cswimr)"] __git__ = "https://www.coastalcommits.com/cswimr/SeaCogs" - __version__ = "1.4.0" + __version__ = "1.4.1" __documentation__ = "https://seacogs.coastalcommits.com/hotreload/" def __init__(self, bot: Red) -> None: super().__init__() self.bot: Red = bot - self.config = Config.get_conf(self, identifier=294518358420750336, force_registration=True) + self.config: Config = Config.get_conf(cog_instance=self, identifier=294518358420750336, force_registration=True) self.logger: RedTraceLogger = getLogger(name="red.SeaCogs.HotReload") - self.observers: List[ObserverType] = [] + self.observers: List[BaseObserver] = [] self.config.register_global(notify_channel=None, compile_before_reload=False) watchdog_loggers = [getLogger(name="watchdog.observers.inotify_buffer")] for watchdog_logger in watchdog_loggers: watchdog_logger.setLevel("INFO") # SHUT UP!!!! + @override async def cog_load(self) -> None: """Start the observer when the cog is loaded.""" - self.bot.loop.create_task(self.start_observer()) + _ = self.bot.loop.create_task(self.start_observer()) + @override async def cog_unload(self) -> None: """Stop the observer when the cog is unloaded.""" for observer in self.observers: @@ -46,6 +48,7 @@ class HotReload(commands.Cog): observer.join() self.logger.info("Stopped observer. No longer watching for file changes.") + @override def format_help_for_context(self, ctx: commands.Context) -> str: pre_processed = super().format_help_for_context(ctx) or "" n = "\n" if "\n\n" not in pre_processed else "" @@ -57,7 +60,7 @@ class HotReload(commands.Cog): ] return "\n".join(text) - async def get_paths(self) -> Tuple[Path]: + async def get_paths(self) -> Generator[Path]: """Retrieve user defined paths.""" cog_manager = self.bot._cog_mgr # noqa: SLF001 # We have to use this private method because there is no public API to get user defined paths cog_paths = await cog_manager.user_defined_paths() @@ -79,7 +82,7 @@ class HotReload(commands.Cog): self.logger.warning("Path %s does not exist. Skipping.", path) continue self.logger.debug("Adding observer schedule for path %s.", path) - observer.schedule(event_handler=HotReloadHandler(cog=self, path=path), path=path, recursive=True) + observer.schedule(event_handler=HotReloadHandler(cog=self, path=path), path=str(path), recursive=True) observer.start() self.logger.info("Started observer. Watching for file changes.") is_first = False @@ -91,24 +94,24 @@ class HotReload(commands.Cog): pass @hotreload_group.command(name="notifychannel") - async def hotreload_notifychannel(self, ctx: commands.Context, channel: commands.TextChannelConverter) -> None: + async def hotreload_notifychannel(self, ctx: commands.Context, channel: discord.TextChannel) -> None: """Set the channel to send notifications to.""" await self.config.notify_channel.set(channel.id) await ctx.send(f"Notifications will be sent to {channel.mention}.") - @hotreload_group.command(name="compile") + @hotreload_group.command(name="compile") # type: ignore async def hotreload_compile(self, ctx: commands.Context, compile_before_reload: bool) -> None: """Set whether to compile modified files before reloading.""" await self.config.compile_before_reload.set(compile_before_reload) await ctx.send(f"I {'will' if compile_before_reload else 'will not'} compile modified files before hotreloading cogs.") - @hotreload_group.command(name="list") + @hotreload_group.command(name="list") # type: ignore async def hotreload_list(self, ctx: commands.Context) -> None: """List the currently active observers.""" if not self.observers: await ctx.send("No observers are currently active.") return - await ctx.send(f"Currently active observers (If there are more than one of these, report an issue): {box(humanize_list(self.observers, style='unit'))}") + await ctx.send(f"Currently active observers (If there are more than one of these, report an issue): {box(humanize_list([str(o) for o in self.observers], style='unit'))}") class HotReloadHandler(RegexMatchingEventHandler): @@ -129,13 +132,13 @@ class HotReloadHandler(RegexMatchingEventHandler): if event.event_type not in allowed_events: return - relative_src_path = Path(event.src_path).relative_to(self.path) + relative_src_path = Path(str(event.src_path)).relative_to(self.path) src_package_name = relative_src_path.parts[0] cogs_to_reload = [src_package_name] if isinstance(event, FileSystemMovedEvent): dest = f" to {event.dest_path}" - relative_dest_path = Path(event.dest_path).relative_to(self.path) + relative_dest_path = Path(str(event.dest_path)).relative_to(self.path) dest_package_name = relative_dest_path.parts[0] if dest_package_name != src_package_name: cogs_to_reload.append(dest_package_name) @@ -147,7 +150,7 @@ class HotReloadHandler(RegexMatchingEventHandler): run_coroutine_threadsafe( coro=self.reload_cogs( cog_names=cogs_to_reload, - paths=[Path(p) for p in (event.src_path, getattr(event, "dest_path", None)) if p], + paths=[Path(str(p)) for p in (event.src_path, getattr(event, "dest_path", None)) if p], ), loop=self.cog.bot.loop, ) @@ -163,7 +166,7 @@ class HotReloadHandler(RegexMatchingEventHandler): self.logger.info("Reloaded cogs: %s", humanize_list(cog_names, style="unit")) channel = self.cog.bot.get_channel(await self.cog.config.notify_channel()) - if channel: + if channel and isinstance(channel, discord.TextChannel): await channel.send(f"Reloaded cogs: {humanize_list(cog_names, style='unit')}") def compile_modified_files(self, cog_names: Sequence[str], paths: Sequence[Path]) -> bool: @@ -176,7 +179,7 @@ class HotReloadHandler(RegexMatchingEventHandler): try: with NamedTemporaryFile() as temp_file: self.logger.debug("Attempting to compile %s", path) - py_compile.compile(file=path, cfile=temp_file.name, doraise=True) + py_compile.compile(file=str(path), cfile=temp_file.name, doraise=True) self.logger.debug("Successfully compiled %s", path) except py_compile.PyCompileError as e: diff --git a/nerdify/nerdify.py b/nerdify/nerdify.py index 346d37e..fb9b784 100644 --- a/nerdify/nerdify.py +++ b/nerdify/nerdify.py @@ -37,16 +37,20 @@ class Nerdify(commands.Cog): ] return "\n".join(text) - @commands.command(aliases=["nerd"]) async def nerdify( - self, ctx: commands.Context, *, text: Optional[str] = None, + self, + ctx: commands.Context, + *, + text: Optional[str] = None, ) -> None: """Nerdify the replied to message, previous message, or your own text.""" if not text: if hasattr(ctx.message, "reference") and ctx.message.reference: with suppress( - discord.Forbidden, discord.NotFound, discord.HTTPException, + discord.Forbidden, + discord.NotFound, + discord.HTTPException, ): message_id = ctx.message.reference.message_id if message_id: @@ -62,7 +66,9 @@ class Nerdify(commands.Cog): ctx.channel, self.nerdify_text(text), allowed_mentions=discord.AllowedMentions( - everyone=False, users=False, roles=False, + everyone=False, + users=False, + roles=False, ), ) @@ -77,7 +83,10 @@ class Nerdify(commands.Cog): return f'"{text}" 🤓' async def type_message( - self, destination: discord.abc.Messageable, content: str, **kwargs: Any, + self, + destination: discord.abc.Messageable, + content: str, + **kwargs: Any, ) -> Union[discord.Message, None]: """Simulate typing and sending a message to a destination. diff --git a/pterodactyl/pterodactyl.py b/pterodactyl/pterodactyl.py index 18e229f..99891e0 100644 --- a/pterodactyl/pterodactyl.py +++ b/pterodactyl/pterodactyl.py @@ -1,6 +1,6 @@ import asyncio import json -from typing import Mapping, Optional, Tuple, Union +from typing import AsyncIterable, Iterable, Mapping, Optional, Tuple, Union import discord import websockets @@ -9,8 +9,9 @@ from pydactyl import PterodactylClient from redbot.core import app_commands, commands from redbot.core.app_commands import Choice from redbot.core.bot import Red -from redbot.core.utils.chat_formatting import bold, box, error, humanize_list +from redbot.core.utils.chat_formatting import bold, box, humanize_list from redbot.core.utils.views import ConfirmView +from typing_extensions import override from pterodactyl import mcsrvstatus from pterodactyl.config import config, register_config @@ -22,7 +23,7 @@ class Pterodactyl(commands.Cog): __author__ = ["[cswimr](https://www.coastalcommits.com/cswimr)"] __git__ = "https://www.coastalcommits.com/cswimr/SeaCogs" - __version__ = "2.0.5" + __version__ = "2.0.6" __documentation__ = "https://seacogs.coastalcommits.com/pterodactyl/" def __init__(self, bot: Red): @@ -32,9 +33,10 @@ class Pterodactyl(commands.Cog): self.websocket: Optional[websockets.ClientConnection] = None self.retry_counter: int = 0 register_config(config) - self.task = self.get_task() + self.task = self._get_task() self.update_topic.start() + @override def format_help_for_context(self, ctx: commands.Context) -> str: pre_processed = super().format_help_for_context(ctx) or "" n = "\n" if "\n\n" not in pre_processed else "" @@ -46,50 +48,57 @@ class Pterodactyl(commands.Cog): ] return "\n".join(text) + @override async def cog_load(self) -> None: pterodactyl_keys = await self.bot.get_shared_api_tokens("pterodactyl") api_key = pterodactyl_keys.get("api_key") if api_key is None: - self.task.cancel() + self.maybe_cancel_task() logger.error("Pterodactyl API key not set. Please set it using `[p]set api`.") return base_url = await config.base_url() if base_url is None: - self.task.cancel() + self.maybe_cancel_task() logger.error("Pterodactyl base URL not set. Please set it using `[p]pterodactyl config url`.") return server_id = await config.server_id() if server_id is None: - self.task.cancel() + self.maybe_cancel_task() logger.error("Pterodactyl server ID not set. Please set it using `[p]pterodactyl config serverid`.") return self.client = PterodactylClient(base_url, api_key).client + @override async def cog_unload(self) -> None: self.update_topic.cancel() - self.task.cancel() - self.retry_counter = 0 + self.maybe_cancel_task() - def get_task(self) -> asyncio.Task: + def maybe_cancel_task(self, reset_retry_counter: bool = True) -> None: + if self.task: + self.task.cancel() + if reset_retry_counter: + self.retry_counter = 0 + + def _get_task(self) -> asyncio.Task: from pterodactyl.websocket import establish_websocket_connection task = self.bot.loop.create_task(establish_websocket_connection(self), name="Pterodactyl Websocket Connection") - task.add_done_callback(self.error_callback) + task.add_done_callback(self._error_callback) return task - def error_callback(self, fut) -> None: # NOTE Thanks flame442 and zephyrkul for helping me figure this out + def _error_callback(self, fut) -> None: # NOTE Thanks flame442 and zephyrkul for helping me figure this out try: fut.result() except asyncio.CancelledError: logger.info("WebSocket task has been cancelled.") except Exception as e: # pylint: disable=broad-exception-caught logger.error("WebSocket task has failed: %s", e, exc_info=e) - self.task.cancel() + self.maybe_cancel_task(reset_retry_counter=False) if self.retry_counter < 5: self.retry_counter += 1 logger.info("Retrying in %s seconds...", 5 * self.retry_counter) - self.task = self.bot.loop.call_later(5 * self.retry_counter, self.get_task) + self.task = self.bot.loop.call_later(5 * self.retry_counter, self._get_task) else: logger.info("Retry limit reached. Stopping task.") @@ -100,9 +109,9 @@ class Pterodactyl(commands.Cog): console = self.bot.get_channel(await config.console_channel()) chat = self.bot.get_channel(await config.chat_channel()) if console: - await console.edit(topic=topic) + await console.edit(topic=topic) # type: ignore if chat: - await chat.edit(topic=topic) + await chat.edit(topic=topic) # type: ignore @commands.Cog.listener() async def on_message_without_command(self, message: discord.Message) -> None: @@ -113,13 +122,7 @@ class Pterodactyl(commands.Cog): return logger.debug("Received console command from %s: %s", message.author.id, message.content) await message.channel.send(f"Received console command from {message.author.id}: {message.content[:1900]}", allowed_mentions=discord.AllowedMentions.none()) - try: - await self.websocket.send(json.dumps({"event": "send command", "args": [message.content]})) - except websockets.exceptions.ConnectionClosed as e: - logger.error("WebSocket connection closed: %s", e) - self.task.cancel() - self.retry_counter = 0 - self.task = self.get_task() + await self._send(json.dumps({"event": "send command", "args": [message.content]})) if message.channel.id == await config.chat_channel() and message.author.bot is False: logger.debug("Received chat message from %s: %s", message.author.id, message.content) channel = self.bot.get_channel(await config.console_channel()) @@ -127,13 +130,22 @@ class Pterodactyl(commands.Cog): await channel.send(f"Received chat message from {message.author.id}: {message.content[:1900]}", allowed_mentions=discord.AllowedMentions.none()) msg = json.dumps({"event": "send command", "args": [await self.get_chat_command(message)]}) logger.debug("Sending chat message to server:\n%s", msg) + await self._send(message=msg) + + async def _send(self, message: Union[websockets.Data, Iterable[websockets.Data], AsyncIterable[websockets.Data]], text: bool = False): + """Send a message through the websocket connection. Restarts the websocket connection task if it is closed, and reinvokes itself.""" + try: + await self.websocket.send(message=message, text=text) # type: ignore - we want this to error if `self.websocket` is none + except websockets.exceptions.ConnectionClosed as e: + logger.error("WebSocket connection closed: %s", e) + self.maybe_cancel_task() + self.task = self._get_task() try: - await self.websocket.send(msg) - except websockets.exceptions.ConnectionClosed as e: - logger.error("WebSocket connection closed: %s", e) - self.task.cancel() - self.retry_counter = 0 - self.task = self.get_task() + await asyncio.wait_for(fut=self.task, timeout=60) + await self._send(message=message, text=text) + except asyncio.TimeoutError: + logger.error("Timeout while waiting for websocket connection") + raise async def get_topic(self) -> str: topic: str = await config.topic() @@ -193,7 +205,7 @@ class Pterodactyl(commands.Cog): async def get_player_list_embed(self, ctx: Union[commands.Context, discord.Interaction]) -> Optional[discord.Embed]: player_list = await self.get_player_list() - if player_list: + if player_list and isinstance(ctx.channel, discord.abc.Messageable): embed = discord.Embed(color=await self.bot.get_embed_color(ctx.channel), title="Players Online") embed.description = player_list[0] return embed @@ -206,10 +218,12 @@ class Pterodactyl(commands.Cog): current_status = await config.current_status() if current_status == action_ing: - return await ctx.send(f"Server is already {action_ing}.", ephemeral=True) + await ctx.send(f"Server is already {action_ing}.", ephemeral=True) + return if current_status in ["starting", "stopping"] and action != "kill": - return await ctx.send("Another power action is already in progress.", ephemeral=True) + await ctx.send("Another power action is already in progress.", ephemeral=True) + return view = ConfirmView(ctx.author, disable_buttons=True) @@ -220,13 +234,13 @@ class Pterodactyl(commands.Cog): if view.result is True: await message.edit(content=f"Sending websocket command to {action} server...", view=None) - await self.websocket.send(json.dumps({"event": "set state", "args": [action]})) + await self._websocket_send(json.dumps({"event": "set state", "args": [action]})) await message.edit(content=f"Server {action_ing}", view=None) - return None + return await message.edit(content="Cancelled.", view=None) - return None + return async def send_command(self, ctx: Union[discord.Interaction, commands.Context], command: str): channel = self.bot.get_channel(await config.console_channel()) @@ -234,23 +248,15 @@ class Pterodactyl(commands.Cog): ctx = await self.bot.get_context(ctx) if channel: await channel.send(f"Received console command from {ctx.author.id}: {command[:1900]}", allowed_mentions=discord.AllowedMentions.none()) - try: - await self.websocket.send(json.dumps({"event": "send command", "args": [command]})) - await ctx.send(f"Command sent to server. {box(command, 'json')}") - except websockets.exceptions.ConnectionClosed as e: - logger.error("WebSocket connection closed: %s", e) - await ctx.send(error("WebSocket connection closed.")) - self.task.cancel() - self.retry_counter = 0 - self.task = self.get_task() + await self._websocket_send(json.dumps({"event": "send command", "args": [command]})) + await ctx.send(f"Command sent to server. {box(command, 'json')}") @commands.Cog.listener() async def on_red_api_tokens_update(self, service_name: str, api_tokens: Mapping[str, str]): # pylint: disable=unused-argument if service_name == "pterodactyl": logger.info("Configuration value set: api_key\nRestarting task...") - self.task.cancel() - self.retry_counter = 0 - self.task = self.get_task() + self.maybe_cancel_task(reset_retry_counter=True) + self.task = self._get_task() slash_pterodactyl = app_commands.Group(name="pterodactyl", description="Pterodactyl allows you to manage your Pterodactyl Panel from Discord.") @@ -346,9 +352,8 @@ class Pterodactyl(commands.Cog): await config.base_url.set(base_url) await ctx.send(f"Base URL set to {base_url}") logger.info("Configuration value set: base_url = %s\nRestarting task...", base_url) - self.task.cancel() - self.retry_counter = 0 - self.task = self.get_task() + self.maybe_cancel_task(reset_retry_counter=True) + self.task = self._get_task() @pterodactyl_config.command(name="serverid") async def pterodactyl_config_server_id(self, ctx: commands.Context, *, server_id: str) -> None: @@ -356,9 +361,8 @@ class Pterodactyl(commands.Cog): await config.server_id.set(server_id) await ctx.send(f"Server ID set to {server_id}") logger.info("Configuration value set: server_id = %s\nRestarting task...", server_id) - self.task.cancel() - self.retry_counter = 0 - self.task = self.get_task() + self.maybe_cancel_task(reset_retry_counter=True) + self.task = self._get_task() @pterodactyl_config.group(name="console") async def pterodactyl_config_console(self, ctx: commands.Context): diff --git a/pterodactyl/websocket.py b/pterodactyl/websocket.py index 4392744..6ead074 100644 --- a/pterodactyl/websocket.py +++ b/pterodactyl/websocket.py @@ -2,7 +2,7 @@ import json import re from pathlib import Path -from typing import Optional, Tuple, Union +from typing import Any, Optional, Tuple, Union import aiohttp import discord @@ -56,7 +56,9 @@ async def establish_websocket_connection(coginstance: Pterodactyl) -> None: content = mask_ip(content) console_channel = coginstance.bot.get_channel(await config.console_channel()) + assert isinstance(console_channel, discord.abc.Messageable) chat_channel = coginstance.bot.get_channel(await config.chat_channel()) + assert isinstance(chat_channel, discord.abc.Messageable) if console_channel is not None: if content.startswith("["): pagified_content = pagify(content, delims=[" ", "\n"]) @@ -83,7 +85,7 @@ async def establish_websocket_connection(coginstance: Pterodactyl) -> None: embed, img = await generate_join_leave_embed(coginstance=coginstance, username=join_message, join=True) if img: with open(img, "rb") as file: - await chat_channel.send(embed=embed, file=file) + await chat_channel.send(embed=embed, file=discord.File(fp=file)) else: await chat_channel.send(embed=embed) else: @@ -96,7 +98,7 @@ async def establish_websocket_connection(coginstance: Pterodactyl) -> None: embed, img = await generate_join_leave_embed(coginstance=coginstance, username=leave_message, join=False) if img: with open(img, "rb") as file: - await chat_channel.send(embed=embed, file=file) + await chat_channel.send(embed=embed, file=discord.File(fp=file)) else: await chat_channel.send(embed=embed) else: @@ -106,7 +108,11 @@ async def establish_websocket_connection(coginstance: Pterodactyl) -> None: if achievement_message: if chat_channel is not None: if coginstance.bot.embed_requested(chat_channel): - await chat_channel.send(embed=await generate_achievement_embed(coginstance, achievement_message["username"], achievement_message["achievement"], achievement_message["challenge"])) + embed, img = await generate_achievement_embed(coginstance, achievement_message["username"], achievement_message["achievement"], achievement_message["challenge"]) + if img: + await chat_channel.send(embed=embed, file=discord.File(fp=img)) + else: + await chat_channel.send(embed=embed) else: await chat_channel.send(f"{achievement_message['username']} has {'completed the challenge' if achievement_message['challenge'] else 'made the advancement'} {achievement_message['achievement']}") @@ -130,24 +136,27 @@ async def establish_websocket_connection(coginstance: Pterodactyl) -> None: await chat.send(await config.shutdown_msg()) -async def retrieve_websocket_credentials(coginstance: Pterodactyl) -> Optional[dict]: +async def retrieve_websocket_credentials(coginstance: Pterodactyl) -> dict: pterodactyl_keys = await coginstance.bot.get_shared_api_tokens("pterodactyl") api_key = pterodactyl_keys.get("api_key") if api_key is None: - coginstance.task.cancel() + coginstance.maybe_cancel_task() raise ValueError("Pterodactyl API key not set. Please set it using `[p]set api`.") base_url = await config.base_url() if base_url is None: - coginstance.task.cancel() + coginstance.maybe_cancel_task() raise ValueError("Pterodactyl base URL not set. Please set it using `[p]pterodactyl config url`.") server_id = await config.server_id() if server_id is None: - coginstance.task.cancel() + coginstance.maybe_cancel_task() raise ValueError("Pterodactyl server ID not set. Please set it using `[p]pterodactyl config serverid`.") client = PterodactylClient(base_url, api_key).client coginstance.client = client - websocket_credentials = client.servers.get_websocket(server_id) + websocket_credentials: dict[str, Any] = client.servers.get_websocket(server_id).json() + if not websocket_credentials: + coginstance.maybe_cancel_task() + raise ValueError("Failed to retrieve websocket credentials. Please ensure the API details are correctly configured.") logger.debug( """Websocket connection details retrieved: Socket: %s @@ -165,44 +174,44 @@ def remove_ansi_escape_codes(text: str) -> str: return ansi_escape.sub("", text) -async def check_if_server_message(text: str) -> Union[bool, str]: +async def check_if_server_message(text: str) -> Optional[str]: regex = await config.server_regex() match: Optional[re.Match[str]] = re.match(regex, text) if match: logger.trace("Message is a server message") return match.group(1) - return False + return None -async def check_if_chat_message(text: str) -> Union[bool, dict]: +async def check_if_chat_message(text: str) -> Optional[dict]: regex = await config.chat_regex() match: Optional[re.Match[str]] = re.match(regex, text) if match: groups = {"username": match.group(1), "message": match.group(2)} logger.trace("Message is a chat message\n%s", json.dumps(groups)) return groups - return False + return None -async def check_if_join_message(text: str) -> Union[bool, str]: +async def check_if_join_message(text: str) -> Optional[str]: regex = await config.join_regex() match: Optional[re.Match[str]] = re.match(regex, text) if match: logger.trace("Message is a join message") return match.group(1) - return False + return None -async def check_if_leave_message(text: str) -> Union[bool, str]: +async def check_if_leave_message(text: str) -> Optional[str]: regex = await config.leave_regex() match: Optional[re.Match[str]] = re.match(regex, text) if match: logger.trace("Message is a leave message") return match.group(1) - return False + return None -async def check_if_achievement_message(text: str) -> Union[bool, dict]: +async def check_if_achievement_message(text: str) -> Optional[dict]: regex = await config.achievement_regex() match: Optional[re.Match[str]] = re.match(regex, text) if match: @@ -213,7 +222,7 @@ async def check_if_achievement_message(text: str) -> Union[bool, dict]: groups["challenge"] = False logger.trace("Message is an achievement message") return groups - return False + return None async def get_info(username: str) -> Optional[dict]: diff --git a/seautils/seautils.py b/seautils/seautils.py index 13d6d03..126ffd1 100644 --- a/seautils/seautils.py +++ b/seautils/seautils.py @@ -42,7 +42,7 @@ class SeaUtils(commands.Cog): __author__ = ["[cswimr](https://www.coastalcommits.com/cswimr)"] __git__ = "https://www.coastalcommits.com/cswimr/SeaCogs" - __version__ = "1.0.1" + __version__ = "1.0.2" __documentation__ = "https://seacogs.coastalcommits.com/seautils/" def __init__(self, bot: Red) -> None: @@ -74,7 +74,7 @@ class SeaUtils(commands.Cog): src = obj.function return inspect.getsource(object=src) - @commands.command(aliases=["source", "src", "code", "showsource"]) + @commands.command(aliases=["source", "src", "code", "showsource"]) # type: ignore @commands.is_owner() async def showcode(self, ctx: commands.Context, *, object: str) -> None: # pylint: disable=redefined-builtin # noqa: A002 """Show the code for a particular object.""" @@ -102,7 +102,7 @@ class SeaUtils(commands.Cog): else: await ctx.send(content="Object not found!", reference=ctx.message.to_reference(fail_if_not_exists=False)) - @commands.command(name="dig", aliases=["dnslookup", "nslookup"]) + @commands.command(name="dig", aliases=["dnslookup", "nslookup"]) # type: ignore @commands.is_owner() async def dig(self, ctx: commands.Context, name: str, record_type: str | None = None, server: str | None = None, port: int = 53) -> None: """Retrieve DNS information for a domain. @@ -110,7 +110,7 @@ class SeaUtils(commands.Cog): Uses `dig` to perform a DNS query. Will fall back to `nslookup` if `dig` is not installed on the system. `nslookup` does not provide as much information as `dig`, so only the `name` parameter will be used if `nslookup` is used. Will return the A, AAAA, and CNAME records for a domain by default. You can specify a different record type with the `type` parameter.""" - command_opts: list[str | int] = ["dig"] + command_opts: list[str] = ["dig"] query_types: list[str] = [record_type] if record_type else ["A", "AAAA", "CNAME"] if server: command_opts.extend(["@", server]) @@ -176,7 +176,7 @@ class SeaUtils(commands.Cog): embed.add_field(name="Authority Section", value=f"{cf.box(text=authority_section, lang='prolog')}", inline=False) await ctx.send(embed=embed) else: - await ctx.send(content=cf.box(text=stdout, lang="yaml")) + await ctx.send(content=cf.box(text=str(stdout), lang="yaml")) except FileNotFoundError: try: ns_process = await asyncio.create_subprocess_exec("nslookup", name, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE) @@ -208,7 +208,7 @@ class SeaUtils(commands.Cog): html = await response.text() soup = BeautifulSoup(html, "html.parser") pre_tags = soup.find_all("pre") - content: list[Embed | str] = [] + content: list[str | Embed] = [] for pre_tag in pre_tags: text = format_rfc_text(md(pre_tag), number) if len(text) > 4096: @@ -227,6 +227,6 @@ class SeaUtils(commands.Cog): if await ctx.embed_requested(): for embed in content: embed.set_footer(text=f"Page {content.index(embed) + 1}/{len(content)}") - await SimpleMenu(pages=content, disable_after_timeout=True, timeout=300).start(ctx) + await SimpleMenu(pages=content, disable_after_timeout=True, timeout=300).start(ctx) # type: ignore else: await ctx.maybe_send_embed(message=cf.error(f"An error occurred while fetching RFC {number}. Status code: {response.status}.")) From 999fd8e96f1d56dc1ea3b130da9a1702d711b23c Mon Sep 17 00:00:00 2001 From: cswimr Date: Tue, 4 Feb 2025 20:18:31 -0600 Subject: [PATCH 42/53] chore(tooling): re-add nix flake and update deps --- .envrc | 1 + .gitignore | 1 + flake.lock | 25 ++++++ flake.nix | 55 +++++++++++++ pyproject.toml | 4 + uv.lock | 212 +++++++++++++++++++++++++------------------------ 6 files changed, 194 insertions(+), 104 deletions(-) create mode 100644 .envrc create mode 100644 flake.lock create mode 100644 flake.nix diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..3550a30 --- /dev/null +++ b/.envrc @@ -0,0 +1 @@ +use flake diff --git a/.gitignore b/.gitignore index b56a839..3902499 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ site __pycache__ .mypy_cache/ .ruff_cache/ +.direnv/ diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..855cc6a --- /dev/null +++ b/flake.lock @@ -0,0 +1,25 @@ +{ + "nodes": { + "nixpkgs": { + "locked": { + "lastModified": 1738546358, + "narHash": "sha256-nLivjIygCiqLp5QcL7l56Tca/elVqM9FG1hGd9ZSsrg=", + "rev": "c6e957d81b96751a3d5967a0fd73694f303cc914", + "revCount": 747070, + "type": "tarball", + "url": "https://api.flakehub.com/f/pinned/NixOS/nixpkgs/0.1.747070%2Brev-c6e957d81b96751a3d5967a0fd73694f303cc914/0194cfda-968b-7c4f-95c5-bd4a42478770/source.tar.gz" + }, + "original": { + "type": "tarball", + "url": "https://flakehub.com/f/NixOS/nixpkgs/0.1.%2A.tar.gz" + } + }, + "root": { + "inputs": { + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..b443a85 --- /dev/null +++ b/flake.nix @@ -0,0 +1,55 @@ +{ + description = "SeaCogs Nix Flake"; + inputs.nixpkgs.url = "https://flakehub.com/f/NixOS/nixpkgs/0.1.*.tar.gz"; + + outputs = + { self, nixpkgs }: + let + supportedSystems = [ + "x86_64-linux" + "aarch64-linux" + "x86_64-darwin" + "aarch64-darwin" + ]; + forEachSupportedSystem = + f: + nixpkgs.lib.genAttrs supportedSystems ( + system: + f { + pkgs = import nixpkgs { inherit system; }; + } + ); + in + { + devShells = forEachSupportedSystem ( + { pkgs }: + { + default = pkgs.mkShell { + packages = with pkgs; [ + python311 + uv + forgejo-runner + # Red-DiscordBot dependencies + git + libsodium + libffi + libaio + jdk17 + # Material for MkDocs dependencies + cairo + pngquant + ]; + shellHook = # bash + '' + export UV_PYTHON_PREFERENCE=only-system + export UV_PYTHON_DOWNLOADS=never + uv sync --all-groups + alias uvr="uv run" + source ./.venv/bin/activate + export PYTHONPATH=`pwd`/.venv/${pkgs.python311.sitePackages}/:$PYTHONPATH + ''; + }; + } + ); + }; +} diff --git a/pyproject.toml b/pyproject.toml index f5010a5..782dad3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -38,6 +38,10 @@ dev-dependencies = ["pylint>=3.3.3", "ruff>=0.9.3", "sqlite-web>=0.6.4"] [tool.uv.sources] py-dactyl = { git = "https://github.com/cswimr/pydactyl" } +[tool.basedpyright] +typeCheckingMode = "basic" +reportAttributeAccessIssue = false # disabled because `commands.group.command` is listed as Any / Unknown for some reason + [tool.ruff] # Exclude a variety of commonly ignored directories. exclude = [ diff --git a/uv.lock b/uv.lock index e2ad6a7..75ae73c 100644 --- a/uv.lock +++ b/uv.lock @@ -76,14 +76,14 @@ wheels = [ [[package]] name = "aiosqlite" -version = "0.20.0" +version = "0.21.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/0d/3a/22ff5415bf4d296c1e92b07fd746ad42c96781f13295a074d58e77747848/aiosqlite-0.20.0.tar.gz", hash = "sha256:6d35c8c256637f4672f843c31021464090805bf925385ac39473fb16eaaca3d7", size = 21691 } +sdist = { url = "https://files.pythonhosted.org/packages/13/7d/8bca2bf9a247c2c5dfeec1d7a5f40db6518f88d314b8bca9da29670d2671/aiosqlite-0.21.0.tar.gz", hash = "sha256:131bb8056daa3bc875608c631c678cda73922a2d4ba8aec373b19f18c17e7aa3", size = 13454 } wheels = [ - { url = "https://files.pythonhosted.org/packages/00/c4/c93eb22025a2de6b83263dfe3d7df2e19138e345bca6f18dba7394120930/aiosqlite-0.20.0-py3-none-any.whl", hash = "sha256:36a1deaca0cac40ebe32aac9977a6e2bbc7f5189f23f4a54d5908986729e5bd6", size = 15564 }, + { url = "https://files.pythonhosted.org/packages/f5/10/6c25ed6de94c49f88a91fa5018cb4c0f3625f31d5be9f771ebe5cc7cd506/aiosqlite-0.21.0-py3-none-any.whl", hash = "sha256:2549cf4057f95f53dcba16f2b64e8e2791d7e1adedb13197dd8ed77bb226d7d0", size = 15792 }, ] [[package]] @@ -153,32 +153,33 @@ wheels = [ [[package]] name = "attrs" -version = "24.3.0" +version = "25.1.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/48/c8/6260f8ccc11f0917360fc0da435c5c9c7504e3db174d5a12a1494887b045/attrs-24.3.0.tar.gz", hash = "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff", size = 805984 } +sdist = { url = "https://files.pythonhosted.org/packages/49/7c/fdf464bcc51d23881d110abd74b512a42b3d5d376a55a831b44c603ae17f/attrs-25.1.0.tar.gz", hash = "sha256:1c97078a80c814273a76b2a298a932eb681c87415c11dee0a6921de7f1b02c3e", size = 810562 } wheels = [ - { url = "https://files.pythonhosted.org/packages/89/aa/ab0f7891a01eeb2d2e338ae8fecbe57fcebea1a24dbb64d45801bfab481d/attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308", size = 63397 }, + { url = "https://files.pythonhosted.org/packages/fc/30/d4986a882011f9df997a55e6becd864812ccfcd821d64aac8570ee39f719/attrs-25.1.0-py3-none-any.whl", hash = "sha256:c75a69e28a550a7e93789579c22aa26b0f5b83b75dc4e08fe092980051e1090a", size = 63152 }, ] [[package]] name = "babel" -version = "2.16.0" +version = "2.17.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/2a/74/f1bc80f23eeba13393b7222b11d95ca3af2c1e28edca18af487137eefed9/babel-2.16.0.tar.gz", hash = "sha256:d1f3554ca26605fe173f3de0c65f750f5a42f924499bf134de6423582298e316", size = 9348104 } +sdist = { url = "https://files.pythonhosted.org/packages/7d/6b/d52e42361e1aa00709585ecc30b3f9684b3ab62530771402248b1b1d6240/babel-2.17.0.tar.gz", hash = "sha256:0c54cffb19f690cdcc52a3b50bcbf71e07a808d1c80d549f2459b9d2cf0afb9d", size = 9951852 } wheels = [ - { url = "https://files.pythonhosted.org/packages/ed/20/bc79bc575ba2e2a7f70e8a1155618bb1301eaa5132a8271373a6903f73f8/babel-2.16.0-py3-none-any.whl", hash = "sha256:368b5b98b37c06b7daf6696391c3240c938b37767d4584413e8438c5c435fa8b", size = 9587599 }, + { url = "https://files.pythonhosted.org/packages/b7/b8/3fe70c75fe32afc4bb507f75563d39bc5642255d1d94f1f23604725780bf/babel-2.17.0-py3-none-any.whl", hash = "sha256:4d0b53093fdfb4b21c92b5213dba5a1b23885afa8383709427046b21c366e5f2", size = 10182537 }, ] [[package]] name = "beautifulsoup4" -version = "4.12.3" +version = "4.13.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "soupsieve" }, + { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/b3/ca/824b1195773ce6166d388573fc106ce56d4a805bd7427b624e063596ec58/beautifulsoup4-4.12.3.tar.gz", hash = "sha256:74e3d1928edc070d21748185c46e3fb33490f22f52a3addee9aee0f4f7781051", size = 581181 } +sdist = { url = "https://files.pythonhosted.org/packages/f0/3c/adaf39ce1fb4afdd21b611e3d530b183bb7759c9b673d60db0e347fd4439/beautifulsoup4-4.13.3.tar.gz", hash = "sha256:1bd32405dacc920b42b83ba01644747ed77456a65760e285fbc47633ceddaf8b", size = 619516 } wheels = [ - { url = "https://files.pythonhosted.org/packages/b1/fe/e8c672695b37eecc5cbf43e1d0638d88d66ba3a44c4d321c796f4e59167f/beautifulsoup4-4.12.3-py3-none-any.whl", hash = "sha256:b80878c9f40111313e55da8ba20bdba06d8fa3969fc68304167741bbf9e082ed", size = 147925 }, + { url = "https://files.pythonhosted.org/packages/f9/49/6abb616eb3cbab6a7cca303dc02fdf3836de2e0b834bf966a7f5271a34d8/beautifulsoup4-4.13.3-py3-none-any.whl", hash = "sha256:99045d7d3f08f91f0d656bc9b7efbae189426cd913d830294a15eefa0ea4df16", size = 186015 }, ] [[package]] @@ -274,11 +275,11 @@ wheels = [ [[package]] name = "certifi" -version = "2024.12.14" +version = "2025.1.31" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/0f/bd/1d41ee578ce09523c81a15426705dd20969f5abf006d1afe8aeff0dd776a/certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db", size = 166010 } +sdist = { url = "https://files.pythonhosted.org/packages/1c/ab/c9f1e32b7b1bf505bf26f0ef697775960db7932abeb7b516de930ba2705f/certifi-2025.1.31.tar.gz", hash = "sha256:3d5da6925056f6f18f119200434a4780a94263f10d1c21d032a6f6b2baa20651", size = 167577 } wheels = [ - { url = "https://files.pythonhosted.org/packages/a5/32/8f6669fc4798494966bf446c8c4a162e0b5d893dff088afddf76414f70e1/certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56", size = 164927 }, + { url = "https://files.pythonhosted.org/packages/38/fc/bce832fd4fd99766c04d1ee0eead6b0ec6486fb100ae5e74c1d91292b982/certifi-2025.1.31-py3-none-any.whl", hash = "sha256:ca78db4565a652026a4db2bcdf68f2fb589ea80d0be70e03929ed730746b84fe", size = 166393 }, ] [[package]] @@ -567,14 +568,14 @@ wheels = [ [[package]] name = "griffe" -version = "1.5.5" +version = "1.5.6" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/5c/74/cd35a98cb11f79de0581e8e1e6fbd738aeeed1f2d90e9b5106728b63f5f7/griffe-1.5.5.tar.gz", hash = "sha256:35ee5b38b93d6a839098aad0f92207e6ad6b70c3e8866c08ca669275b8cba585", size = 391124 } +sdist = { url = "https://files.pythonhosted.org/packages/88/f0/a001e06c321dfa220103418259afbac50b933eac7a86657a4b572f0517e8/griffe-1.5.6.tar.gz", hash = "sha256:181f6666d5aceb6cd6e2da5a2b646cfb431e47a0da1fda283845734b67e10944", size = 391173 } wheels = [ - { url = "https://files.pythonhosted.org/packages/1f/88/52c9422bc853cd7c2b6122090e887d17b5fad29b67f930e4277c9c557357/griffe-1.5.5-py3-none-any.whl", hash = "sha256:2761b1e8876c6f1f9ab1af274df93ea6bbadd65090de5f38f4cb5cc84897c7dd", size = 128221 }, + { url = "https://files.pythonhosted.org/packages/b6/87/505777c4e5ca9c4fa5ae53fa4b0d5c2ba13a6d55a503a5594e94a2ba9b5a/griffe-1.5.6-py3-none-any.whl", hash = "sha256:b2a3afe497c6c1f952e54a23095ecc09435016293e77af8478ed65df1022a394", size = 128176 }, ] [[package]] @@ -591,7 +592,7 @@ name = "importlib-metadata" version = "8.5.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "zipp", marker = "python_full_version >= '3.12'" }, + { name = "zipp" }, ] sdist = { url = "https://files.pythonhosted.org/packages/cd/12/33e59336dca5be0c398a7482335911a33aa0e20776128f038019f1a95f1b/importlib_metadata-8.5.0.tar.gz", hash = "sha256:71522656f0abace1d072b9e5481a48f07c138e00f079c38c8f883823f9c26bd7", size = 55304 } wheels = [ @@ -600,11 +601,11 @@ wheels = [ [[package]] name = "isort" -version = "5.13.2" +version = "6.0.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/87/f9/c1eb8635a24e87ade2efce21e3ce8cd6b8630bb685ddc9cdaca1349b2eb5/isort-5.13.2.tar.gz", hash = "sha256:48fdfcb9face5d58a4f6dde2e72a1fb8dcaf8ab26f95ab49fab84c2ddefb0109", size = 175303 } +sdist = { url = "https://files.pythonhosted.org/packages/1c/28/b382d1656ac0ee4cef4bf579b13f9c6c813bff8a5cb5996669592c8c75fa/isort-6.0.0.tar.gz", hash = "sha256:75d9d8a1438a9432a7d7b54f2d3b45cad9a4a0fdba43617d9873379704a8bdf1", size = 828356 } wheels = [ - { url = "https://files.pythonhosted.org/packages/d1/b3/8def84f539e7d2289a02f0524b944b15d7c75dab7628bedf1c4f0992029c/isort-5.13.2-py3-none-any.whl", hash = "sha256:8ca5e72a8d85860d5a3fa69b8745237f2939afe12dbf656afbcb47fe72d947a6", size = 92310 }, + { url = "https://files.pythonhosted.org/packages/76/c7/d6017f09ae5b1206fbe531f7af3b6dac1f67aedcbd2e79f3b386c27955d6/isort-6.0.0-py3-none-any.whl", hash = "sha256:567954102bb47bb12e0fae62606570faacddd441e45683968c8d1734fb1af892", size = 94053 }, ] [[package]] @@ -818,7 +819,7 @@ wheels = [ [[package]] name = "mkdocs-material" -version = "9.5.50" +version = "9.6.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "babel" }, @@ -833,9 +834,9 @@ dependencies = [ { name = "regex" }, { name = "requests" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/c7/16/c48d5a28bc4a67c49808180b6009d4d1b4c0753739ffee3cc37046ab29d7/mkdocs_material-9.5.50.tar.gz", hash = "sha256:ae5fe16f3d7c9ccd05bb6916a7da7420cf99a9ce5e33debd9d40403a090d5825", size = 3923354 } +sdist = { url = "https://files.pythonhosted.org/packages/c9/75/fb8f772d4acf5439a446aedbe6e49b4c42a4bc4f8c866c930a7b0c3be2f8/mkdocs_material-9.6.2.tar.gz", hash = "sha256:a3de1c5d4c745f10afa78b1a02f917b9dce0808fb206adc0f5bb48b58c1ca21f", size = 3942567 } wheels = [ - { url = "https://files.pythonhosted.org/packages/ee/b5/1bf29cd744896ae83bd38c72970782c843ba13e0240b1a85277bd3928637/mkdocs_material-9.5.50-py3-none-any.whl", hash = "sha256:f24100f234741f4d423a9d672a909d859668a4f404796be3cf035f10d6050385", size = 8645274 }, + { url = "https://files.pythonhosted.org/packages/d1/17/b97aa245d43933acd416361d4f34612baec8ad4a6337339d45448cde728d/mkdocs_material-9.6.2-py3-none-any.whl", hash = "sha256:71d90dbd63b393ad11a4d90151dfe3dcbfcd802c0f29ce80bebd9bbac6abc753", size = 8688648 }, ] [package.optional-dependencies] @@ -867,21 +868,20 @@ wheels = [ [[package]] name = "mkdocstrings" -version = "0.27.0" +version = "0.28.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "click" }, { name = "jinja2" }, { name = "markdown" }, { name = "markupsafe" }, { name = "mkdocs" }, { name = "mkdocs-autorefs" }, - { name = "platformdirs" }, + { name = "mkdocs-get-deps" }, { name = "pymdown-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/e2/5a/5de70538c2cefae7ac3a15b5601e306ef3717290cb2aab11d51cbbc2d1c0/mkdocstrings-0.27.0.tar.gz", hash = "sha256:16adca6d6b0a1f9e0c07ff0b02ced8e16f228a9d65a37c063ec4c14d7b76a657", size = 94830 } +sdist = { url = "https://files.pythonhosted.org/packages/86/4b/70522427768a4637ffac376140f362dc3d159364fb64e698667e51053d57/mkdocstrings-0.28.0.tar.gz", hash = "sha256:df20afef1eafe36ba466ae20732509ecb74237653a585f5061937e54b553b4e0", size = 3392797 } wheels = [ - { url = "https://files.pythonhosted.org/packages/cd/10/4c27c3063c2b3681a4b7942f8dbdeb4fa34fecb2c19b594e7345ebf4f86f/mkdocstrings-0.27.0-py3-none-any.whl", hash = "sha256:6ceaa7ea830770959b55a16203ac63da24badd71325b96af950e59fd37366332", size = 30658 }, + { url = "https://files.pythonhosted.org/packages/75/c3/e5a319d4de0867c1b59ff22abb93bf898f9812e934ab75dcf7fe94e85bb6/mkdocstrings-0.28.0-py3-none-any.whl", hash = "sha256:84cf3dc910614781fe0fee46ce8006fde7df6cc7cca2e3f799895fb8a9170b39", size = 4700952 }, ] [package.optional-dependencies] @@ -891,16 +891,16 @@ python = [ [[package]] name = "mkdocstrings-python" -version = "1.13.0" +version = "1.14.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "griffe" }, { name = "mkdocs-autorefs" }, { name = "mkdocstrings" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ab/ae/32703e35d74040051c672400fd9f5f2b48a6ea094f5071dd8a0e3be35322/mkdocstrings_python-1.13.0.tar.gz", hash = "sha256:2dbd5757e8375b9720e81db16f52f1856bf59905428fd7ef88005d1370e2f64c", size = 185697 } +sdist = { url = "https://files.pythonhosted.org/packages/8f/64/bc658504b73b9ff064046e4ee3c551254d417d409b0d848c2054f2e8d528/mkdocstrings_python-1.14.4.tar.gz", hash = "sha256:12e1b1a3848554484896b602dda1096033adeb2715fef421f47d6a163d6c983d", size = 421537 } wheels = [ - { url = "https://files.pythonhosted.org/packages/51/23/d02d86553327296c3bf369d444194ea83410cce8f0e690565264f37f3261/mkdocstrings_python-1.13.0-py3-none-any.whl", hash = "sha256:b88bbb207bab4086434743849f8e796788b373bd32e7bfefbf8560ac45d88f97", size = 112254 }, + { url = "https://files.pythonhosted.org/packages/4b/49/22c0415d44dc7c1714b47944fbf0734306a99c992c84efd4c197e4f4dbc9/mkdocstrings_python-1.14.4-py3-none-any.whl", hash = "sha256:35d73fdf2079a2a4e2c8e8ff52976463a75d138f97ffadbc7d29108c6de11b35", size = 448488 }, ] [[package]] @@ -1007,45 +1007,49 @@ wheels = [ [[package]] name = "orjson" -version = "3.10.12" +version = "3.10.15" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e0/04/bb9f72987e7f62fb591d6c880c0caaa16238e4e530cbc3bdc84a7372d75f/orjson-3.10.12.tar.gz", hash = "sha256:0a78bbda3aea0f9f079057ee1ee8a1ecf790d4f1af88dd67493c6b8ee52506ff", size = 5438647 } +sdist = { url = "https://files.pythonhosted.org/packages/ae/f9/5dea21763eeff8c1590076918a446ea3d6140743e0e36f58f369928ed0f4/orjson-3.10.15.tar.gz", hash = "sha256:05ca7fe452a2e9d8d9d706a2984c95b9c2ebc5db417ce0b7a49b91d50642a23e", size = 5282482 } wheels = [ - { url = "https://files.pythonhosted.org/packages/d3/48/7c3cd094488f5a3bc58488555244609a8c4d105bc02f2b77e509debf0450/orjson-3.10.12-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a734c62efa42e7df94926d70fe7d37621c783dea9f707a98cdea796964d4cf74", size = 248687 }, - { url = "https://files.pythonhosted.org/packages/ff/90/e55f0e25c7fdd1f82551fe787f85df6f378170caca863c04c810cd8f2730/orjson-3.10.12-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:750f8b27259d3409eda8350c2919a58b0cfcd2054ddc1bd317a643afc646ef23", size = 136953 }, - { url = "https://files.pythonhosted.org/packages/2a/b3/109c020cf7fee747d400de53b43b183ca9d3ebda3906ad0b858eb5479718/orjson-3.10.12-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bb52c22bfffe2857e7aa13b4622afd0dd9d16ea7cc65fd2bf318d3223b1b6252", size = 149090 }, - { url = "https://files.pythonhosted.org/packages/96/d4/35c0275dc1350707d182a1b5da16d1184b9439848060af541285407f18f9/orjson-3.10.12-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:440d9a337ac8c199ff8251e100c62e9488924c92852362cd27af0e67308c16ef", size = 140480 }, - { url = "https://files.pythonhosted.org/packages/3b/79/f863ff460c291ad2d882cc3b580cc444bd4ec60c9df55f6901e6c9a3f519/orjson-3.10.12-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a9e15c06491c69997dfa067369baab3bf094ecb74be9912bdc4339972323f252", size = 156564 }, - { url = "https://files.pythonhosted.org/packages/98/7e/8d5835449ddd873424ee7b1c4ba73a0369c1055750990d824081652874d6/orjson-3.10.12-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:362d204ad4b0b8724cf370d0cd917bb2dc913c394030da748a3bb632445ce7c4", size = 131279 }, - { url = "https://files.pythonhosted.org/packages/46/f5/d34595b6d7f4f984c6fef289269a7f98abcdc2445ebdf90e9273487dda6b/orjson-3.10.12-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2b57cbb4031153db37b41622eac67329c7810e5f480fda4cfd30542186f006ae", size = 139764 }, - { url = "https://files.pythonhosted.org/packages/b3/5b/ee6e9ddeab54a7b7806768151c2090a2d36025bc346a944f51cf172ef7f7/orjson-3.10.12-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:165c89b53ef03ce0d7c59ca5c82fa65fe13ddf52eeb22e859e58c237d4e33b9b", size = 131915 }, - { url = "https://files.pythonhosted.org/packages/c4/45/febee5951aef6db5cd8cdb260548101d7ece0ca9d4ddadadf1766306b7a4/orjson-3.10.12-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:5dee91b8dfd54557c1a1596eb90bcd47dbcd26b0baaed919e6861f076583e9da", size = 415783 }, - { url = "https://files.pythonhosted.org/packages/27/a5/5a8569e49f3a6c093bee954a3de95062a231196f59e59df13a48e2420081/orjson-3.10.12-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:77a4e1cfb72de6f905bdff061172adfb3caf7a4578ebf481d8f0530879476c07", size = 142387 }, - { url = "https://files.pythonhosted.org/packages/6e/05/02550fb38c5bf758f3994f55401233a2ef304e175f473f2ac6dbf464cc8b/orjson-3.10.12-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:038d42c7bc0606443459b8fe2d1f121db474c49067d8d14c6a075bbea8bf14dd", size = 130664 }, - { url = "https://files.pythonhosted.org/packages/8c/f4/ba31019d0646ce51f7ac75af6dabf98fd89dbf8ad87a9086da34710738e7/orjson-3.10.12-cp311-none-win32.whl", hash = "sha256:03b553c02ab39bed249bedd4abe37b2118324d1674e639b33fab3d1dafdf4d79", size = 143623 }, - { url = "https://files.pythonhosted.org/packages/83/fe/babf08842b989acf4c46103fefbd7301f026423fab47e6f3ba07b54d7837/orjson-3.10.12-cp311-none-win_amd64.whl", hash = "sha256:8b8713b9e46a45b2af6b96f559bfb13b1e02006f4242c156cbadef27800a55a8", size = 135074 }, - { url = "https://files.pythonhosted.org/packages/a1/2f/989adcafad49afb535da56b95d8f87d82e748548b2a86003ac129314079c/orjson-3.10.12-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:53206d72eb656ca5ac7d3a7141e83c5bbd3ac30d5eccfe019409177a57634b0d", size = 248678 }, - { url = "https://files.pythonhosted.org/packages/69/b9/8c075e21a50c387649db262b618ebb7e4d40f4197b949c146fc225dd23da/orjson-3.10.12-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac8010afc2150d417ebda810e8df08dd3f544e0dd2acab5370cfa6bcc0662f8f", size = 136763 }, - { url = "https://files.pythonhosted.org/packages/87/d3/78edf10b4ab14c19f6d918cf46a145818f4aca2b5a1773c894c5490d3a4c/orjson-3.10.12-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed459b46012ae950dd2e17150e838ab08215421487371fa79d0eced8d1461d70", size = 149137 }, - { url = "https://files.pythonhosted.org/packages/16/81/5db8852bdf990a0ddc997fa8f16b80895b8cc77c0fe3701569ed2b4b9e78/orjson-3.10.12-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8dcb9673f108a93c1b52bfc51b0af422c2d08d4fc710ce9c839faad25020bb69", size = 140567 }, - { url = "https://files.pythonhosted.org/packages/fa/a6/9ce1e3e3db918512efadad489630c25841eb148513d21dab96f6b4157fa1/orjson-3.10.12-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:22a51ae77680c5c4652ebc63a83d5255ac7d65582891d9424b566fb3b5375ee9", size = 156620 }, - { url = "https://files.pythonhosted.org/packages/47/d4/05133d6bea24e292d2f7628b1e19986554f7d97b6412b3e51d812e38db2d/orjson-3.10.12-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:910fdf2ac0637b9a77d1aad65f803bac414f0b06f720073438a7bd8906298192", size = 131555 }, - { url = "https://files.pythonhosted.org/packages/b9/7a/b3fbffda8743135c7811e95dc2ab7cdbc5f04999b83c2957d046f1b3fac9/orjson-3.10.12-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:24ce85f7100160936bc2116c09d1a8492639418633119a2224114f67f63a4559", size = 139743 }, - { url = "https://files.pythonhosted.org/packages/b5/13/95bbcc9a6584aa083da5ce5004ce3d59ea362a542a0b0938d884fd8790b6/orjson-3.10.12-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8a76ba5fc8dd9c913640292df27bff80a685bed3a3c990d59aa6ce24c352f8fc", size = 131733 }, - { url = "https://files.pythonhosted.org/packages/e8/29/dddbb2ea6e7af426fcc3da65a370618a88141de75c6603313d70768d1df1/orjson-3.10.12-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:ff70ef093895fd53f4055ca75f93f047e088d1430888ca1229393a7c0521100f", size = 415788 }, - { url = "https://files.pythonhosted.org/packages/53/df/4aea59324ac539975919b4705ee086aced38e351a6eb3eea0f5071dd5661/orjson-3.10.12-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:f4244b7018b5753ecd10a6d324ec1f347da130c953a9c88432c7fbc8875d13be", size = 142347 }, - { url = "https://files.pythonhosted.org/packages/55/55/a52d83d7c49f8ff44e0daab10554490447d6c658771569e1c662aa7057fe/orjson-3.10.12-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:16135ccca03445f37921fa4b585cff9a58aa8d81ebcb27622e69bfadd220b32c", size = 130829 }, - { url = "https://files.pythonhosted.org/packages/a1/8b/b1beb1624dd4adf7d72e2d9b73c4b529e7851c0c754f17858ea13e368b33/orjson-3.10.12-cp312-none-win32.whl", hash = "sha256:2d879c81172d583e34153d524fcba5d4adafbab8349a7b9f16ae511c2cee8708", size = 143659 }, - { url = "https://files.pythonhosted.org/packages/13/91/634c9cd0bfc6a857fc8fab9bf1a1bd9f7f3345e0d6ca5c3d4569ceb6dcfa/orjson-3.10.12-cp312-none-win_amd64.whl", hash = "sha256:fc23f691fa0f5c140576b8c365bc942d577d861a9ee1142e4db468e4e17094fb", size = 135221 }, - { url = "https://files.pythonhosted.org/packages/1b/bb/3f560735f46fa6f875a9d7c4c2171a58cfb19f56a633d5ad5037a924f35f/orjson-3.10.12-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:47962841b2a8aa9a258b377f5188db31ba49af47d4003a32f55d6f8b19006543", size = 248662 }, - { url = "https://files.pythonhosted.org/packages/a3/df/54817902350636cc9270db20486442ab0e4db33b38555300a1159b439d16/orjson-3.10.12-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6334730e2532e77b6054e87ca84f3072bee308a45a452ea0bffbbbc40a67e296", size = 126055 }, - { url = "https://files.pythonhosted.org/packages/2e/77/55835914894e00332601a74540840f7665e81f20b3e2b9a97614af8565ed/orjson-3.10.12-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:accfe93f42713c899fdac2747e8d0d5c659592df2792888c6c5f829472e4f85e", size = 131507 }, - { url = "https://files.pythonhosted.org/packages/33/9e/b91288361898e3158062a876b5013c519a5d13e692ac7686e3486c4133ab/orjson-3.10.12-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a7974c490c014c48810d1dede6c754c3cc46598da758c25ca3b4001ac45b703f", size = 131686 }, - { url = "https://files.pythonhosted.org/packages/b2/15/08ce117d60a4d2d3fd24e6b21db463139a658e9f52d22c9c30af279b4187/orjson-3.10.12-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:3f250ce7727b0b2682f834a3facff88e310f52f07a5dcfd852d99637d386e79e", size = 415710 }, - { url = "https://files.pythonhosted.org/packages/71/af/c09da5ed58f9c002cf83adff7a4cdf3e6cee742aa9723395f8dcdb397233/orjson-3.10.12-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:f31422ff9486ae484f10ffc51b5ab2a60359e92d0716fcce1b3593d7bb8a9af6", size = 142305 }, - { url = "https://files.pythonhosted.org/packages/17/d1/8612038d44f33fae231e9ba480d273bac2b0383ce9e77cb06bede1224ae3/orjson-3.10.12-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5f29c5d282bb2d577c2a6bbde88d8fdcc4919c593f806aac50133f01b733846e", size = 130815 }, - { url = "https://files.pythonhosted.org/packages/67/2c/d5f87834be3591555cfaf9aecdf28f480a6f0b4afeaac53bad534bf9518f/orjson-3.10.12-cp313-none-win32.whl", hash = "sha256:f45653775f38f63dc0e6cd4f14323984c3149c05d6007b58cb154dd080ddc0dc", size = 143664 }, - { url = "https://files.pythonhosted.org/packages/6a/05/7d768fa3ca23c9b3e1e09117abeded1501119f1d8de0ab722938c91ab25d/orjson-3.10.12-cp313-none-win_amd64.whl", hash = "sha256:229994d0c376d5bdc91d92b3c9e6be2f1fbabd4cc1b59daae1443a46ee5e9825", size = 134944 }, + { url = "https://files.pythonhosted.org/packages/7a/a2/21b25ce4a2c71dbb90948ee81bd7a42b4fbfc63162e57faf83157d5540ae/orjson-3.10.15-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:c4cc83960ab79a4031f3119cc4b1a1c627a3dc09df125b27c4201dff2af7eaa6", size = 249533 }, + { url = "https://files.pythonhosted.org/packages/b2/85/2076fc12d8225698a51278009726750c9c65c846eda741e77e1761cfef33/orjson-3.10.15-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ddbeef2481d895ab8be5185f2432c334d6dec1f5d1933a9c83014d188e102cef", size = 125230 }, + { url = "https://files.pythonhosted.org/packages/06/df/a85a7955f11274191eccf559e8481b2be74a7c6d43075d0a9506aa80284d/orjson-3.10.15-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9e590a0477b23ecd5b0ac865b1b907b01b3c5535f5e8a8f6ab0e503efb896334", size = 150148 }, + { url = "https://files.pythonhosted.org/packages/37/b3/94c55625a29b8767c0eed194cb000b3787e3c23b4cdd13be17bae6ccbb4b/orjson-3.10.15-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a6be38bd103d2fd9bdfa31c2720b23b5d47c6796bcb1d1b598e3924441b4298d", size = 139749 }, + { url = "https://files.pythonhosted.org/packages/53/ba/c608b1e719971e8ddac2379f290404c2e914cf8e976369bae3cad88768b1/orjson-3.10.15-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ff4f6edb1578960ed628a3b998fa54d78d9bb3e2eb2cfc5c2a09732431c678d0", size = 154558 }, + { url = "https://files.pythonhosted.org/packages/b2/c4/c1fb835bb23ad788a39aa9ebb8821d51b1c03588d9a9e4ca7de5b354fdd5/orjson-3.10.15-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b0482b21d0462eddd67e7fce10b89e0b6ac56570424662b685a0d6fccf581e13", size = 130349 }, + { url = "https://files.pythonhosted.org/packages/78/14/bb2b48b26ab3c570b284eb2157d98c1ef331a8397f6c8bd983b270467f5c/orjson-3.10.15-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:bb5cc3527036ae3d98b65e37b7986a918955f85332c1ee07f9d3f82f3a6899b5", size = 138513 }, + { url = "https://files.pythonhosted.org/packages/4a/97/d5b353a5fe532e92c46467aa37e637f81af8468aa894cd77d2ec8a12f99e/orjson-3.10.15-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d569c1c462912acdd119ccbf719cf7102ea2c67dd03b99edcb1a3048651ac96b", size = 130942 }, + { url = "https://files.pythonhosted.org/packages/b5/5d/a067bec55293cca48fea8b9928cfa84c623be0cce8141d47690e64a6ca12/orjson-3.10.15-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:1e6d33efab6b71d67f22bf2962895d3dc6f82a6273a965fab762e64fa90dc399", size = 414717 }, + { url = "https://files.pythonhosted.org/packages/6f/9a/1485b8b05c6b4c4db172c438cf5db5dcfd10e72a9bc23c151a1137e763e0/orjson-3.10.15-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:c33be3795e299f565681d69852ac8c1bc5c84863c0b0030b2b3468843be90388", size = 141033 }, + { url = "https://files.pythonhosted.org/packages/f8/d2/fc67523656e43a0c7eaeae9007c8b02e86076b15d591e9be11554d3d3138/orjson-3.10.15-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:eea80037b9fae5339b214f59308ef0589fc06dc870578b7cce6d71eb2096764c", size = 129720 }, + { url = "https://files.pythonhosted.org/packages/79/42/f58c7bd4e5b54da2ce2ef0331a39ccbbaa7699b7f70206fbf06737c9ed7d/orjson-3.10.15-cp311-cp311-win32.whl", hash = "sha256:d5ac11b659fd798228a7adba3e37c010e0152b78b1982897020a8e019a94882e", size = 142473 }, + { url = "https://files.pythonhosted.org/packages/00/f8/bb60a4644287a544ec81df1699d5b965776bc9848d9029d9f9b3402ac8bb/orjson-3.10.15-cp311-cp311-win_amd64.whl", hash = "sha256:cf45e0214c593660339ef63e875f32ddd5aa3b4adc15e662cdb80dc49e194f8e", size = 133570 }, + { url = "https://files.pythonhosted.org/packages/66/85/22fe737188905a71afcc4bf7cc4c79cd7f5bbe9ed1fe0aac4ce4c33edc30/orjson-3.10.15-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:9d11c0714fc85bfcf36ada1179400862da3288fc785c30e8297844c867d7505a", size = 249504 }, + { url = "https://files.pythonhosted.org/packages/48/b7/2622b29f3afebe938a0a9037e184660379797d5fd5234e5998345d7a5b43/orjson-3.10.15-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dba5a1e85d554e3897fa9fe6fbcff2ed32d55008973ec9a2b992bd9a65d2352d", size = 125080 }, + { url = "https://files.pythonhosted.org/packages/ce/8f/0b72a48f4403d0b88b2a41450c535b3e8989e8a2d7800659a967efc7c115/orjson-3.10.15-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7723ad949a0ea502df656948ddd8b392780a5beaa4c3b5f97e525191b102fff0", size = 150121 }, + { url = "https://files.pythonhosted.org/packages/06/ec/acb1a20cd49edb2000be5a0404cd43e3c8aad219f376ac8c60b870518c03/orjson-3.10.15-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6fd9bc64421e9fe9bd88039e7ce8e58d4fead67ca88e3a4014b143cec7684fd4", size = 139796 }, + { url = "https://files.pythonhosted.org/packages/33/e1/f7840a2ea852114b23a52a1c0b2bea0a1ea22236efbcdb876402d799c423/orjson-3.10.15-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dadba0e7b6594216c214ef7894c4bd5f08d7c0135f4dd0145600be4fbcc16767", size = 154636 }, + { url = "https://files.pythonhosted.org/packages/fa/da/31543337febd043b8fa80a3b67de627669b88c7b128d9ad4cc2ece005b7a/orjson-3.10.15-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b48f59114fe318f33bbaee8ebeda696d8ccc94c9e90bc27dbe72153094e26f41", size = 130621 }, + { url = "https://files.pythonhosted.org/packages/ed/78/66115dc9afbc22496530d2139f2f4455698be444c7c2475cb48f657cefc9/orjson-3.10.15-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:035fb83585e0f15e076759b6fedaf0abb460d1765b6a36f48018a52858443514", size = 138516 }, + { url = "https://files.pythonhosted.org/packages/22/84/cd4f5fb5427ffcf823140957a47503076184cb1ce15bcc1165125c26c46c/orjson-3.10.15-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d13b7fe322d75bf84464b075eafd8e7dd9eae05649aa2a5354cfa32f43c59f17", size = 130762 }, + { url = "https://files.pythonhosted.org/packages/93/1f/67596b711ba9f56dd75d73b60089c5c92057f1130bb3a25a0f53fb9a583b/orjson-3.10.15-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:7066b74f9f259849629e0d04db6609db4cf5b973248f455ba5d3bd58a4daaa5b", size = 414700 }, + { url = "https://files.pythonhosted.org/packages/7c/0c/6a3b3271b46443d90efb713c3e4fe83fa8cd71cda0d11a0f69a03f437c6e/orjson-3.10.15-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:88dc3f65a026bd3175eb157fea994fca6ac7c4c8579fc5a86fc2114ad05705b7", size = 141077 }, + { url = "https://files.pythonhosted.org/packages/3b/9b/33c58e0bfc788995eccd0d525ecd6b84b40d7ed182dd0751cd4c1322ac62/orjson-3.10.15-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b342567e5465bd99faa559507fe45e33fc76b9fb868a63f1642c6bc0735ad02a", size = 129898 }, + { url = "https://files.pythonhosted.org/packages/01/c1/d577ecd2e9fa393366a1ea0a9267f6510d86e6c4bb1cdfb9877104cac44c/orjson-3.10.15-cp312-cp312-win32.whl", hash = "sha256:0a4f27ea5617828e6b58922fdbec67b0aa4bb844e2d363b9244c47fa2180e665", size = 142566 }, + { url = "https://files.pythonhosted.org/packages/ed/eb/a85317ee1732d1034b92d56f89f1de4d7bf7904f5c8fb9dcdd5b1c83917f/orjson-3.10.15-cp312-cp312-win_amd64.whl", hash = "sha256:ef5b87e7aa9545ddadd2309efe6824bd3dd64ac101c15dae0f2f597911d46eaa", size = 133732 }, + { url = "https://files.pythonhosted.org/packages/06/10/fe7d60b8da538e8d3d3721f08c1b7bff0491e8fa4dd3bf11a17e34f4730e/orjson-3.10.15-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:bae0e6ec2b7ba6895198cd981b7cca95d1487d0147c8ed751e5632ad16f031a6", size = 249399 }, + { url = "https://files.pythonhosted.org/packages/6b/83/52c356fd3a61abd829ae7e4366a6fe8e8863c825a60d7ac5156067516edf/orjson-3.10.15-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f93ce145b2db1252dd86af37d4165b6faa83072b46e3995ecc95d4b2301b725a", size = 125044 }, + { url = "https://files.pythonhosted.org/packages/55/b2/d06d5901408e7ded1a74c7c20d70e3a127057a6d21355f50c90c0f337913/orjson-3.10.15-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7c203f6f969210128af3acae0ef9ea6aab9782939f45f6fe02d05958fe761ef9", size = 150066 }, + { url = "https://files.pythonhosted.org/packages/75/8c/60c3106e08dc593a861755781c7c675a566445cc39558677d505878d879f/orjson-3.10.15-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8918719572d662e18b8af66aef699d8c21072e54b6c82a3f8f6404c1f5ccd5e0", size = 139737 }, + { url = "https://files.pythonhosted.org/packages/6a/8c/ae00d7d0ab8a4490b1efeb01ad4ab2f1982e69cc82490bf8093407718ff5/orjson-3.10.15-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f71eae9651465dff70aa80db92586ad5b92df46a9373ee55252109bb6b703307", size = 154804 }, + { url = "https://files.pythonhosted.org/packages/22/86/65dc69bd88b6dd254535310e97bc518aa50a39ef9c5a2a5d518e7a223710/orjson-3.10.15-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e117eb299a35f2634e25ed120c37c641398826c2f5a3d3cc39f5993b96171b9e", size = 130583 }, + { url = "https://files.pythonhosted.org/packages/bb/00/6fe01ededb05d52be42fabb13d93a36e51f1fd9be173bd95707d11a8a860/orjson-3.10.15-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:13242f12d295e83c2955756a574ddd6741c81e5b99f2bef8ed8d53e47a01e4b7", size = 138465 }, + { url = "https://files.pythonhosted.org/packages/db/2f/4cc151c4b471b0cdc8cb29d3eadbce5007eb0475d26fa26ed123dca93b33/orjson-3.10.15-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:7946922ada8f3e0b7b958cc3eb22cfcf6c0df83d1fe5521b4a100103e3fa84c8", size = 130742 }, + { url = "https://files.pythonhosted.org/packages/9f/13/8a6109e4b477c518498ca37963d9c0eb1508b259725553fb53d53b20e2ea/orjson-3.10.15-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:b7155eb1623347f0f22c38c9abdd738b287e39b9982e1da227503387b81b34ca", size = 414669 }, + { url = "https://files.pythonhosted.org/packages/22/7b/1d229d6d24644ed4d0a803de1b0e2df832032d5beda7346831c78191b5b2/orjson-3.10.15-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:208beedfa807c922da4e81061dafa9c8489c6328934ca2a562efa707e049e561", size = 141043 }, + { url = "https://files.pythonhosted.org/packages/cc/d3/6dc91156cf12ed86bed383bcb942d84d23304a1e57b7ab030bf60ea130d6/orjson-3.10.15-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:eca81f83b1b8c07449e1d6ff7074e82e3fd6777e588f1a6632127f286a968825", size = 129826 }, + { url = "https://files.pythonhosted.org/packages/b3/38/c47c25b86f6996f1343be721b6ea4367bc1c8bc0fc3f6bbcd995d18cb19d/orjson-3.10.15-cp313-cp313-win32.whl", hash = "sha256:c03cd6eea1bd3b949d0d007c8d57049aa2b39bd49f58b4b2af571a5d3833d890", size = 142542 }, + { url = "https://files.pythonhosted.org/packages/27/f1/1d7ec15b20f8ce9300bc850de1e059132b88990e46cd0ccac29cbf11e4f9/orjson-3.10.15-cp313-cp313-win_amd64.whl", hash = "sha256:fd56a26a04f6ba5fb2045b0acc487a63162a958ed837648c5781e1fe3316cfbf", size = 133444 }, ] [[package]] @@ -1307,16 +1311,16 @@ wheels = [ [[package]] name = "pygments" -version = "2.18.0" +version = "2.19.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/8e/62/8336eff65bcbc8e4cb5d05b55faf041285951b6e80f33e2bff2024788f31/pygments-2.18.0.tar.gz", hash = "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199", size = 4891905 } +sdist = { url = "https://files.pythonhosted.org/packages/7c/2d/c3338d48ea6cc0feb8446d8e6937e1408088a72a39937982cc6111d17f84/pygments-2.19.1.tar.gz", hash = "sha256:61c16d2a8576dc0649d9f39e089b5f02bcd27fba10d8fb4dcc28173f7a45151f", size = 4968581 } wheels = [ - { url = "https://files.pythonhosted.org/packages/f7/3f/01c8b82017c199075f8f788d0d906b9ffbbc5a47dc9918a945e13d5a2bda/pygments-2.18.0-py3-none-any.whl", hash = "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a", size = 1205513 }, + { url = "https://files.pythonhosted.org/packages/8a/0b/9fcc47d19c48b59121088dd6da2488a49d5f72dacf8262e2790a1d2c7d15/pygments-2.19.1-py3-none-any.whl", hash = "sha256:9ea1544ad55cecf4b8242fab6dd35a93bbce657034b0611ee383099054ab6d8c", size = 1225293 }, ] [[package]] name = "pylint" -version = "3.3.3" +version = "3.3.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "astroid" }, @@ -1327,22 +1331,22 @@ dependencies = [ { name = "platformdirs" }, { name = "tomlkit" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/17/fd/e9a739afac274a39596bbe562e9d966db6f3917fdb2bd7322ffc56da0ba2/pylint-3.3.3.tar.gz", hash = "sha256:07c607523b17e6d16e2ae0d7ef59602e332caa762af64203c24b41c27139f36a", size = 1516550 } +sdist = { url = "https://files.pythonhosted.org/packages/ab/b9/50be49afc91469f832c4bf12318ab4abe56ee9aa3700a89aad5359ad195f/pylint-3.3.4.tar.gz", hash = "sha256:74ae7a38b177e69a9b525d0794bd8183820bfa7eb68cc1bee6e8ed22a42be4ce", size = 1518905 } wheels = [ - { url = "https://files.pythonhosted.org/packages/91/e1/26d55acea92b1ea4d33672e48f09ceeb274e84d7d542a4fb9a32a556db46/pylint-3.3.3-py3-none-any.whl", hash = "sha256:26e271a2bc8bce0fc23833805a9076dd9b4d5194e2a02164942cb3cdc37b4183", size = 521918 }, + { url = "https://files.pythonhosted.org/packages/0d/8b/eef15df5f4e7aa393de31feb96ca9a3d6639669bd59d589d0685d5ef4e62/pylint-3.3.4-py3-none-any.whl", hash = "sha256:289e6a1eb27b453b08436478391a48cd53bb0efb824873f949e709350f3de018", size = 522280 }, ] [[package]] name = "pymdown-extensions" -version = "10.14.1" +version = "10.14.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "markdown" }, { name = "pyyaml" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/e7/24/f7a412dc1630b1a6d7b288e7c736215ce878ee4aad24359f7f67b53bbaa9/pymdown_extensions-10.14.1.tar.gz", hash = "sha256:b65801996a0cd4f42a3110810c306c45b7313c09b0610a6f773730f2a9e3c96b", size = 845243 } +sdist = { url = "https://files.pythonhosted.org/packages/7c/44/e6de2fdc880ad0ec7547ca2e087212be815efbc9a425a8d5ba9ede602cbb/pymdown_extensions-10.14.3.tar.gz", hash = "sha256:41e576ce3f5d650be59e900e4ceff231e0aed2a88cf30acaee41e02f063a061b", size = 846846 } wheels = [ - { url = "https://files.pythonhosted.org/packages/09/fb/79a8d27966e90feeeb686395c8b1bff8221727abcbd80d2485841393a955/pymdown_extensions-10.14.1-py3-none-any.whl", hash = "sha256:637951cbfbe9874ba28134fb3ce4b8bcadd6aca89ac4998ec29dcbafd554ae08", size = 264283 }, + { url = "https://files.pythonhosted.org/packages/eb/f5/b9e2a42aa8f9e34d52d66de87941ecd236570c7ed2e87775ed23bbe4e224/pymdown_extensions-10.14.3-py3-none-any.whl", hash = "sha256:05e0bee73d64b9c71a4ae17c72abc2f700e8bc8403755a00580b49a4e9f189e9", size = 264467 }, ] [[package]] @@ -1359,11 +1363,11 @@ wheels = [ [[package]] name = "pytz" -version = "2024.2" +version = "2025.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/3a/31/3c70bf7603cc2dca0f19bdc53b4537a797747a58875b552c8c413d963a3f/pytz-2024.2.tar.gz", hash = "sha256:2aa355083c50a0f93fa581709deac0c9ad65cca8a9e9beac660adcbd493c798a", size = 319692 } +sdist = { url = "https://files.pythonhosted.org/packages/5f/57/df1c9157c8d5a05117e455d66fd7cf6dbc46974f832b1058ed4856785d8a/pytz-2025.1.tar.gz", hash = "sha256:c2db42be2a2518b28e65f9207c4d05e6ff547d1efa4086469ef855e4ab70178e", size = 319617 } wheels = [ - { url = "https://files.pythonhosted.org/packages/11/c3/005fcca25ce078d2cc29fd559379817424e94885510568bc1bc53d7d5846/pytz-2024.2-py2.py3-none-any.whl", hash = "sha256:31c7c1817eb7fae7ca4b8c7ee50c72f93aa2dd863de768e1ef4245d426aa0725", size = 508002 }, + { url = "https://files.pythonhosted.org/packages/eb/38/ac33370d784287baa1c3d538978b5e2ea064d4c1b93ffbd12826c190dd10/pytz-2025.1-py2.py3-none-any.whl", hash = "sha256:89dd22dca55b46eac6eda23b2d72721bf1bdfef212645d81513ef5d03038de57", size = 507930 }, ] [[package]] @@ -1477,7 +1481,7 @@ wheels = [ [[package]] name = "red-discordbot" -version = "3.5.14" +version = "3.5.15" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "aiohttp" }, @@ -1518,9 +1522,9 @@ dependencies = [ { name = "yarl" }, { name = "zipp", marker = "python_full_version >= '3.12'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ea/b6/b680024b91c8dbf89c66aa1f43a7599b155e6e69101641a9da66d5907011/red_discordbot-3.5.14.tar.gz", hash = "sha256:b603b59a75429fa37bf6bc303f08a95e725c339599ad044278bed8337429c110", size = 3681606 } +sdist = { url = "https://files.pythonhosted.org/packages/55/69/42940946a3bd3a099f61ee9e6fa78e9ab7cf7e671a328506497a879b34fe/red_discordbot-3.5.15.tar.gz", hash = "sha256:2326712065b45ec61aff5d0943620efd6212c69ae08a2ad8fe673c859e34e921", size = 3685486 } wheels = [ - { url = "https://files.pythonhosted.org/packages/9d/0a/5cb23863863ed70bc60937fe16f4626b9cb22fe0afd74ac67a0f543ed33a/Red_DiscordBot-3.5.14-py3-none-any.whl", hash = "sha256:9be0806c21cf83c0e972b331583b088786b5f3c2d8221eefab5adbf1ac9b761f", size = 5772233 }, + { url = "https://files.pythonhosted.org/packages/50/f5/f0b8ebdc3f1a072a846dd0388cf67d5acdaa4f300e36dd78af1b704181dd/Red_DiscordBot-3.5.15-py3-none-any.whl", hash = "sha256:e08d96ee270a36feb2331435a6173777a514e268263d5bb4839fff713815491c", size = 5776852 }, ] [[package]] @@ -1620,27 +1624,27 @@ wheels = [ [[package]] name = "ruff" -version = "0.9.3" +version = "0.9.4" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/1e/7f/60fda2eec81f23f8aa7cbbfdf6ec2ca11eb11c273827933fb2541c2ce9d8/ruff-0.9.3.tar.gz", hash = "sha256:8293f89985a090ebc3ed1064df31f3b4b56320cdfcec8b60d3295bddb955c22a", size = 3586740 } +sdist = { url = "https://files.pythonhosted.org/packages/c0/17/529e78f49fc6f8076f50d985edd9a2cf011d1dbadb1cdeacc1d12afc1d26/ruff-0.9.4.tar.gz", hash = "sha256:6907ee3529244bb0ed066683e075f09285b38dd5b4039370df6ff06041ca19e7", size = 3599458 } wheels = [ - { url = "https://files.pythonhosted.org/packages/f9/77/4fb790596d5d52c87fd55b7160c557c400e90f6116a56d82d76e95d9374a/ruff-0.9.3-py3-none-linux_armv6l.whl", hash = "sha256:7f39b879064c7d9670197d91124a75d118d00b0990586549949aae80cdc16624", size = 11656815 }, - { url = "https://files.pythonhosted.org/packages/a2/a8/3338ecb97573eafe74505f28431df3842c1933c5f8eae615427c1de32858/ruff-0.9.3-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:a187171e7c09efa4b4cc30ee5d0d55a8d6c5311b3e1b74ac5cb96cc89bafc43c", size = 11594821 }, - { url = "https://files.pythonhosted.org/packages/8e/89/320223c3421962762531a6b2dd58579b858ca9916fb2674874df5e97d628/ruff-0.9.3-py3-none-macosx_11_0_arm64.whl", hash = "sha256:c59ab92f8e92d6725b7ded9d4a31be3ef42688a115c6d3da9457a5bda140e2b4", size = 11040475 }, - { url = "https://files.pythonhosted.org/packages/b2/bd/1d775eac5e51409535804a3a888a9623e87a8f4b53e2491580858a083692/ruff-0.9.3-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2dc153c25e715be41bb228bc651c1e9b1a88d5c6e5ed0194fa0dfea02b026439", size = 11856207 }, - { url = "https://files.pythonhosted.org/packages/7f/c6/3e14e09be29587393d188454064a4aa85174910d16644051a80444e4fd88/ruff-0.9.3-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:646909a1e25e0dc28fbc529eab8eb7bb583079628e8cbe738192853dbbe43af5", size = 11420460 }, - { url = "https://files.pythonhosted.org/packages/ef/42/b7ca38ffd568ae9b128a2fa76353e9a9a3c80ef19746408d4ce99217ecc1/ruff-0.9.3-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5a5a46e09355695fbdbb30ed9889d6cf1c61b77b700a9fafc21b41f097bfbba4", size = 12605472 }, - { url = "https://files.pythonhosted.org/packages/a6/a1/3167023f23e3530fde899497ccfe239e4523854cb874458ac082992d206c/ruff-0.9.3-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:c4bb09d2bbb394e3730d0918c00276e79b2de70ec2a5231cd4ebb51a57df9ba1", size = 13243123 }, - { url = "https://files.pythonhosted.org/packages/d0/b4/3c600758e320f5bf7de16858502e849f4216cb0151f819fa0d1154874802/ruff-0.9.3-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:96a87ec31dc1044d8c2da2ebbed1c456d9b561e7d087734336518181b26b3aa5", size = 12744650 }, - { url = "https://files.pythonhosted.org/packages/be/38/266fbcbb3d0088862c9bafa8b1b99486691d2945a90b9a7316336a0d9a1b/ruff-0.9.3-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9bb7554aca6f842645022fe2d301c264e6925baa708b392867b7a62645304df4", size = 14458585 }, - { url = "https://files.pythonhosted.org/packages/63/a6/47fd0e96990ee9b7a4abda62de26d291bd3f7647218d05b7d6d38af47c30/ruff-0.9.3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cabc332b7075a914ecea912cd1f3d4370489c8018f2c945a30bcc934e3bc06a6", size = 12419624 }, - { url = "https://files.pythonhosted.org/packages/84/5d/de0b7652e09f7dda49e1a3825a164a65f4998175b6486603c7601279baad/ruff-0.9.3-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:33866c3cc2a575cbd546f2cd02bdd466fed65118e4365ee538a3deffd6fcb730", size = 11843238 }, - { url = "https://files.pythonhosted.org/packages/9e/be/3f341ceb1c62b565ec1fb6fd2139cc40b60ae6eff4b6fb8f94b1bb37c7a9/ruff-0.9.3-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:006e5de2621304c8810bcd2ee101587712fa93b4f955ed0985907a36c427e0c2", size = 11484012 }, - { url = "https://files.pythonhosted.org/packages/a3/c8/ff8acbd33addc7e797e702cf00bfde352ab469723720c5607b964491d5cf/ruff-0.9.3-py3-none-musllinux_1_2_i686.whl", hash = "sha256:ba6eea4459dbd6b1be4e6bfc766079fb9b8dd2e5a35aff6baee4d9b1514ea519", size = 12038494 }, - { url = "https://files.pythonhosted.org/packages/73/b1/8d9a2c0efbbabe848b55f877bc10c5001a37ab10aca13c711431673414e5/ruff-0.9.3-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:90230a6b8055ad47d3325e9ee8f8a9ae7e273078a66401ac66df68943ced029b", size = 12473639 }, - { url = "https://files.pythonhosted.org/packages/cb/44/a673647105b1ba6da9824a928634fe23186ab19f9d526d7bdf278cd27bc3/ruff-0.9.3-py3-none-win32.whl", hash = "sha256:eabe5eb2c19a42f4808c03b82bd313fc84d4e395133fb3fc1b1516170a31213c", size = 9834353 }, - { url = "https://files.pythonhosted.org/packages/c3/01/65cadb59bf8d4fbe33d1a750103e6883d9ef302f60c28b73b773092fbde5/ruff-0.9.3-py3-none-win_amd64.whl", hash = "sha256:040ceb7f20791dfa0e78b4230ee9dce23da3b64dd5848e40e3bf3ab76468dcf4", size = 10821444 }, - { url = "https://files.pythonhosted.org/packages/69/cb/b3fe58a136a27d981911cba2f18e4b29f15010623b79f0f2510fd0d31fd3/ruff-0.9.3-py3-none-win_arm64.whl", hash = "sha256:800d773f6d4d33b0a3c60e2c6ae8f4c202ea2de056365acfa519aa48acf28e0b", size = 10038168 }, + { url = "https://files.pythonhosted.org/packages/b6/f8/3fafb7804d82e0699a122101b5bee5f0d6e17c3a806dcbc527bb7d3f5b7a/ruff-0.9.4-py3-none-linux_armv6l.whl", hash = "sha256:64e73d25b954f71ff100bb70f39f1ee09e880728efb4250c632ceed4e4cdf706", size = 11668400 }, + { url = "https://files.pythonhosted.org/packages/2e/a6/2efa772d335da48a70ab2c6bb41a096c8517ca43c086ea672d51079e3d1f/ruff-0.9.4-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:6ce6743ed64d9afab4fafeaea70d3631b4d4b28b592db21a5c2d1f0ef52934bf", size = 11628395 }, + { url = "https://files.pythonhosted.org/packages/dc/d7/cd822437561082f1c9d7225cc0d0fbb4bad117ad7ac3c41cd5d7f0fa948c/ruff-0.9.4-py3-none-macosx_11_0_arm64.whl", hash = "sha256:54499fb08408e32b57360f6f9de7157a5fec24ad79cb3f42ef2c3f3f728dfe2b", size = 11090052 }, + { url = "https://files.pythonhosted.org/packages/9e/67/3660d58e893d470abb9a13f679223368ff1684a4ef40f254a0157f51b448/ruff-0.9.4-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:37c892540108314a6f01f105040b5106aeb829fa5fb0561d2dcaf71485021137", size = 11882221 }, + { url = "https://files.pythonhosted.org/packages/79/d1/757559995c8ba5f14dfec4459ef2dd3fcea82ac43bc4e7c7bf47484180c0/ruff-0.9.4-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:de9edf2ce4b9ddf43fd93e20ef635a900e25f622f87ed6e3047a664d0e8f810e", size = 11424862 }, + { url = "https://files.pythonhosted.org/packages/c0/96/7915a7c6877bb734caa6a2af424045baf6419f685632469643dbd8eb2958/ruff-0.9.4-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:87c90c32357c74f11deb7fbb065126d91771b207bf9bfaaee01277ca59b574ec", size = 12626735 }, + { url = "https://files.pythonhosted.org/packages/0e/cc/dadb9b35473d7cb17c7ffe4737b4377aeec519a446ee8514123ff4a26091/ruff-0.9.4-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:56acd6c694da3695a7461cc55775f3a409c3815ac467279dfa126061d84b314b", size = 13255976 }, + { url = "https://files.pythonhosted.org/packages/5f/c3/ad2dd59d3cabbc12df308cced780f9c14367f0321e7800ca0fe52849da4c/ruff-0.9.4-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e0c93e7d47ed951b9394cf352d6695b31498e68fd5782d6cbc282425655f687a", size = 12752262 }, + { url = "https://files.pythonhosted.org/packages/c7/17/5f1971e54bd71604da6788efd84d66d789362b1105e17e5ccc53bba0289b/ruff-0.9.4-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1d4c8772670aecf037d1bf7a07c39106574d143b26cfe5ed1787d2f31e800214", size = 14401648 }, + { url = "https://files.pythonhosted.org/packages/30/24/6200b13ea611b83260501b6955b764bb320e23b2b75884c60ee7d3f0b68e/ruff-0.9.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bfc5f1d7afeda8d5d37660eeca6d389b142d7f2b5a1ab659d9214ebd0e025231", size = 12414702 }, + { url = "https://files.pythonhosted.org/packages/34/cb/f5d50d0c4ecdcc7670e348bd0b11878154bc4617f3fdd1e8ad5297c0d0ba/ruff-0.9.4-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:faa935fc00ae854d8b638c16a5f1ce881bc3f67446957dd6f2af440a5fc8526b", size = 11859608 }, + { url = "https://files.pythonhosted.org/packages/d6/f4/9c8499ae8426da48363bbb78d081b817b0f64a9305f9b7f87eab2a8fb2c1/ruff-0.9.4-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:a6c634fc6f5a0ceae1ab3e13c58183978185d131a29c425e4eaa9f40afe1e6d6", size = 11485702 }, + { url = "https://files.pythonhosted.org/packages/18/59/30490e483e804ccaa8147dd78c52e44ff96e1c30b5a95d69a63163cdb15b/ruff-0.9.4-py3-none-musllinux_1_2_i686.whl", hash = "sha256:433dedf6ddfdec7f1ac7575ec1eb9844fa60c4c8c2f8887a070672b8d353d34c", size = 12067782 }, + { url = "https://files.pythonhosted.org/packages/3d/8c/893fa9551760b2f8eb2a351b603e96f15af167ceaf27e27ad873570bc04c/ruff-0.9.4-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:d612dbd0f3a919a8cc1d12037168bfa536862066808960e0cc901404b77968f0", size = 12483087 }, + { url = "https://files.pythonhosted.org/packages/23/15/f6751c07c21ca10e3f4a51ea495ca975ad936d780c347d9808bcedbd7182/ruff-0.9.4-py3-none-win32.whl", hash = "sha256:db1192ddda2200671f9ef61d9597fcef89d934f5d1705e571a93a67fb13a4402", size = 9852302 }, + { url = "https://files.pythonhosted.org/packages/12/41/2d2d2c6a72e62566f730e49254f602dfed23019c33b5b21ea8f8917315a1/ruff-0.9.4-py3-none-win_amd64.whl", hash = "sha256:05bebf4cdbe3ef75430d26c375773978950bbf4ee3c95ccb5448940dc092408e", size = 10850051 }, + { url = "https://files.pythonhosted.org/packages/c6/e6/3d6ec3bc3d254e7f005c543a661a41c3e788976d0e52a1ada195bd664344/ruff-0.9.4-py3-none-win_arm64.whl", hash = "sha256:585792f1e81509e38ac5123492f8875fbc36f3ede8185af0a26df348e5154f41", size = 10078251 }, ] [[package]] From 1224d2b60fed3a2ae03b76e878ba25869ecf5df1 Mon Sep 17 00:00:00 2001 From: cswimr Date: Thu, 6 Feb 2025 06:40:49 -0600 Subject: [PATCH 43/53] chore(deps): update dependencies --- uv.lock | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/uv.lock b/uv.lock index 75ae73c..c11d993 100644 --- a/uv.lock +++ b/uv.lock @@ -891,16 +891,16 @@ python = [ [[package]] name = "mkdocstrings-python" -version = "1.14.4" +version = "1.14.5" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "griffe" }, { name = "mkdocs-autorefs" }, { name = "mkdocstrings" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/8f/64/bc658504b73b9ff064046e4ee3c551254d417d409b0d848c2054f2e8d528/mkdocstrings_python-1.14.4.tar.gz", hash = "sha256:12e1b1a3848554484896b602dda1096033adeb2715fef421f47d6a163d6c983d", size = 421537 } +sdist = { url = "https://files.pythonhosted.org/packages/4e/00/75f8badeca7bcc06dd2ca0a09b98998b228beb2109f6dd4e9155ea6a6cc7/mkdocstrings_python-1.14.5.tar.gz", hash = "sha256:8582eeac8cce952f395d76ec636fc814757cba7d8458aa75ba0529a3aa10d98c", size = 421738 } wheels = [ - { url = "https://files.pythonhosted.org/packages/4b/49/22c0415d44dc7c1714b47944fbf0734306a99c992c84efd4c197e4f4dbc9/mkdocstrings_python-1.14.4-py3-none-any.whl", hash = "sha256:35d73fdf2079a2a4e2c8e8ff52976463a75d138f97ffadbc7d29108c6de11b35", size = 448488 }, + { url = "https://files.pythonhosted.org/packages/17/1e/c970d43d2dc844b7dfabb5daf24bc1c8ffdb40c56e3ec65d6dc78879ce16/mkdocstrings_python-1.14.5-py3-none-any.whl", hash = "sha256:ac394f273ae298aeaa6be4506768f05e61bd7c8119437ea98553354b1185c469", size = 448584 }, ] [[package]] @@ -1081,9 +1081,9 @@ wheels = [ [[package]] name = "peewee" -version = "3.17.8" +version = "3.17.9" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b4/dc/832bcf4ea5ee2ebc4ea42ef36e44a451de5d80f8b9858bf2066e30738c67/peewee-3.17.8.tar.gz", hash = "sha256:ce1d05db3438830b989a1b9d0d0aa4e7f6134d5f6fd57686eeaa26a3e6485a8c", size = 948249 } +sdist = { url = "https://files.pythonhosted.org/packages/57/09/4393bd378e70b7fc3163ee83353cc27bb520010a5c2b3c924121e7e7e068/peewee-3.17.9.tar.gz", hash = "sha256:fe15cd001758e324c8e3ca8c8ed900e7397c2907291789e1efc383e66b9bc7a8", size = 3026085 } [[package]] name = "phx-class-registry" @@ -1481,7 +1481,7 @@ wheels = [ [[package]] name = "red-discordbot" -version = "3.5.15" +version = "3.5.16" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "aiohttp" }, @@ -1522,9 +1522,9 @@ dependencies = [ { name = "yarl" }, { name = "zipp", marker = "python_full_version >= '3.12'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/55/69/42940946a3bd3a099f61ee9e6fa78e9ab7cf7e671a328506497a879b34fe/red_discordbot-3.5.15.tar.gz", hash = "sha256:2326712065b45ec61aff5d0943620efd6212c69ae08a2ad8fe673c859e34e921", size = 3685486 } +sdist = { url = "https://files.pythonhosted.org/packages/8a/2a/3d3ae9ba47de022a1a47ed5f5ea08739b069b079508a7a818bd74d18e29f/red_discordbot-3.5.16.tar.gz", hash = "sha256:f77f54cd65523ed0ea30b40cc81b07574fe10d1f1a80d013281c872664cabb35", size = 3685700 } wheels = [ - { url = "https://files.pythonhosted.org/packages/50/f5/f0b8ebdc3f1a072a846dd0388cf67d5acdaa4f300e36dd78af1b704181dd/Red_DiscordBot-3.5.15-py3-none-any.whl", hash = "sha256:e08d96ee270a36feb2331435a6173777a514e268263d5bb4839fff713815491c", size = 5776852 }, + { url = "https://files.pythonhosted.org/packages/72/58/4ae469ee7961bc8f488669432ffb62d42a89376ad92ed809d66512228f27/Red_DiscordBot-3.5.16-py3-none-any.whl", hash = "sha256:c042c20b94b3e12b388b8ffa1d0472179403630d3e979108e7ee288a549f2ec2", size = 5777054 }, ] [[package]] From e4f419ec7b09790afd3ae3b5d87c336fc29b8944 Mon Sep 17 00:00:00 2001 From: cswimr Date: Thu, 6 Feb 2025 06:41:00 -0600 Subject: [PATCH 44/53] chore(repo): formatting --- .devcontainer/Dockerfile | 44 ++++++++++++++++++++-------------------- info.json | 13 ++++++------ 2 files changed, 28 insertions(+), 29 deletions(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 2e79139..19c88c9 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -7,26 +7,26 @@ LABEL repository="www.coastalcommits.com/cswimr/SeaCogs" LABEL maintainer="cswimr " RUN apt-get update; \ - apt-get install -y --no-install-recommends \ - # Red-DiscordBot - build-essential \ - git \ - # PyNaCl - libsodium-dev \ - # CFFI - libffi-dev \ - # SSH repository support - openssh-client \ - # Cog dependencies - # Audio - openjdk-17-jre-headless \ - # PyLav - libaio1 \ - libaio-dev \ - # SeaUtils - dnsutils; \ - apt-get clean; \ - rm -rf /var/lib/apt/lists/* + apt-get install -y --no-install-recommends \ + # Red-DiscordBot + build-essential \ + git \ + # PyNaCl + libsodium-dev \ + # CFFI + libffi-dev \ + # SSH repository support + openssh-client \ + # Cog dependencies + # Audio + openjdk-17-jre-headless \ + # PyLav + libaio1 \ + libaio-dev \ + # SeaUtils + dnsutils; \ + apt-get clean; \ + rm -rf /var/lib/apt/lists/* COPY --from=uv --chown=vscode: /uv /uvx /bin/ COPY --from=python --chown=vscode: /usr/local /usr/local @@ -34,5 +34,5 @@ COPY --from=forgejo-runner --chown=vscode: /bin/forgejo-runner /bin/forgejo-runn COPY --chown=vscode: .devcontainer/home/* /home/vscode/ RUN ln -s /usr/local/bin/python3.11 /usr/local/bin/python; \ - python --version; \ - python -m ensurepip + python --version; \ + python -m ensurepip diff --git a/info.json b/info.json index c679a52..08ba1dc 100644 --- a/info.json +++ b/info.json @@ -1,9 +1,8 @@ { - "author": [ - "cswimr" - ], - "install_msg": "Thanks for installing my repo!\n\nIf you have any issues with any of the cogs, please create an issue [here](https://coastalcommits.com/cswimr/SeaCogs/issues) or join my [Discord Server](https://discord.gg/eMUMe77Yb8 ).", - "index_name": "sea-cogs", - "short": "Various cogs for Red, by cswimr", - "description": "Various cogs for Red, by cswimr" + "$schema": "https://raw.githubusercontent.com/Cog-Creators/Red-DiscordBot/V3/develop/schema/red_cog_repo.schema.json", + "author": ["cswimr"], + "install_msg": "Thanks for installing my repo!\n\nIf you have any issues with any of the cogs, please create an issue [here](https://coastalcommits.com/cswimr/SeaCogs/issues) or join my [Discord Server](https://discord.gg/eMUMe77Yb8 ).", + "index_name": "sea-cogs", + "short": "Various cogs for Red, by cswimr", + "description": "Various cogs for Red, by cswimr" } From 7593aace002ebee2e19e1d6e6dcaa09339d8c5e7 Mon Sep 17 00:00:00 2001 From: cswimr Date: Thu, 6 Feb 2025 06:41:39 -0600 Subject: [PATCH 45/53] chore(tooling): add `dig` to the nix flake --- flake.nix | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/flake.nix b/flake.nix index b443a85..a93f91a 100644 --- a/flake.nix +++ b/flake.nix @@ -33,11 +33,14 @@ git libsodium libffi - libaio jdk17 # Material for MkDocs dependencies cairo pngquant + # PyLav dependencies + libaio + # SeaCogs dependencies + dig ]; shellHook = # bash '' From 9b96a1562155d851e43d4051b972a0a50549168c Mon Sep 17 00:00:00 2001 From: cswimr Date: Thu, 6 Feb 2025 15:10:19 -0600 Subject: [PATCH 46/53] chore(repo): add schemas to repo.json files --- antipolls/info.json | 19 ++++++++----------- backup/info.json | 18 ++++-------------- bible/info.json | 19 ++++++++----------- emojiinfo/info.json | 17 ++++++++--------- hotreload/info.json | 20 +++++--------------- nerdify/info.json | 19 ++++++++----------- pterodactyl/info.json | 20 ++++++++------------ seautils/info.json | 13 +++++++------ 8 files changed, 56 insertions(+), 89 deletions(-) diff --git a/antipolls/info.json b/antipolls/info.json index 7856195..24bc0bb 100644 --- a/antipolls/info.json +++ b/antipolls/info.json @@ -1,17 +1,14 @@ { - "author" : ["cswimr"], - "install_msg" : "Thank you for installing AntiPolls!\nYou can find the source code of this cog [here](https://coastalcommits.com/cswimr/SeaCogs).", - "name" : "AntiPolls", - "short" : "AntiPolls deletes messages that contain polls.", - "description" : "AntiPolls deletes messages that contain polls, with a configurable per-guild role and channel whitelist and support for default Discord permissions (Manage Messages).", - "end_user_data_statement" : "This cog does not store any user data.", + "$schema": "https://raw.githubusercontent.com/Cog-Creators/Red-DiscordBot/refs/heads/V3/develop/schema/red_cog_repo.schema.json", + "author": ["cswimr"], + "install_msg": "Thank you for installing AntiPolls!\nYou can find the source code of this cog [here](https://coastalcommits.com/cswimr/SeaCogs).", + "name": "AntiPolls", + "short": "AntiPolls deletes messages that contain polls.", + "description": "AntiPolls deletes messages that contain polls, with a configurable per-guild role and channel whitelist and support for default Discord permissions (Manage Messages).", + "end_user_data_statement": "This cog does not store any user data.", "hidden": true, "disabled": false, "min_bot_version": "3.5.0", "min_python_version": [3, 10, 0], - "tags": [ - "automod", - "automoderation", - "polls" - ] + "tags": ["automod", "automoderation", "polls"] } diff --git a/backup/info.json b/backup/info.json index 288ece1..b00ecaf 100644 --- a/backup/info.json +++ b/backup/info.json @@ -1,7 +1,6 @@ { - "author": [ - "cswimr" - ], + "$schema": "https://raw.githubusercontent.com/Cog-Creators/Red-DiscordBot/refs/heads/V3/develop/schema/red_cog_repo.schema.json", + "author": ["cswimr"], "install_msg": "Thank you for installing Backup!\nYou can find the source code of this cog [here](https://coastalcommits.com/cswimr/SeaCogs).", "name": "Backup", "short": "A utility to make reinstalling repositories and cogs after migrating the bot far easier.", @@ -11,15 +10,6 @@ "disabled": false, "min_bot_version": "3.5.6", "max_bot_version": "3.5.14", - "min_python_version": [ - 3, - 9, - 0 - ], - "tags": [ - "utility", - "backup", - "restore", - "migration" - ] + "min_python_version": [3, 9, 0], + "tags": ["utility", "backup", "restore", "migration"] } diff --git a/bible/info.json b/bible/info.json index b2da6d1..79ae088 100644 --- a/bible/info.json +++ b/bible/info.json @@ -1,18 +1,15 @@ { - "author" : ["cswimr"], - "install_msg" : "Thank you for installing Bible!\nThis cog requires setting an API key for API.Bible. Please read the [documentation](https://seacogs.coastalcommits.com/bible/#setup) for more information.\nYou can find the source code of this cog [here](https://coastalcommits.com/cswimr/SeaCogs).", - "name" : "Bible", - "short" : "Retrieve Bible verses from API.Bible.", - "description" : "Retrieve Bible verses from the API.Bible API. This cog requires an API.Bible api key.", - "end_user_data_statement" : "This cog does not store end user data, however it does send the following data to the API.Bible API:\n- The bot user's ID\n- The timestamp of the invoking message\n- The hashed user id of the invoking user", + "$schema": "https://raw.githubusercontent.com/Cog-Creators/Red-DiscordBot/refs/heads/V3/develop/schema/red_cog_repo.schema.json", + "author": ["cswimr"], + "install_msg": "Thank you for installing Bible!\nThis cog requires setting an API key for API.Bible. Please read the [documentation](https://seacogs.coastalcommits.com/bible/#setup) for more information.\nYou can find the source code of this cog [here](https://coastalcommits.com/cswimr/SeaCogs).", + "name": "Bible", + "short": "Retrieve Bible verses from API.Bible.", + "description": "Retrieve Bible verses from the API.Bible API. This cog requires an API.Bible api key.", + "end_user_data_statement": "This cog does not store end user data, however it does send the following data to the API.Bible API:\n- The bot user's ID\n- The timestamp of the invoking message\n- The hashed user id of the invoking user", "hidden": false, "disabled": false, "min_bot_version": "3.5.0", "min_python_version": [3, 10, 0], "requirements": ["numpy", "pillow"], - "tags": [ - "fun", - "utility", - "api" - ] + "tags": ["fun", "utility", "api"] } diff --git a/emojiinfo/info.json b/emojiinfo/info.json index 68a8de1..ccc32c7 100644 --- a/emojiinfo/info.json +++ b/emojiinfo/info.json @@ -1,16 +1,15 @@ { - "author" : ["cswimr"], - "install_msg" : "Thank you for installing Emoji!", - "name" : "Emoji", - "short" : "Retrieve information about emojis.", - "description" : "Retrieve information about emojis.", - "end_user_data_statement" : "This cog does not store end user data.", + "$schema": "https://raw.githubusercontent.com/Cog-Creators/Red-DiscordBot/refs/heads/V3/develop/schema/red_cog_repo.schema.json", + "author": ["cswimr"], + "install_msg": "Thank you for installing Emoji!", + "name": "Emoji", + "short": "Retrieve information about emojis.", + "description": "Retrieve information about emojis.", + "end_user_data_statement": "This cog does not store end user data.", "hidden": false, "disabled": false, "min_bot_version": "3.5.0", "min_python_version": [3, 10, 0], "requirements": ["colorthief"], - "tags": [ - "utility" - ] + "tags": ["utility"] } diff --git a/hotreload/info.json b/hotreload/info.json index 6028830..4669078 100644 --- a/hotreload/info.json +++ b/hotreload/info.json @@ -1,7 +1,6 @@ { - "author": [ - "cswimr" - ], + "$schema": "https://raw.githubusercontent.com/Cog-Creators/Red-DiscordBot/refs/heads/V3/develop/schema/red_cog_repo.schema.json", + "author": ["cswimr"], "install_msg": "Thank you for installing HotReload! Please see the [documentation](https://seacogs.coastalcommits.com/hotreload) to get started.", "name": "HotReload", "short": "Automatically reload cogs in local cog paths on file change.", @@ -10,16 +9,7 @@ "hidden": false, "disabled": false, "min_bot_version": "3.5.0", - "min_python_version": [ - 3, - 8, - 0 - ], - "requirements": [ - "watchdog" - ], - "tags": [ - "utility", - "development" - ] + "min_python_version": [3, 8, 0], + "requirements": ["watchdog"], + "tags": ["utility", "development"] } diff --git a/nerdify/info.json b/nerdify/info.json index 1d06223..eeb0ef7 100644 --- a/nerdify/info.json +++ b/nerdify/info.json @@ -1,17 +1,14 @@ { - "author" : ["cswimr"], - "install_msg" : "Thank you for installing Nerdify!\nYou can find the source code of this cog [here](https://coastalcommits.com/cswimr/SeaCogs). Based off of PhasecoreX's [UwU]() cog.", - "name" : "Nerdify", - "short" : "Nerdify your text!", - "description" : "Nerdify your text!", - "end_user_data_statement" : "This cog does not store end user data.", + "$schema": "https://raw.githubusercontent.com/Cog-Creators/Red-DiscordBot/refs/heads/V3/develop/schema/red_cog_repo.schema.json", + "author": ["cswimr"], + "install_msg": "Thank you for installing Nerdify!\nYou can find the source code of this cog [here](https://coastalcommits.com/cswimr/SeaCogs). Based off of PhasecoreX's [UwU]() cog.", + "name": "Nerdify", + "short": "Nerdify your text!", + "description": "Nerdify your text!", + "end_user_data_statement": "This cog does not store end user data.", "hidden": false, "disabled": false, "min_bot_version": "3.5.0", "min_python_version": [3, 8, 0], - "tags": [ - "fun", - "text", - "meme" - ] + "tags": ["fun", "text", "meme"] } diff --git a/pterodactyl/info.json b/pterodactyl/info.json index 7c4545a..ec7c4db 100644 --- a/pterodactyl/info.json +++ b/pterodactyl/info.json @@ -1,19 +1,15 @@ { - "author" : ["cswimr"], - "install_msg" : "Thank you for installing Pterodactyl!\nYou can find the source code of this cog [here](https://coastalcommits.com/cswimr/SeaCogs).\nDocumentation can be found [here](https://seacogs.coastalcommits.com/pterodactyl ).", - "name" : "Pterodactyl", - "short" : "Interface with Pterodactyl through websockets.", - "description" : "Interface with Pterodactyl through websockets.", - "end_user_data_statement" : "This cog does not store end user data.", + "$schema": "https://raw.githubusercontent.com/Cog-Creators/Red-DiscordBot/refs/heads/V3/develop/schema/red_cog_repo.schema.json", + "author": ["cswimr"], + "install_msg": "Thank you for installing Pterodactyl!\nYou can find the source code of this cog [here](https://coastalcommits.com/cswimr/SeaCogs).\nDocumentation can be found [here](https://seacogs.coastalcommits.com/pterodactyl ).", + "name": "Pterodactyl", + "short": "Interface with Pterodactyl through websockets.", + "description": "Interface with Pterodactyl through websockets.", + "end_user_data_statement": "This cog does not store end user data.", "hidden": false, "disabled": false, "min_bot_version": "3.5.0", "min_python_version": [3, 8, 0], "requirements": ["git+https://github.com/cswimr/pydactyl", "websockets"], - "tags": [ - "pterodactyl", - "minecraft", - "server", - "management" - ] + "tags": ["pterodactyl", "minecraft", "server", "management"] } diff --git a/seautils/info.json b/seautils/info.json index 2f8fa83..bdd6708 100644 --- a/seautils/info.json +++ b/seautils/info.json @@ -1,10 +1,11 @@ { - "author" : ["cswimr"], - "install_msg" : "Thank you for installing SeaUtils!\nYou can find the source code of this cog [here](https://coastalcommits.com/cswimr/SeaCogs).", - "name" : "SeaUtils", - "short" : "A collection of useful utilities.", - "description" : "A collection of useful utilities.", - "end_user_data_statement" : "This cog does not store end user data.", + "$schema": "https://raw.githubusercontent.com/Cog-Creators/Red-DiscordBot/refs/heads/V3/develop/schema/red_cog_repo.schema.json", + "author": ["cswimr"], + "install_msg": "Thank you for installing SeaUtils!\nYou can find the source code of this cog [here](https://coastalcommits.com/cswimr/SeaCogs).", + "name": "SeaUtils", + "short": "A collection of useful utilities.", + "description": "A collection of useful utilities.", + "end_user_data_statement": "This cog does not store end user data.", "hidden": true, "disabled": false, "min_bot_version": "3.5.0", From e7714cd2dfe3da3413c0226f96e053320fe51ea0 Mon Sep 17 00:00:00 2001 From: cswimr Date: Thu, 6 Feb 2025 17:20:21 -0600 Subject: [PATCH 47/53] fix(hotreload): fix typehint --- hotreload/hotreload.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hotreload/hotreload.py b/hotreload/hotreload.py index 579e7db..268a41a 100644 --- a/hotreload/hotreload.py +++ b/hotreload/hotreload.py @@ -60,7 +60,7 @@ class HotReload(commands.Cog): ] return "\n".join(text) - async def get_paths(self) -> Generator[Path]: + async def get_paths(self) -> Generator[Path, None, None]: """Retrieve user defined paths.""" cog_manager = self.bot._cog_mgr # noqa: SLF001 # We have to use this private method because there is no public API to get user defined paths cog_paths = await cog_manager.user_defined_paths() From 527c372fb0f0e297f01d2e52a3415adcb1767135 Mon Sep 17 00:00:00 2001 From: cswimr Date: Thu, 6 Feb 2025 17:20:39 -0600 Subject: [PATCH 48/53] chore(tooling): fix the nix flake --- flake.lock | 10 +++++----- flake.nix | 36 +++++++++++++++++++++++++----------- 2 files changed, 30 insertions(+), 16 deletions(-) diff --git a/flake.lock b/flake.lock index 855cc6a..363c464 100644 --- a/flake.lock +++ b/flake.lock @@ -2,12 +2,12 @@ "nodes": { "nixpkgs": { "locked": { - "lastModified": 1738546358, - "narHash": "sha256-nLivjIygCiqLp5QcL7l56Tca/elVqM9FG1hGd9ZSsrg=", - "rev": "c6e957d81b96751a3d5967a0fd73694f303cc914", - "revCount": 747070, + "lastModified": 1738680400, + "narHash": "sha256-ooLh+XW8jfa+91F1nhf9OF7qhuA/y1ChLx6lXDNeY5U=", + "rev": "799ba5bffed04ced7067a91798353d360788b30d", + "revCount": 747653, "type": "tarball", - "url": "https://api.flakehub.com/f/pinned/NixOS/nixpkgs/0.1.747070%2Brev-c6e957d81b96751a3d5967a0fd73694f303cc914/0194cfda-968b-7c4f-95c5-bd4a42478770/source.tar.gz" + "url": "https://api.flakehub.com/f/pinned/NixOS/nixpkgs/0.1.747653%2Brev-799ba5bffed04ced7067a91798353d360788b30d/0194d302-29da-7009-8f43-5b8a58825954/source.tar.gz" }, "original": { "type": "tarball", diff --git a/flake.nix b/flake.nix index a93f91a..819e209 100644 --- a/flake.nix +++ b/flake.nix @@ -17,39 +17,53 @@ system: f { pkgs = import nixpkgs { inherit system; }; + lib = nixpkgs.lib; } ); in { devShells = forEachSupportedSystem ( - { pkgs }: + { pkgs, lib }: + let + myPython = pkgs.python311; + lib-path = + with pkgs; + lib.makeLibraryPath [ + stdenv.cc.cc + # Red-DiscordBot dependencies + libffi + libsodium + # PyLav dependency + libaio + # Material for MkDocs dependency + cairo + ]; + in { default = pkgs.mkShell { + lib-path = lib-path; packages = with pkgs; [ - python311 + myPython uv + ruff # the ruff pip package installs a dynamically linked binary that cannot run on NixOS forgejo-runner # Red-DiscordBot dependencies git - libsodium - libffi jdk17 # Material for MkDocs dependencies - cairo pngquant - # PyLav dependencies - libaio # SeaCogs dependencies dig ]; shellHook = # bash '' - export UV_PYTHON_PREFERENCE=only-system - export UV_PYTHON_DOWNLOADS=never + export "LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${lib-path}" + export "UV_PYTHON_PREFERENCE=only-system" + export "UV_PYTHON_DOWNLOADS=never" uv sync --all-groups - alias uvr="uv run" source ./.venv/bin/activate - export PYTHONPATH=`pwd`/.venv/${pkgs.python311.sitePackages}/:$PYTHONPATH + export "PYTHONPATH=`pwd`/.venv/${myPython.sitePackages}/:$PYTHONPATH" + export "PATH=${pkgs.ruff}/bin:$PATH" ''; }; } From 72dcc96fea7644a860457c47d030631035575bd2 Mon Sep 17 00:00:00 2001 From: cswimr Date: Fri, 7 Feb 2025 16:07:44 -0600 Subject: [PATCH 49/53] chore(tooling): remove comments --- .vscode/launch.json | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 9a7e46e..2a3559f 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -1,15 +1,12 @@ { - // Use IntelliSense to learn about possible attributes. - // Hover to view descriptions of existing attributes. - // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [ - { - "name": "Python: Red-DiscordBot", - "type": "debugpy", - "request": "launch", - "module": "redbot", - "args": ["local", "--dev", "-vvv", "--load-cogs=hotreload"] - } - ] + "version": "0.2.0", + "configurations": [ + { + "name": "Python: Red-DiscordBot", + "type": "debugpy", + "request": "launch", + "module": "redbot", + "args": ["local", "--dev", "-vvv", "--load-cogs=hotreload"] + } + ] } From d649ca0f020614bdd4129cb73cf2838549cad2f9 Mon Sep 17 00:00:00 2001 From: cswimr Date: Fri, 7 Feb 2025 16:07:50 -0600 Subject: [PATCH 50/53] chore(repo): formatting --- pyproject.toml | 136 ++++++++++++++++++++++++------------------------- 1 file changed, 68 insertions(+), 68 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 782dad3..8dce5ac 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,29 +7,29 @@ license = { file = "LICENSE" } readme = "README.md" requires-python = ">=3.11" dependencies = [ - "aiosqlite>=0.20.0", - "beautifulsoup4>=4.12.3", - "colorthief>=0.2.1", - "markdownify>=0.14.1", - "numpy>=2.2.2", - "phx-class-registry>=5.1.1", - "pillow>=10.4.0", - "pip>=25.0", - "py-dactyl", - "pydantic>=2.10.6", - "red-discordbot>=3.5.14", - "watchdog>=6.0.0", - "websockets>=14.2", + "aiosqlite>=0.20.0", + "beautifulsoup4>=4.12.3", + "colorthief>=0.2.1", + "markdownify>=0.14.1", + "numpy>=2.2.2", + "phx-class-registry>=5.1.1", + "pillow>=10.4.0", + "pip>=25.0", + "py-dactyl", + "pydantic>=2.10.6", + "red-discordbot>=3.5.14", + "watchdog>=6.0.0", + "websockets>=14.2", ] [dependency-groups] documentation = [ - "mkdocs>=1.6.1", - "mkdocs-git-authors-plugin>=0.9.2", - "mkdocs-git-revision-date-localized-plugin>=1.3.0", - "mkdocs-material[imaging]>=9.5.50", - "mkdocs-redirects>=1.2.2", - "mkdocstrings[python]>=0.27.0", + "mkdocs>=1.6.1", + "mkdocs-git-authors-plugin>=0.9.2", + "mkdocs-git-revision-date-localized-plugin>=1.3.0", + "mkdocs-material[imaging]>=9.5.50", + "mkdocs-redirects>=1.2.2", + "mkdocstrings[python]>=0.27.0", ] [tool.uv] @@ -45,32 +45,32 @@ reportAttributeAccessIssue = false # disabled because `commands.group.command` i [tool.ruff] # Exclude a variety of commonly ignored directories. exclude = [ - ".bzr", - ".direnv", - ".eggs", - ".git", - ".git-rewrite", - ".hg", - ".ipynb_checkpoints", - ".mypy_cache", - ".nox", - ".pants.d", - ".pyenv", - ".pytest_cache", - ".pytype", - ".ruff_cache", - ".svn", - ".tox", - ".venv", - ".vscode", - "__pypackages__", - "_build", - "buck-out", - "build", - "dist", - "node_modules", - "site-packages", - "venv", + ".bzr", + ".direnv", + ".eggs", + ".git", + ".git-rewrite", + ".hg", + ".ipynb_checkpoints", + ".mypy_cache", + ".nox", + ".pants.d", + ".pyenv", + ".pytest_cache", + ".pytype", + ".ruff_cache", + ".svn", + ".tox", + ".venv", + ".vscode", + "__pypackages__", + "_build", + "buck-out", + "build", + "dist", + "node_modules", + "site-packages", + "venv", ] # Same as Black. @@ -85,29 +85,29 @@ target-version = "py311" # Unlike Flake8, Ruff doesn't enable pycodestyle warnings (`W`) or # McCabe complexity (`C901`) by default. select = [ - "I", - "N", - "F", - "W", - "E", - "G", - "A", - "COM", - "INP", - "T20", - "PLC", - "PLE", - "PLW", - "PLR", - "LOG", - "SLF", - "ERA", - "FIX", - "PERF", - "C4", - "EM", - "RET", - "RSE", + "I", + "N", + "F", + "W", + "E", + "G", + "A", + "COM", + "INP", + "T20", + "PLC", + "PLE", + "PLW", + "PLR", + "LOG", + "SLF", + "ERA", + "FIX", + "PERF", + "C4", + "EM", + "RET", + "RSE", ] ignore = ["PLR0911", "PLR0912", "PLR0915", "PLR2004", "PLR0913", "EM101"] From 7ada16e999478de170a951dd8be4b379ab0d910f Mon Sep 17 00:00:00 2001 From: cswimr Date: Sat, 8 Feb 2025 19:00:36 -0600 Subject: [PATCH 51/53] chore(tooling): add .editorconfig --- .editorconfig | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..4a7ea30 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,12 @@ +root = true + +[*] +indent_style = space +indent_size = 2 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[*.md] +trim_trailing_whitespace = false From e854abfb0e78fda34ad35d59fa39ac1936908793 Mon Sep 17 00:00:00 2001 From: cswimr Date: Sat, 8 Feb 2025 19:00:45 -0600 Subject: [PATCH 52/53] feat(backup): update to most recent red version --- backup/info.json | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/backup/info.json b/backup/info.json index b00ecaf..c9a9269 100644 --- a/backup/info.json +++ b/backup/info.json @@ -1,6 +1,8 @@ { "$schema": "https://raw.githubusercontent.com/Cog-Creators/Red-DiscordBot/refs/heads/V3/develop/schema/red_cog_repo.schema.json", - "author": ["cswimr"], + "author": [ + "cswimr" + ], "install_msg": "Thank you for installing Backup!\nYou can find the source code of this cog [here](https://coastalcommits.com/cswimr/SeaCogs).", "name": "Backup", "short": "A utility to make reinstalling repositories and cogs after migrating the bot far easier.", @@ -9,7 +11,16 @@ "hidden": false, "disabled": false, "min_bot_version": "3.5.6", - "max_bot_version": "3.5.14", - "min_python_version": [3, 9, 0], - "tags": ["utility", "backup", "restore", "migration"] + "max_bot_version": "3.5.16", + "min_python_version": [ + 3, + 9, + 0 + ], + "tags": [ + "utility", + "backup", + "restore", + "migration" + ] } From d89c156744a014a96322f4d1f796818b21902bb0 Mon Sep 17 00:00:00 2001 From: Renovate Date: Mon, 10 Feb 2025 23:01:15 -0500 Subject: [PATCH 53/53] chore(deps): update ghcr.io/astral-sh/uv docker tag to v0.5.30 (#53) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [ghcr.io/astral-sh/uv](https://github.com/astral-sh/uv) | stage | patch | `0.5.24` -> `0.5.30` | --- > ⚠️ **Warning** > > Some dependencies could not be looked up. Check the Dependency Dashboard for more information. --- ### Release Notes
astral-sh/uv (ghcr.io/astral-sh/uv) ### [`v0.5.30`](https://github.com/astral-sh/uv/blob/HEAD/CHANGELOG.md#0530) [Compare Source](https://github.com/astral-sh/uv/compare/0.5.29...0.5.30) ##### Python The managed PyPy distributions have been updated for PyPy v7.3.18, which includes: - PyPy3.10, which updates the standard library from Python 3.10.14 to 3.10.19 - PyPy3.11, which adds beta support for Python 3.11.11 See the [PyPy release](https://pypy.org/posts/2025/02/pypy-v7318-release.html) for more details. ##### Enhancements - Add `uv sync --dry-run` ([#​11299](https://github.com/astral-sh/uv/pull/11299)) - Ignore `#egg` fragment in HTML Simple API response ([#​11340](https://github.com/astral-sh/uv/pull/11340)) ##### Configuration - Add `NO_BINARY` and `NO_BINARY_PACKAGE` environment variables ([#​11399](https://github.com/astral-sh/uv/pull/11399)) ##### Performance - Avoid re-cloning name when populating ambiguous set ([#​11401](https://github.com/astral-sh/uv/pull/11401)) - Optimize flattening in large workspaces ([#​11313](https://github.com/astral-sh/uv/pull/11313)) ##### Bug fixes - Allow dynamic packages to be overloaded ([#​11400](https://github.com/astral-sh/uv/pull/11400)) - Fix credential caching for index roots when URL ends in `simple/` ([#​11336](https://github.com/astral-sh/uv/pull/11336)) - Fix marker merging for requirements.txt for psycopg ([#​11298](https://github.com/astral-sh/uv/pull/11298)) - Set 777 permissions on locked files ([#​11328](https://github.com/astral-sh/uv/pull/11328)) - Support extras in `@` requests for tools ([#​11335](https://github.com/astral-sh/uv/pull/11335)) - Upgrade `astral-tokio-tar` to v0.5.1 ([#​11359](https://github.com/astral-sh/uv/pull/11359)) - Avoid missing logging for no-op upgrade events ([#​11301](https://github.com/astral-sh/uv/pull/11301)) - Use refined specifiers when logging narrowed Python range ([#​11334](https://github.com/astral-sh/uv/pull/11334)) - Don't use popup-generating `eprintln` in trampoline warnings ([#​11295](https://github.com/astral-sh/uv/pull/11295)) - Patch pkg-config files to be relocatable ([#​11291](https://github.com/astral-sh/uv/pull/11291)) - Fix a case of duplicate `torch` packages when using conflicting extras ([#​11323](https://github.com/astral-sh/uv/pull/11323)) ##### Documentation - Add docs for `uv tool install --editable` ([#​11280](https://github.com/astral-sh/uv/pull/11280)) - Fix broken anchors in README and docs index ([#​11338](https://github.com/astral-sh/uv/pull/11338)) ### [`v0.5.29`](https://github.com/astral-sh/uv/blob/HEAD/CHANGELOG.md#0529) [Compare Source](https://github.com/astral-sh/uv/compare/0.5.28...0.5.29) ##### Enhancements - Add `--bare` option to `uv init` ([#​11192](https://github.com/astral-sh/uv/pull/11192)) - Add support for respecting `VIRTUAL_ENV` in project commands via `--active` ([#​11189](https://github.com/astral-sh/uv/pull/11189)) - Allow the project `VIRTUAL_ENV` warning to be silenced with `--no-active` ([#​11251](https://github.com/astral-sh/uv/pull/11251)) ##### Python The managed Python distributions have been updated, including: - CPython 3.12.9 - CPython 3.13.2 - pkg-config files are now relocatable See the [`python-build-standalone` release notes](https://github.com/astral-sh/python-build-standalone/releases/tag/20250205) for more details. ##### Bug fixes - Always use base Python discovery logic for cached environments ([#​11254](https://github.com/astral-sh/uv/pull/11254)) - Use a flock to avoid concurrent initialization of project environments ([#​11259](https://github.com/astral-sh/uv/pull/11259)) - Fix handling of `--all-groups` and `--no-default-groups` flags ([#​11224](https://github.com/astral-sh/uv/pull/11224)) ##### Documentation - Minor touchups to the Docker provenance docs ([#​11252](https://github.com/astral-sh/uv/pull/11252)) - Move content from the `mkdocs.public.yml` into the template ([#​11246](https://github.com/astral-sh/uv/pull/11246)) ### [`v0.5.28`](https://github.com/astral-sh/uv/blob/HEAD/CHANGELOG.md#0528) [Compare Source](https://github.com/astral-sh/uv/compare/0.5.27...0.5.28) ##### Bug fixes - Allow discovering virtual environments from the first interpreter found on the `PATH` ([#​11218](https://github.com/astral-sh/uv/pull/11218)) - Clear ephemeral overlays when running tools ([#​11141](https://github.com/astral-sh/uv/pull/11141)) - Disable SSL in Git commands for `--allow-insecure-host` ([#​11210](https://github.com/astral-sh/uv/pull/11210)) - Fix hardlinks in tar unpacking ([#​11221](https://github.com/astral-sh/uv/pull/11221)) - Set base executable when returning virtual environment ([#​11209](https://github.com/astral-sh/uv/pull/11209)) - Use base Python for cached environments ([#​11208](https://github.com/astral-sh/uv/pull/11208)) ##### Documentation - Add documentation on verifying Docker image attestations ([#​11140](https://github.com/astral-sh/uv/pull/11140)) - Add `last updated` to documentation ([#​11164](https://github.com/astral-sh/uv/pull/11164)) ### [`v0.5.27`](https://github.com/astral-sh/uv/blob/HEAD/CHANGELOG.md#0527) [Compare Source](https://github.com/astral-sh/uv/compare/0.5.26...0.5.27) ##### Enhancements - Avoid setting permissions during tar extraction ([#​11191](https://github.com/astral-sh/uv/pull/11191)) - Remove warnings for missing lower bounds ([#​11195](https://github.com/astral-sh/uv/pull/11195)) - Update PubGrub to set-based outdated priority tracking ([#​11169](https://github.com/astral-sh/uv/pull/11169)) - Improve error messages for `uv pip install` with `--extra` or `--all-extras` and invalid sources ([#​11193](https://github.com/astral-sh/uv/pull/11193)) - Sign Docker images using GitHub attestations ([#​8685](https://github.com/astral-sh/uv/pull/8685)) ##### Preview features - Don't expand self-referential extras in the build backend ([#​11142](https://github.com/astral-sh/uv/pull/11142)) ##### Performance - Filter discovered Python executables by source before querying ([#​11143](https://github.com/astral-sh/uv/pull/11143)) - Optimize exclusion computation for markers ([#​11158](https://github.com/astral-sh/uv/pull/11158)) - Use Astral-maintained `tokio-tar` fork ([#​11174](https://github.com/astral-sh/uv/pull/11174)) - Remove unneeded `.clone()` ([#​11127](https://github.com/astral-sh/uv/pull/11127)) ##### Bug fixes - Fix relative paths in bytecode compilation ([#​11177](https://github.com/astral-sh/uv/pull/11177)) - Percent-decode URLs in canonical comparisons ([#​11088](https://github.com/astral-sh/uv/pull/11088)) - Respect concurrency limits in parallel index fetch ([#​11182](https://github.com/astral-sh/uv/pull/11182)) - Use wire JSON schema for conflict items ([#​11196](https://github.com/astral-sh/uv/pull/11196)) - Use explicit `_GLibCVersion` tuple in uv-python crate ([#​11122](https://github.com/astral-sh/uv/pull/11122)) ##### Documentation - Add Git SHA locking behavior to docs ([#​11125](https://github.com/astral-sh/uv/pull/11125)) - Add best-practice flags to `pip install` example in troubleshooting guide ([#​11194](https://github.com/astral-sh/uv/pull/11194)) - Set `VIRTUAL_ENV` in Jupyter kernels ([#​11155](https://github.com/astral-sh/uv/pull/11155)) - Add instructions for deactivating an environment ([#​11200](https://github.com/astral-sh/uv/pull/11200)) ### [`v0.5.26`](https://github.com/astral-sh/uv/blob/HEAD/CHANGELOG.md#0526) [Compare Source](https://github.com/astral-sh/uv/compare/0.5.25...0.5.26) ##### Enhancements - Add support for `uvx python` ([#​11076](https://github.com/astral-sh/uv/pull/11076)) - Allow `--no-dev --invert` in `uv tree` ([#​11068](https://github.com/astral-sh/uv/pull/11068)) - Update `uv python install --reinstall` to reinstall all previous versions ([#​11072](https://github.com/astral-sh/uv/pull/11072)) - Consistently write log messages with capitalized first word ([#​11111](https://github.com/astral-sh/uv/pull/11111)) - Suggest `--build-backend` when `--backend` is passed to `uv init` ([#​10958](https://github.com/astral-sh/uv/pull/10958)) - Improve retry trace message ([#​11108](https://github.com/astral-sh/uv/pull/11108)) ##### Performance - Remove unnecessary UTF-8 conversion in hash parsing ([#​11110](https://github.com/astral-sh/uv/pull/11110)) ##### Bug fixes - Ignore non-hash fragments in HTML API responses ([#​11107](https://github.com/astral-sh/uv/pull/11107)) - Avoid resolving symbolic links when querying Python interpreters ([#​11083](https://github.com/astral-sh/uv/pull/11083)) - Avoid sharing state between universal and non-universal resolves ([#​11051](https://github.com/astral-sh/uv/pull/11051)) - Error when `--script` is passing a non-PEP 723 script ([#​11118](https://github.com/astral-sh/uv/pull/11118)) - Make metadata deserialization failures non-fatal in the cache ([#​11105](https://github.com/astral-sh/uv/pull/11105)) - Mark metadata as dynamic when reading from built wheel cache ([#​11046](https://github.com/astral-sh/uv/pull/11046)) - Propagate credentials for `/simple` to `/...` endpoints ([#​11074](https://github.com/astral-sh/uv/pull/11074)) - Fix conflicting extra bug during `uv sync` ([#​11075](https://github.com/astral-sh/uv/pull/11075)) ##### Documentation - Add PyTorch XPU instructions to the PyTorch guide ([#​11109](https://github.com/astral-sh/uv/pull/11109)) - Add docs for signal handling ([#​11041](https://github.com/astral-sh/uv/pull/11041)) - Explain build frontend vs. build backend ([#​11094](https://github.com/astral-sh/uv/pull/11094)) - Fix formatting of `RUST_LOG` documentation ([#​10053](https://github.com/astral-sh/uv/pull/10053)) - Fix typo in `--no-deps` description ([#​11073](https://github.com/astral-sh/uv/pull/11073)) - Reflow CLI documentation comments ([#​11040](https://github.com/astral-sh/uv/pull/11040)) - Shorten "Using existing Python versions" nav item so it fits on one line ([#​11077](https://github.com/astral-sh/uv/pull/11077)) - Some minor touch-ups to the Python install guide ([#​11116](https://github.com/astral-sh/uv/pull/11116)) - Update Dependabot tracking issue link ([#​11054](https://github.com/astral-sh/uv/pull/11054)) - Update documentation for running in a container ([#​11052](https://github.com/astral-sh/uv/pull/11052)) - Upgrade PyTorch version in documentation ([#​11114](https://github.com/astral-sh/uv/pull/11114)) - Use `sys_platform` in lieu of `platform_system` in PyTorch docs ([#​11113](https://github.com/astral-sh/uv/pull/11113)) - Use positive (rather than negative) markers in PyTorch examples ([#​11112](https://github.com/astral-sh/uv/pull/11112)) - Fix unnecessary backslashes in brackets ([#​11059](https://github.com/astral-sh/uv/pull/11059)) - Suggest setting copy link mode in GitLab integration guide ([#​11067](https://github.com/astral-sh/uv/pull/11067)) ### [`v0.5.25`](https://github.com/astral-sh/uv/blob/HEAD/CHANGELOG.md#0525) [Compare Source](https://github.com/astral-sh/uv/compare/0.5.24...0.5.25) ##### Enhancements - Allow installation of manylinux wheels on loongarch64 ([#​10927](https://github.com/astral-sh/uv/pull/10927)) - Allow optional `=` for editables in `requirements.txt` ([#​10954](https://github.com/astral-sh/uv/pull/10954)) - Add Windows aarch64 to the release binaries ([#​10885](https://github.com/astral-sh/uv/pull/10885)) ##### Bug fixes - Use spec-compliant (`128+n`) exit codes for `uv run` and `uv tool run` on Unix ([#​10781](https://github.com/astral-sh/uv/pull/10781)) - Fix best-interpreter lookups when there is an invalid interpreter in the `PATH` ([#​11030](https://github.com/astral-sh/uv/pull/11030)) - Guard against concurrent cache writes on Windows ([#​11007](https://github.com/astral-sh/uv/pull/11007)) - Prioritize package preferences with greater package versions ([#​10963](https://github.com/astral-sh/uv/pull/10963)) - Reject `--editable` flag on non-directory requirements ([#​10994](https://github.com/astral-sh/uv/pull/10994)) - Respect `--no-sources` for `uv pip install` workspace discovery ([#​11003](https://github.com/astral-sh/uv/pull/11003)) - Set `JEMALLOC_SYS_WITH_LG_PAGE=16` in ARM Docker builds ([#​10943](https://github.com/astral-sh/uv/pull/10943)) - Update `riscv64` Python downloads to allow install on `riscv64gc` ([#​10937](https://github.com/astral-sh/uv/pull/10937)) - Fix file persist retries on Windows ([#​11008](https://github.com/astral-sh/uv/pull/11008)) - Fix incorrect error message when specifying `tool.uv.sources.(package).workspace` with other options ([#​11013](https://github.com/astral-sh/uv/pull/11013)) - Improve SIGINT handling in `uv run` ([#​11009](https://github.com/astral-sh/uv/pull/11009)) ##### Documentation - Add `SECURITY` policy ([#​11035](https://github.com/astral-sh/uv/pull/11035)) - Add `Requires-Python` upper bound behavior to the docs ([#​10964](https://github.com/astral-sh/uv/pull/10964)) - Add a troubleshooting section and reproducible example guide ([#​10947](https://github.com/astral-sh/uv/pull/10947)) - Add documentation for `uv add -r` ([#​10926](https://github.com/astral-sh/uv/pull/10926)) - Amend `requires-python` rules in resolver documentation ([#​10993](https://github.com/astral-sh/uv/pull/10993)) - Reference workspaces in `--no-sources` documentation ([#​10995](https://github.com/astral-sh/uv/pull/10995)) - Update documentation for activating virtual environments in different shell ([#​11000](https://github.com/astral-sh/uv/pull/11000)) - Add Docker SHA pinning tip ([#​10955](https://github.com/astral-sh/uv/pull/10955))
--- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). Reviewed-on: https://c.csw.im/cswimr/SeaCogs/pulls/53 Co-authored-by: Renovate Co-committed-by: Renovate --- .devcontainer/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 19c88c9..50a99c7 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,4 +1,4 @@ -FROM ghcr.io/astral-sh/uv:0.5.24@sha256:2381d6aa60c326b71fd40023f921a0a3b8f91b14d5db6b90402e65a635053709 AS uv +FROM ghcr.io/astral-sh/uv:0.5.30@sha256:bb74263127d6451222fe7f71b330edfb189ab1c98d7898df2401fbf4f272d9b9 AS uv FROM python:3.11-slim@sha256:6ed5bff4d7d377e2a27d9285553b8c21cfccc4f00881de1b24c9bc8d90016e82 AS python FROM code.forgejo.org/forgejo/runner:6.2.1@sha256:fecc96a111a15811a6887ce488e75718089f24599e613e93db8e54fe70b706e8 AS forgejo-runner