From d97984255080f9307aa96a8f1818eb5a5a1abe76 Mon Sep 17 00:00:00 2001 From: Vlad Emelianov Date: Sun, 12 Jan 2025 05:12:38 +0300 Subject: [PATCH] Use loguru in scripts --- mypy_boto3_builder/chat/chat_buddy.py | 2 + scripts/check_output.py | 86 +++++++++++++-------------- scripts/integration.py | 81 ++++++++++++------------- scripts/release.py | 2 - uv.lock | 78 ++++++++++++------------ 5 files changed, 119 insertions(+), 130 deletions(-) diff --git a/mypy_boto3_builder/chat/chat_buddy.py b/mypy_boto3_builder/chat/chat_buddy.py index 43c5c6bc..1b5c2bbe 100644 --- a/mypy_boto3_builder/chat/chat_buddy.py +++ b/mypy_boto3_builder/chat/chat_buddy.py @@ -18,6 +18,7 @@ from mypy_boto3_builder.cli_parser import CLINamespace from mypy_boto3_builder.constants import PROG_NAME from mypy_boto3_builder.enums.output_type import OutputType +from mypy_boto3_builder.logger import enable_logger from mypy_boto3_builder.service_name import ServiceName from mypy_boto3_builder.utils.boto3_utils import get_available_service_names from mypy_boto3_builder.utils.path import print_path @@ -654,6 +655,7 @@ def run(self) -> None: self._run_builder() def _run_builder(self) -> None: + enable_logger() self.run_builder(self.args) _linebreak() diff --git a/scripts/check_output.py b/scripts/check_output.py index 540cd235..605b2d1e 100755 --- a/scripts/check_output.py +++ b/scripts/check_output.py @@ -1,6 +1,9 @@ #!/usr/bin/env python # /// script # requires-python = ">=3.8" +# dependencies = [ +# "loguru", +# ] # /// """ Checker of generated packages. @@ -17,7 +20,6 @@ import argparse import json -import logging import shutil import subprocess import sys @@ -27,10 +29,13 @@ from pathlib import Path from typing import TYPE_CHECKING, Any +from loguru import logger + if TYPE_CHECKING: from collections.abc import Sequence ROOT_PATH = Path(__file__).parent.parent.resolve() +DEFAULT_PATH = ROOT_PATH / "mypy_boto3_output" PYRIGHT_CONFIG_PATH = Path(__file__).parent / "pyrightconfig_output.json" LOGGER_NAME = "check_output" PYRIGHT_IGNORED_MESSAGES = ( @@ -103,9 +108,8 @@ class Config: Local configuration. """ - path: Path - logger: logging.Logger - args: CLINamespace + path: Path = DEFAULT_PATH + python_version: str | None = None @classmethod def get_uvx_cmd(cls) -> tuple[str, ...]: @@ -113,8 +117,8 @@ def get_uvx_cmd(cls) -> tuple[str, ...]: Get uvx command prefix. """ result: list[str] = ["uvx", "-q"] - if cls.args.python_version: - result.extend(("--python", cls.args.python_version)) + if cls.python_version: + result.extend(("--python", cls.python_version)) return tuple(result) @@ -153,33 +157,13 @@ def __init__(self, path: Path, error: str) -> None: self.errors = error -def setup_logging(level: int) -> logging.Logger: - """ - Get Logger instance. - - Arguments: - level -- Log level - - Returns: - Overriden Logger. - """ - logger = logging.getLogger(LOGGER_NAME) - stream_handler = logging.StreamHandler() - formatter = logging.Formatter("%(asctime)s %(levelname)-7s %(message)s", datefmt="%H:%M:%S") - stream_handler.setFormatter(formatter) - stream_handler.setLevel(level) - logger.addHandler(stream_handler) - logger.setLevel(level) - return logger - - @dataclass class CLINamespace: """ CLI namespace. """ - debug: bool + log_level: str path: Path filter: list[str] exit_on_error: bool @@ -194,7 +178,7 @@ def parse_args() -> CLINamespace: parser = argparse.ArgumentParser(__file__) parser.add_argument("-d", "--debug", action="store_true") parser.add_argument("-x", "--exit-on-error", action="store_true") - parser.add_argument("-p", "--path", type=Path, default=ROOT_PATH / "mypy_boto3_output") + parser.add_argument("-p", "--path", type=Path, default=DEFAULT_PATH) parser.add_argument( "--python", type=str, @@ -205,7 +189,7 @@ def parse_args() -> CLINamespace: parser.add_argument("filter", nargs="*") args = parser.parse_args() return CLINamespace( - debug=args.debug, + log_level="DEBUG" if args.debug else "INFO", path=args.path, filter=args.filter, exit_on_error=args.exit_on_error, @@ -233,7 +217,7 @@ def run_ruff(path: Path) -> None: "lint.pyupgrade.keep-runtime-typing=true", path.as_posix(), ] - Config.logger.debug(f"Running subprocess: {' '.join(cmd)}") + logger.debug(f"Running subprocess: {' '.join(cmd)}") try: subprocess.check_call( cmd, @@ -267,7 +251,7 @@ def run_pyright(path: Path) -> None: path.as_posix(), "--outputjson", ] - Config.logger.debug(f"Running subprocess: {' '.join(cmd)}") + logger.debug(f"Running subprocess: {' '.join(cmd)}") with tempfile.NamedTemporaryFile("w+b") as f: try: subprocess.check_call( @@ -285,7 +269,7 @@ def run_pyright(path: Path) -> None: try: output_data = json.loads(output) except json.JSONDecodeError: - Config.logger.error("Pyright output is not a valid JSON") + logger.error("Pyright output is not a valid JSON") return data = output_data.get("generalDiagnostics", []) @@ -318,7 +302,7 @@ def run_mypy(path: Path) -> None: Check output with mypy. """ cmd = [*Config.get_uvx_cmd(), *get_with_arguments(), "mypy", path.as_posix()] - Config.logger.debug(f"Running subprocess: {' '.join(cmd)}") + logger.debug(f"Running subprocess: {' '.join(cmd)}") try: output = subprocess.check_output( cmd, @@ -370,7 +354,7 @@ def run_import(path: Path) -> None: "-c", f"import {path.name}", ] - Config.logger.debug(f"Running subprocess: {' '.join(cmd)}") + logger.debug(f"Running subprocess: {' '.join(cmd)}") try: subprocess.check_call(cmd, stdout=subprocess.DEVNULL) except subprocess.CalledProcessError as e: @@ -395,7 +379,6 @@ def run_checks(path: Path) -> None: Raises: CheckError -- If snapshot is not equal to current output. """ - logger = Config.logger relative_path = path.absolute().relative_to(Path.cwd()) logger.info(f"Checking {relative_path} ...") logger.debug(f"Running ruff for {relative_path} ...") @@ -412,12 +395,12 @@ def run_checks(path: Path) -> None: run_import(path) -def get_package_paths() -> tuple[Path, ...]: +def get_package_paths(path: Path, filter_names: Sequence[str]) -> tuple[Path, ...]: """ Find package directories. """ result: list[Path] = [] - for directory in sorted(Config.args.path.iterdir()): + for directory in sorted(path.iterdir()): if not directory.is_dir(): continue if not directory.name.endswith("_package"): @@ -426,9 +409,7 @@ def get_package_paths() -> tuple[Path, ...]: for package_path in directory.iterdir(): if not is_package_dir(package_path): continue - if Config.args.filter and not any( - i in package_path.as_posix() for i in Config.args.filter - ): + if filter_names and not any(i in package_path.as_posix() for i in filter_names): continue result.append(package_path) @@ -444,7 +425,7 @@ def is_run_checks_passed(path: Path) -> tuple[Path, bool]: try: run_checks(path) except CheckError as e: - Config.logger.warning(e) + logger.warning(e) return path, False return path, True @@ -455,11 +436,26 @@ def main() -> None: """ args = parse_args() Config.path = args.path - Config.args = args - Config.logger = setup_logging(logging.DEBUG if args.debug else logging.INFO) - logger = Config.logger + Config.python_version = args.python_version + logger.configure( + handlers=[ + { + "sink": sys.stderr, + "level": args.log_level, + "format": ( + "{time:YYYY-MM-DD HH:mm:ss.SSS} | " + "{level: <8} | " + f"{Path(__file__).stem} - " + "{message}" + ), + } + ] + ) has_errors = False - package_paths = get_package_paths() + package_paths = get_package_paths( + path=args.path, + filter_names=args.filter, + ) if not package_paths: logger.error(f"No packages found if {args.path}") diff --git a/scripts/integration.py b/scripts/integration.py index b0e3f426..c6918bad 100755 --- a/scripts/integration.py +++ b/scripts/integration.py @@ -1,6 +1,9 @@ #!/usr/bin/env python # /// script # requires-python = ">=3.8" +# dependencies = [ +# "loguru", +# ] # /// """ Integration tests. @@ -14,7 +17,6 @@ import difflib import enum import json -import logging import shutil import subprocess import sys @@ -24,6 +26,8 @@ from pathlib import Path from typing import TYPE_CHECKING +from loguru import logger + if TYPE_CHECKING: from collections.abc import Sequence @@ -32,7 +36,6 @@ TYPES_BOTO3_PATH = ROOT_PATH / "integration" / "types-boto3" TYPES_AIOBOTO3_PATH = ROOT_PATH / "integration" / "types-aioboto3" SCRIPTS_PATH = ROOT_PATH / "scripts" -LOGGER_NAME = "integration" TEMP_PATH = Path(tempfile.TemporaryDirectory().name) @@ -41,8 +44,8 @@ class Config: Config for integration tests. """ - args: CLINamespace - logger: logging.Logger + python_version: str | None = None + products: tuple[Product, ...] = () install_paths: Sequence[Path] = () @classmethod @@ -51,9 +54,9 @@ def get_uvx_arguments(cls) -> list[str]: Get `uvx` arguments. """ result: list[str] = ["-q"] - if cls.args.python_version: - result.extend(["--python", cls.args.python_version]) - with_libraries = list(chain.from_iterable(p.prerequisites for p in cls.args.products)) + if cls.python_version: + result.extend(["--python", cls.python_version]) + with_libraries = list(chain.from_iterable(p.prerequisites for p in cls.products)) for library_name in with_libraries: result.extend(["--with", library_name]) for install_path in cls.install_paths: @@ -195,28 +198,6 @@ def get(cls, name: str) -> Product: raise ValueError(f"Unknown product: {name}") -def setup_logging(level: int) -> logging.Logger: - """ - Get Logger instance. - - Arguments: - level -- Logging level - - Returns: - Created Logger. - """ - logger = logging.getLogger(LOGGER_NAME) - stream_handler = logging.StreamHandler() - formatter = logging.Formatter( - "%(asctime)s %(name)s %(levelname)-7s %(message)s", datefmt="%H:%M:%S" - ) - stream_handler.setFormatter(formatter) - stream_handler.setLevel(level) - logger.addHandler(stream_handler) - logger.setLevel(level) - return logger - - def print_path(path: Path) -> str: """ Get path as a string relative to current workdir. @@ -243,8 +224,8 @@ class CLINamespace: CLI namespace. """ - log_level: int - products: list[Product] + log_level: str + products: tuple[Product, ...] fast: bool update: bool services: tuple[str, ...] @@ -287,8 +268,8 @@ def parse_args() -> CLINamespace: parser.add_argument("-w", "--wheel", action="store_true", help="Build wheel packages") args = parser.parse_args() return CLINamespace( - log_level=logging.DEBUG if args.debug else logging.INFO, - products=[ProductChoices.get(name) for name in args.product], + log_level="DEBUG" if args.debug else "INFO", + products=tuple(ProductChoices.get(name) for name in args.product), fast=args.fast, update=args.update, services=tuple(args.services), @@ -302,7 +283,6 @@ def check_call(cmd: Sequence[str]) -> str: """ Check command exit code and output on error. """ - logger = Config.logger logger.debug(f"Running process: {' '.join(cmd)}") try: return subprocess.check_output(cmd, stderr=subprocess.STDOUT).decode() @@ -316,6 +296,7 @@ def build_packages( products: Sequence[Product], output_path: Path, output_type: str, + services: Sequence[str], ) -> list[Path]: """ Build and install stubs. @@ -323,12 +304,11 @@ def build_packages( - boto3: `types-boto3` - aioboto3: `types-aioboto3` and `types-aiobotocore` """ - logger = Config.logger prerequisites: set[str] = set() build_products: set[str] = set() service_names: set[str] = set() for product in products: - product.find_service_names(Config.args.services) + product.find_service_names(services) build_products.update(product.build_products) prerequisites.update(product.prerequisites) service_names.update(product.service_names) @@ -360,7 +340,6 @@ def compare(data: str, snapshot_path: Path, *, update: bool) -> None: Compare tool output with a snapshot. """ data = data.strip() - logger = logging.getLogger(LOGGER_NAME) if not snapshot_path.exists(): snapshot_path.write_text(data) logger.info(f"Created {print_path(snapshot_path)}") @@ -393,7 +372,7 @@ def run_pyright(path: Path, snapshot_path: Path, *, update: bool) -> None: config_path = ROOT_PATH / "pyrightconfig.json" shutil.copyfile(PYRIGHT_CONFIG_PATH, config_path) cmd = ["uvx", *Config.get_uvx_arguments(), "pyright", path.as_posix(), "--outputjson"] - Config.logger.debug(f"Running process: {' '.join(cmd)}") + logger.debug(f"Running process: {' '.join(cmd)}") try: output = subprocess.check_output(cmd, stderr=subprocess.DEVNULL, encoding="utf8") except subprocess.CalledProcessError as e: @@ -417,7 +396,7 @@ def run_mypy(path: Path, snapshot_path: Path, *, update: bool) -> None: Run `mypy` and compare output. """ cmd = ["uvx", *Config.get_uvx_arguments(), "mypy", path.as_posix(), "--no-incremental"] - Config.logger.debug(f"Running process: {' '.join(cmd)}") + logger.debug(f"Running process: {' '.join(cmd)}") try: output = subprocess.check_output(cmd, stderr=subprocess.STDOUT, encoding="utf8") except subprocess.CalledProcessError as e: @@ -432,7 +411,7 @@ def run_mypy(path: Path, snapshot_path: Path, *, update: bool) -> None: compare(new_data, snapshot_path, update=update) -def get_service_names(product: Product) -> list[str]: +def get_service_names(product: Product, services: Sequence[str]) -> list[str]: """ Get service names from config. """ @@ -441,7 +420,7 @@ def get_service_names(product: Product) -> list[str]: if not file.name.endswith("_example.py"): continue service_name = file.name.replace("_example.py", "") - if Config.args.services and service_name not in Config.args.services: + if services and service_name not in services: continue service_names.append(service_name) @@ -453,9 +432,22 @@ def main() -> None: Run main logic. """ args = parse_args() - logger = setup_logging(args.log_level) - Config.args = args - Config.logger = logger + logger.configure( + handlers=[ + { + "sink": sys.stderr, + "level": args.log_level, + "format": ( + "{time:YYYY-MM-DD HH:mm:ss.SSS} | " + "{level: <8} | " + f"{Path(__file__).stem} - " + "{message}" + ), + } + ] + ) + Config.python_version = args.python_version + Config.products = args.products error: Exception | None = None if not args.fast: @@ -464,6 +456,7 @@ def main() -> None: products=args.products, output_path=args.output_path, output_type="wheel" if args.wheel else "package", + services=args.services, ) Config.install_paths = install_paths diff --git a/scripts/release.py b/scripts/release.py index a934feaf..964bc11d 100755 --- a/scripts/release.py +++ b/scripts/release.py @@ -19,7 +19,6 @@ import argparse import itertools -import logging import os import shutil import subprocess @@ -271,7 +270,6 @@ def publish_batches(args: CLINamespace, path_batches: Sequence[Sequence[Sequence """ total = sum(len(i) for i in path_batches) current_total = 0 - logger = logging.getLogger(LOGGER_NAME) for path_batch in path_batches: if args.publish_threads == 1: for index, paths in enumerate(map(publish, path_batch)): diff --git a/uv.lock b/uv.lock index 057d15e9..c17ca91c 100644 --- a/uv.lock +++ b/uv.lock @@ -80,55 +80,55 @@ wheels = [ [[package]] name = "boto3" -version = "1.35.96" +version = "1.35.97" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "botocore" }, { name = "jmespath" }, { name = "s3transfer" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/fc/6c/ea481adf32791472885664224ac8e5269a4429db2e510d9fa56c493407e9/boto3-1.35.96.tar.gz", hash = "sha256:bace02ef2181d176cedc1f8f90c95c301bb7c555db124cf80bc193cbb52a7c64", size = 110999 } +sdist = { url = "https://files.pythonhosted.org/packages/b0/0b/be51ba3bf22832bc918b4059ca182877681b02a45627c51d70efbbf1991d/boto3-1.35.97.tar.gz", hash = "sha256:7d398f66a11e67777c189d1f58c0a75d9d60f98d0ee51b8817e828930bf19e4e", size = 110994 } wheels = [ - { url = "https://files.pythonhosted.org/packages/17/07/a1da47e567f7550783a6def2b1840d1b69c1f0cd4933e6f1c5942ff4a6c6/boto3-1.35.96-py3-none-any.whl", hash = "sha256:e6acb2380791b13d8fd55062d9bbc6e27c3ddb3e73cff71c4ca02e6743780c67", size = 139181 }, + { url = "https://files.pythonhosted.org/packages/ec/15/0c39a7f80bab931fb3757d8bdefa2fc98b154b46544996d2f1d7b8e26365/boto3-1.35.97-py3-none-any.whl", hash = "sha256:8e49416216a6e3a62c2a0c44fba4dd2852c85472e7b702516605b1363867d220", size = 139180 }, ] [[package]] name = "boto3-stubs" -version = "1.35.96" +version = "1.35.97" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "botocore-stubs" }, { name = "types-s3transfer" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/30/44/db9e344416685088d881297d3cd4b5bb71637c4ac29333cb4635e05d451d/boto3_stubs-1.35.96.tar.gz", hash = "sha256:03685bf3c62f2a34eb8e55420074f175940153cd900e45caf3ae3156ee6c7861", size = 98565 } +sdist = { url = "https://files.pythonhosted.org/packages/0f/a9/c4e8c8e0e0971fd1a43997030d975c4fc323f204b66a06fad2588eafd7d3/boto3_stubs-1.35.97.tar.gz", hash = "sha256:4182f9f18f279969fbcb697200f9a89a6b07a95e45f7db276ab90dcdf65a72ba", size = 98586 } wheels = [ - { url = "https://files.pythonhosted.org/packages/88/1b/6d7b0964fcbd521b0cd39cbd1cc93bd39a7232719c6d1b07e49bfa4a7169/boto3_stubs-1.35.96-py3-none-any.whl", hash = "sha256:4a6c1590a4183a9fc758aa738e9f71bb4b9471aadb0bd49df62aa479bab8a80c", size = 68245 }, + { url = "https://files.pythonhosted.org/packages/fa/d8/feb6319e057e25ad6dc5bf59863d012eda09bd74525b32f6571aba3a12cd/boto3_stubs-1.35.97-py3-none-any.whl", hash = "sha256:da33f2a540c942505d761bcc59bc16d607a9adb815198967d66b38515a4a60e8", size = 68247 }, ] [[package]] name = "botocore" -version = "1.35.96" +version = "1.35.97" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "jmespath" }, { name = "python-dateutil" }, { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/d3/b2/9b2558e3f0094eb4829338bca777fc0747ad69fa8fe0b5f692d7e4e86bea/botocore-1.35.96.tar.gz", hash = "sha256:385fd406ed14bdd624e082d3e15dd6575d490d5d7374fb02f0a798c3ca9ea802", size = 13488154 } +sdist = { url = "https://files.pythonhosted.org/packages/48/cd/79656501384e265c9b3099358da2ec6a18568ddf44e5dd61582692a3e7b3/botocore-1.35.97.tar.gz", hash = "sha256:88f2fab29192ffe2f2115d5bafbbd823ff4b6eb2774296e03ec8b5b0fe074f61", size = 13488547 } wheels = [ - { url = "https://files.pythonhosted.org/packages/65/bc/9ba93a90b3f53afdd5d27c4a0b7bc19b5b9d6ad0e1489b4c5cd47ef6fbe4/botocore-1.35.96-py3-none-any.whl", hash = "sha256:b5f4cf11372aeccf87bb0b6148a020212c4c42fb5bcdebb6590bb10f6612b98e", size = 13289712 }, + { url = "https://files.pythonhosted.org/packages/f7/81/ce588b6713ce81f2b95a4097ebd4047e38f5925f5d4c07abc73087744bc1/botocore-1.35.97-py3-none-any.whl", hash = "sha256:fed4f156b1a9b8ece53738f702ba5851b8c6216b4952de326547f349cc494f14", size = 13289762 }, ] [[package]] name = "botocore-stubs" -version = "1.35.96" +version = "1.35.97" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "types-awscrt" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/5e/11/dfa9067f30a927e216ef2f63d898cc9b9949ac7aec011aa39c92413d8632/botocore_stubs-1.35.96.tar.gz", hash = "sha256:a417dcdcf127da644c975963bc7403b188d2ae5a8c1bb907849d4b8681e4fb90", size = 41116 } +sdist = { url = "https://files.pythonhosted.org/packages/d6/f8/e2821dc1e3d611c10d438f145964279901369d8518faca00b2a82ec2a211/botocore_stubs-1.35.97.tar.gz", hash = "sha256:aae08ea4a2aa3c360cfd783f8e4c713db64351b429baee148820d5b0a6d9221a", size = 41111 } wheels = [ - { url = "https://files.pythonhosted.org/packages/75/ae/f88d89acc68ac8ac1c02e22ca0f0256b26f5744ad091774ee54fe87fb321/botocore_stubs-1.35.96-py3-none-any.whl", hash = "sha256:699fd80064e5ae2c25e566e6ebdf235b523aab0f8dbbcb5ae80a7247cbfbce38", size = 63934 }, + { url = "https://files.pythonhosted.org/packages/76/6b/bdab3f2486c1a1397e201f855412bec84259cb65267a84ccd8be2a7a4196/botocore_stubs-1.35.97-py3-none-any.whl", hash = "sha256:5427684c2248ad3db66c83b96e2486ebbacf13d7ba648a5acad7f422a086c419", size = 63934 }, ] [[package]] @@ -1046,27 +1046,27 @@ wheels = [ [[package]] name = "ruff" -version = "0.9.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/75/48/385f276f41e89623a5ea8e4eb9c619a44fdfc2a64849916b3584eca6cb9f/ruff-0.9.0.tar.gz", hash = "sha256:143f68fa5560ecf10fc49878b73cee3eab98b777fcf43b0e62d43d42f5ef9d8b", size = 3489167 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/e9/01/e0885e5519212efc7ab9d868bc39cb9781931c4c6f9b17becafa81193ec4/ruff-0.9.0-py3-none-linux_armv6l.whl", hash = "sha256:949b3513f931741e006cf267bf89611edff04e1f012013424022add3ce78f319", size = 10647069 }, - { url = "https://files.pythonhosted.org/packages/dd/69/510a9a5781dcf84c2ad513c2003936fefc802f39c745d5f2355d77fa45fd/ruff-0.9.0-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:99fbcb8c7fe94ae1e462ab2a1ef17cb20b25fb6438b9f198b1bcf5207a0a7916", size = 10401936 }, - { url = "https://files.pythonhosted.org/packages/07/9f/37fb86bfdf28c4cbfe94cbcc01fb9ab0cb8128548f243f34d5298b212562/ruff-0.9.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:0b022afd8eb0fcfce1e0adec84322abf4d6ce3cd285b3b99c4f17aae7decf749", size = 10010347 }, - { url = "https://files.pythonhosted.org/packages/30/0d/b95121f53c7f7bfb7ba427a35d25f983ed3b476620c5cd69f45caa5b294e/ruff-0.9.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:336567ce92c9ca8ec62780d07b5fa11fbc881dc7bb40958f93a7d621e7ab4589", size = 10882152 }, - { url = "https://files.pythonhosted.org/packages/d4/0b/a955cb6b19eb900c4c594707ab72132ce2d5cd8b5565137fb8fed21b8f08/ruff-0.9.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d338336c44bda602dc8e8766836ac0441e5b0dfeac3af1bd311a97ebaf087a75", size = 10405502 }, - { url = "https://files.pythonhosted.org/packages/1e/fa/9a6c70af74f20edd2519b89eb3322f4bfa399315cf306383443700f2d6b6/ruff-0.9.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d9b3ececf523d733e90b540e7afcc0494189e8999847f8855747acd5a9a8c45f", size = 11465069 }, - { url = "https://files.pythonhosted.org/packages/ee/8b/7effac8915470da496be009fe861060baff2692f92801976b2c01cdc8c54/ruff-0.9.0-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:a11c0872a31232e473e2e0e2107f3d294dbadd2f83fb281c3eb1c22a24866924", size = 12176850 }, - { url = "https://files.pythonhosted.org/packages/bd/ed/626179786889eca47b1e821c1582622ac0c1c8f01d60ac974f8b96867a57/ruff-0.9.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b5fd06220c17a9cc0dc7fc6552f2ac4db74e8e8bff9c401d160ac59d00566f54", size = 11700963 }, - { url = "https://files.pythonhosted.org/packages/75/79/094c34ddec47fd3c61a0bc5e83ca164344c592949cff91f05961fd40922e/ruff-0.9.0-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0457e775c74bf3976243f910805242b7dcd389e1d440deccbd1194ca17a5728c", size = 13096560 }, - { url = "https://files.pythonhosted.org/packages/e7/23/ec85dca0dcb329835197401734501bfa1d39e72343df64628c67b72bcbf5/ruff-0.9.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:05415599bbcb318f730ea1b46a39e4fbf71f6a63fdbfa1dda92efb55f19d7ecf", size = 11278658 }, - { url = "https://files.pythonhosted.org/packages/6c/17/1b3ea5f06578ea1daa08ac35f9de099d1827eea6e116a8cabbf11235c925/ruff-0.9.0-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:fbf9864b009e43cfc1c8bed1a6a4c529156913105780af4141ca4342148517f5", size = 10879847 }, - { url = "https://files.pythonhosted.org/packages/a6/e5/00bc97d6f419da03c0d898e95cca77311494e7274dc7cc17d94976e32e52/ruff-0.9.0-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:37b3da222b12e2bb2ce628e02586ab4846b1ed7f31f42a5a0683b213453b2d49", size = 10494220 }, - { url = "https://files.pythonhosted.org/packages/cc/70/d0a23d94f3e40b7ffac0e5506f33bb504672569173781a6c7cab0db6a4ba/ruff-0.9.0-py3-none-musllinux_1_2_i686.whl", hash = "sha256:733c0fcf2eb0c90055100b4ed1af9c9d87305b901a8feb6a0451fa53ed88199d", size = 11004182 }, - { url = "https://files.pythonhosted.org/packages/20/8e/367cf8e401890f823d0e4eb33635d0113719d5660b6522b7295376dd95fd/ruff-0.9.0-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:8221a454bfe5ccdf8017512fd6bb60e6ec30f9ea252b8a80e5b73619f6c3cefd", size = 11345761 }, - { url = "https://files.pythonhosted.org/packages/fe/08/4b54e02da73060ebc29368ab15868613f7d2496bde3b01d284d5423646bc/ruff-0.9.0-py3-none-win32.whl", hash = "sha256:d345f2178afd192c7991ddee59155c58145e12ad81310b509bd2e25c5b0247b3", size = 8807005 }, - { url = "https://files.pythonhosted.org/packages/a1/a7/0b422971e897c51bf805f998d75bcfe5d4d858f5002203832875fc91b733/ruff-0.9.0-py3-none-win_amd64.whl", hash = "sha256:0cbc0905d94d21305872f7f8224e30f4bbcd532bc21b2225b2446d8fc7220d19", size = 9689974 }, - { url = "https://files.pythonhosted.org/packages/73/0e/c00f66731e514be3299801b1d9d54efae0abfe8f00a5c14155f2ab9e2920/ruff-0.9.0-py3-none-win_arm64.whl", hash = "sha256:7b1148771c6ca88f820d761350a053a5794bc58e0867739ea93eb5e41ad978cd", size = 9147729 }, +version = "0.9.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/67/3e/e89f736f01aa9517a97e2e7e0ce8d34a4d8207087b3cfdec95133fee13b5/ruff-0.9.1.tar.gz", hash = "sha256:fd2b25ecaf907d6458fa842675382c8597b3c746a2dde6717fe3415425df0c17", size = 3498844 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/dc/05/c3a2e0feb3d5d394cdfd552de01df9d3ec8a3a3771bbff247fab7e668653/ruff-0.9.1-py3-none-linux_armv6l.whl", hash = "sha256:84330dda7abcc270e6055551aca93fdde1b0685fc4fd358f26410f9349cf1743", size = 10645241 }, + { url = "https://files.pythonhosted.org/packages/dd/da/59f0a40e5f88ee5c054ad175caaa2319fc96571e1d29ab4730728f2aad4f/ruff-0.9.1-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:3cae39ba5d137054b0e5b472aee3b78a7c884e61591b100aeb544bcd1fc38d4f", size = 10391066 }, + { url = "https://files.pythonhosted.org/packages/b7/fe/85e1c1acf0ba04a3f2d54ae61073da030f7a5dc386194f96f3c6ca444a78/ruff-0.9.1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:50c647ff96f4ba288db0ad87048257753733763b409b2faf2ea78b45c8bb7fcb", size = 10012308 }, + { url = "https://files.pythonhosted.org/packages/6f/9b/780aa5d4bdca8dcea4309264b8faa304bac30e1ce0bcc910422bfcadd203/ruff-0.9.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f0c8b149e9c7353cace7d698e1656ffcf1e36e50f8ea3b5d5f7f87ff9986a7ca", size = 10881960 }, + { url = "https://files.pythonhosted.org/packages/12/f4/dac4361afbfe520afa7186439e8094e4884ae3b15c8fc75fb2e759c1f267/ruff-0.9.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:beb3298604540c884d8b282fe7625651378e1986c25df51dec5b2f60cafc31ce", size = 10414803 }, + { url = "https://files.pythonhosted.org/packages/f0/a2/057a3cb7999513cb78d6cb33a7d1cc6401c82d7332583786e4dad9e38e44/ruff-0.9.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:39d0174ccc45c439093971cc06ed3ac4dc545f5e8bdacf9f067adf879544d969", size = 11464929 }, + { url = "https://files.pythonhosted.org/packages/eb/c6/1ccfcc209bee465ced4874dcfeaadc88aafcc1ea9c9f31ef66f063c187f0/ruff-0.9.1-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:69572926c0f0c9912288915214ca9b2809525ea263603370b9e00bed2ba56dbd", size = 12170717 }, + { url = "https://files.pythonhosted.org/packages/84/97/4a524027518525c7cf6931e9fd3b2382be5e4b75b2b61bec02681a7685a5/ruff-0.9.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:937267afce0c9170d6d29f01fcd1f4378172dec6760a9f4dface48cdabf9610a", size = 11708921 }, + { url = "https://files.pythonhosted.org/packages/a6/a4/4e77cf6065c700d5593b25fca6cf725b1ab6d70674904f876254d0112ed0/ruff-0.9.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:186c2313de946f2c22bdf5954b8dd083e124bcfb685732cfb0beae0c47233d9b", size = 13058074 }, + { url = "https://files.pythonhosted.org/packages/f9/d6/fcb78e0531e863d0a952c4c5600cc5cd317437f0e5f031cd2288b117bb37/ruff-0.9.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3f94942a3bb767675d9a051867c036655fe9f6c8a491539156a6f7e6b5f31831", size = 11281093 }, + { url = "https://files.pythonhosted.org/packages/e4/3b/7235bbeff00c95dc2d073cfdbf2b871b5bbf476754c5d277815d286b4328/ruff-0.9.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:728d791b769cc28c05f12c280f99e8896932e9833fef1dd8756a6af2261fd1ab", size = 10882610 }, + { url = "https://files.pythonhosted.org/packages/2a/66/5599d23257c61cf038137f82999ca8f9d0080d9d5134440a461bef85b461/ruff-0.9.1-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:2f312c86fb40c5c02b44a29a750ee3b21002bd813b5233facdaf63a51d9a85e1", size = 10489273 }, + { url = "https://files.pythonhosted.org/packages/78/85/de4aa057e2532db0f9761e2c2c13834991e087787b93e4aeb5f1cb10d2df/ruff-0.9.1-py3-none-musllinux_1_2_i686.whl", hash = "sha256:ae017c3a29bee341ba584f3823f805abbe5fe9cd97f87ed07ecbf533c4c88366", size = 11003314 }, + { url = "https://files.pythonhosted.org/packages/00/42/afedcaa089116d81447347f76041ff46025849fedb0ed2b187d24cf70fca/ruff-0.9.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:5dc40a378a0e21b4cfe2b8a0f1812a6572fc7b230ef12cd9fac9161aa91d807f", size = 11342982 }, + { url = "https://files.pythonhosted.org/packages/39/c6/fe45f3eb27e3948b41a305d8b768e949bf6a39310e9df73f6c576d7f1d9f/ruff-0.9.1-py3-none-win32.whl", hash = "sha256:46ebf5cc106cf7e7378ca3c28ce4293b61b449cd121b98699be727d40b79ba72", size = 8819750 }, + { url = "https://files.pythonhosted.org/packages/38/8d/580db77c3b9d5c3d9479e55b0b832d279c30c8f00ab0190d4cd8fc67831c/ruff-0.9.1-py3-none-win_amd64.whl", hash = "sha256:342a824b46ddbcdddd3abfbb332fa7fcaac5488bf18073e841236aadf4ad5c19", size = 9701331 }, + { url = "https://files.pythonhosted.org/packages/b2/94/0498cdb7316ed67a1928300dd87d659c933479f44dec51b4f62bfd1f8028/ruff-0.9.1-py3-none-win_arm64.whl", hash = "sha256:1cd76c7f9c679e6e8f2af8f778367dca82b95009bc7b1a85a47f1521ae524fa7", size = 9145708 }, ] [[package]] @@ -1169,15 +1169,15 @@ wheels = [ [[package]] name = "types-boto3" -version = "1.35.96" +version = "1.35.97" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "botocore-stubs" }, { name = "types-s3transfer" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/16/0e/65a5a88cbdc57c2e82fc72643aa4668f6e17e1fd0f995df12cca864aec9d/types_boto3-1.35.96.tar.gz", hash = "sha256:e8d7db7d4db5d42faa64c765a34d0e7edf85d29ccd3a03a812e89ae49503025b", size = 99018 } +sdist = { url = "https://files.pythonhosted.org/packages/97/e8/7b108b0d3563200813e895e26970914bb9d8651afd5a3c2595aa1984ecf0/types_boto3-1.35.97.tar.gz", hash = "sha256:123c16afe501b17aa8f80a8b07f4f922edc5be30837e8131658b2fec1952570b", size = 99037 } wheels = [ - { url = "https://files.pythonhosted.org/packages/48/c2/7b6fce22a701be5d9ec973a64f8003cfc8d2e1d4b85047dc774209f0e234/types_boto3-1.35.96-py3-none-any.whl", hash = "sha256:eb336201c16235c90769289aa80c6338c5b2d3e2ecc303a3d7c8520f85d47438", size = 68171 }, + { url = "https://files.pythonhosted.org/packages/cb/c2/85c1d102b461c8c01ac479b92df5b4d04960acf12fa9fe8ae119c9fda56f/types_boto3-1.35.97-py3-none-any.whl", hash = "sha256:2ace973b5ab6be31d03d3642b53b46bf56e29ab227740ad9f490557a7a15b39f", size = 68170 }, ] [[package]] @@ -1221,11 +1221,11 @@ wheels = [ [[package]] name = "types-setuptools" -version = "75.6.0.20241223" +version = "75.8.0.20250110" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/53/48/a89068ef20e3bbb559457faf0fd3c18df6df5df73b4b48ebf466974e1f54/types_setuptools-75.6.0.20241223.tar.gz", hash = "sha256:d9478a985057ed48a994c707f548e55aababa85fe1c9b212f43ab5a1fffd3211", size = 48063 } +sdist = { url = "https://files.pythonhosted.org/packages/f7/42/5713e90d4f9683f2301d900f33e4fc2405ad8ac224dda30f6cb7f4cd215b/types_setuptools-75.8.0.20250110.tar.gz", hash = "sha256:96f7ec8bbd6e0a54ea180d66ad68ad7a1d7954e7281a710ea2de75e355545271", size = 48185 } wheels = [ - { url = "https://files.pythonhosted.org/packages/41/2f/051d5d23711209d4077d95c62fa8ef6119df7298635e3a929e50376219d1/types_setuptools-75.6.0.20241223-py3-none-any.whl", hash = "sha256:7cbfd3bf2944f88bbcdd321b86ddd878232a277be95d44c78a53585d78ebc2f6", size = 71377 }, + { url = "https://files.pythonhosted.org/packages/cf/a3/dbfd106751b11c728cec21cc62cbfe7ff7391b935c4b6e8f0bdc2e6fd541/types_setuptools-75.8.0.20250110-py3-none-any.whl", hash = "sha256:a9f12980bbf9bcdc23ecd80755789085bad6bfce4060c2275bc2b4ca9f2bc480", size = 71521 }, ] [[package]]