diff --git a/pyproject.toml b/pyproject.toml index 8acb611c..88ed43e7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -82,7 +82,7 @@ dev = [ "pytest-cov>=7.0.0", "pytest-xdist[psutil]>=3.8.0", # lint - "ruff>=0.14.5", + "ruff>=0.16.5", # tests with all python versions "tox>=4.32.0", "tox-uv>=1.29.0", @@ -161,7 +161,8 @@ lint.select = [ "PL", # PyLint checks "RUF", # Specific to Ruff checks "FA102", # Future annotations - "UP" # Pyupgrade + "UP", # Pyupgrade + "G", # flake8-logging-format ] lint.ignore = [ "D105", # Missing docstring in magic method @@ -172,6 +173,7 @@ lint.ignore = [ "D100", # Missing docstring in public module "ANN401", # typing.Any are disallowed in `**kwargs "PLR0913", # Too many arguments for function call + "PLR0917", # Too many positional arguments "D106" # Missing docstring in public nested class ] lint.mccabe = { max-complexity = 10 } diff --git a/taskiq/abc/broker.py b/taskiq/abc/broker.py index ea2e86c0..f676b2a3 100644 --- a/taskiq/abc/broker.py +++ b/taskiq/abc/broker.py @@ -177,8 +177,8 @@ def add_middlewares(self, *middlewares: "TaskiqMiddleware") -> None: for middleware in middlewares: if not isinstance(middleware, TaskiqMiddleware): logger.warning( - f"Middleware {middleware} is not an instance of TaskiqMiddleware. " - "Skipping...", + "Middleware %s is not an instance of TaskiqMiddleware. Skipping...", + middleware, ) continue middleware.set_broker(self) @@ -464,8 +464,8 @@ def with_middlewares( for middleware in middlewares: if not isinstance(middleware, TaskiqMiddleware): logger.warning( - f"Middleware {middleware} is not an instance of TaskiqMiddleware. " - "Skipping...", + "Middleware %s is not an instance of TaskiqMiddleware. Skipping...", + middleware, ) continue middleware.set_broker(self) diff --git a/taskiq/abc/middleware.py b/taskiq/abc/middleware.py index dd908649..cba52e16 100644 --- a/taskiq/abc/middleware.py +++ b/taskiq/abc/middleware.py @@ -24,7 +24,7 @@ def set_broker(self, broker: "AsyncBroker") -> None: def startup( self, - ) -> Union[None, Coroutine[Any, Any, None], "CoroutineType[Any, Any, None]"]: + ) -> Union[Coroutine[Any, Any, None], "CoroutineType[Any, Any, None]", None]: """ Startup method to perform various action during startup. @@ -36,7 +36,7 @@ def startup( def shutdown( self, - ) -> Union[None, Coroutine[Any, Any, None], "CoroutineType[Any, Any, None]"]: + ) -> Union[Coroutine[Any, Any, None], "CoroutineType[Any, Any, None]", None]: """ Shutdown method to perform various action during shutdown. @@ -68,7 +68,7 @@ def pre_send( def post_send( self, message: "TaskiqMessage", - ) -> Union[None, Coroutine[Any, Any, None], "CoroutineType[Any, Any, None]"]: + ) -> Union[Coroutine[Any, Any, None], "CoroutineType[Any, Any, None]", None]: """ This hook is executed right after the task is sent. @@ -101,7 +101,7 @@ def post_execute( self, message: "TaskiqMessage", result: "TaskiqResult[Any]", - ) -> Union[None, Coroutine[Any, Any, None], "CoroutineType[Any, Any, None]"]: + ) -> Union[Coroutine[Any, Any, None], "CoroutineType[Any, Any, None]", None]: """ This hook executes after task is complete. @@ -116,7 +116,7 @@ def post_save( self, message: "TaskiqMessage", result: "TaskiqResult[Any]", - ) -> Union[None, Coroutine[Any, Any, None], "CoroutineType[Any, Any, None]"]: + ) -> Union[Coroutine[Any, Any, None], "CoroutineType[Any, Any, None]", None]: """ Post save hook. @@ -132,7 +132,7 @@ def on_error( message: "TaskiqMessage", result: "TaskiqResult[Any]", exception: BaseException, - ) -> Union[None, Coroutine[Any, Any, None], "CoroutineType[Any, Any, None]"]: + ) -> Union[Coroutine[Any, Any, None], "CoroutineType[Any, Any, None]", None]: """ This function is called when exception is found. diff --git a/taskiq/abc/schedule_source.py b/taskiq/abc/schedule_source.py index c196078c..8cec23d0 100644 --- a/taskiq/abc/schedule_source.py +++ b/taskiq/abc/schedule_source.py @@ -58,7 +58,7 @@ async def delete_schedule(self, schedule_id: str) -> None: def pre_send( # noqa: B027 self, task: "ScheduledTask", - ) -> Union[None, "CoroutineType[Any, Any, None]", Coroutine[Any, Any, None]]: + ) -> Union["CoroutineType[Any, Any, None]", Coroutine[Any, Any, None], None]: """ Actions to execute before task will be sent to broker. @@ -71,7 +71,7 @@ def pre_send( # noqa: B027 def post_send( # noqa: B027 self, task: "ScheduledTask", - ) -> Union[None, "CoroutineType[Any, Any, None]", Coroutine[Any, Any, None]]: + ) -> Union["CoroutineType[Any, Any, None]", Coroutine[Any, Any, None], None]: """ Actions to execute after task was sent to broker. diff --git a/taskiq/acks.py b/taskiq/acks.py index 894a9160..8b2341bd 100644 --- a/taskiq/acks.py +++ b/taskiq/acks.py @@ -54,13 +54,13 @@ class AckableMessage(BaseModel): """ data: bytes - ack: Callable[[], None | Awaitable[None]] + ack: Callable[[], Awaitable[None] | None] class AckController: """Controls acknowledgement state for a received message.""" - def __init__(self, ack: Callable[[], None | Awaitable[None]] | None) -> None: + def __init__(self, ack: Callable[[], Awaitable[None] | None] | None) -> None: self._ack = ack self.is_acked = False diff --git a/taskiq/cli/scheduler/run.py b/taskiq/cli/scheduler/run.py index 60390538..03c9faf6 100644 --- a/taskiq/cli/scheduler/run.py +++ b/taskiq/cli/scheduler/run.py @@ -47,13 +47,8 @@ async def get_schedules(source: ScheduleSource) -> list[ScheduledTask]: """ try: return await source.get_schedules() - except Exception as exc: - logger.error( - "Cannot update schedules with source: %s\n%s{}", - source, - exc, - exc_info=True, - ) + except Exception: + logger.exception("Cannot update schedules with source: %s", source) return [] diff --git a/taskiq/cli/utils.py b/taskiq/cli/utils.py index a8554d37..ffb44d1c 100644 --- a/taskiq/cli/utils.py +++ b/taskiq/cli/utils.py @@ -25,7 +25,7 @@ def add_cwd_in_path() -> Generator[None, None, None]: if str(cwd) in sys.path: yield else: - logger.debug(f"Inserting {cwd} in sys.path") + logger.debug("Inserting %s in sys.path", cwd) sys.path.insert(0, str(cwd)) try: yield @@ -33,7 +33,7 @@ def add_cwd_in_path() -> Generator[None, None, None]: try: sys.path.remove(str(cwd)) except ValueError: - logger.warning(f"Cannot remove '{cwd}' from sys.path") + logger.warning("Cannot remove '%s' from sys.path", cwd) def import_object(object_spec: str, app_dir: str | None = None) -> Any: @@ -63,11 +63,11 @@ def import_from_modules(modules: list[str]) -> None: """ for module in modules: try: - logger.info(f"Importing tasks from module {module}") + logger.info("Importing tasks from module %s", module) with add_cwd_in_path(): import_module(module) except ImportError as err: - logger.warning(f"Cannot import {module}. Cause:") + logger.warning("Cannot import %s. Cause:", module) logger.exception(err) diff --git a/taskiq/cli/watcher.py b/taskiq/cli/watcher.py index a16264d9..246ae5b9 100644 --- a/taskiq/cli/watcher.py +++ b/taskiq/cli/watcher.py @@ -56,9 +56,11 @@ def dispatch(self, event: FileSystemEvent) -> None: return except Exception as exc: logger.info( - f"Cannot check path `{event.src_path!r}` in gitignore. Cause: {exc}", + "Cannot check path `%r` in gitignore. Cause: %s", + event.src_path, + exc, ) return - logger.debug(f"File changed. Event: {event}") + logger.debug("File changed. Event: %s", event) self.callback(**self.callback_kwargs) diff --git a/taskiq/cli/worker/process_manager.py b/taskiq/cli/worker/process_manager.py index 22257e86..b5d27427 100644 --- a/taskiq/cli/worker/process_manager.py +++ b/taskiq/cli/worker/process_manager.py @@ -77,7 +77,7 @@ def handle( try: worker.terminate() except ValueError: - logger.debug(f"Process {worker.name} is already terminated.") + logger.debug("Process %s is already terminated.", worker.name) # Waiting worker shutdown. worker.join() event: EventType = Event() @@ -88,7 +88,11 @@ def handle( daemon=False, ) new_process.start() - logger.info(f"Process {new_process.name} restarted with pid {new_process.pid}") + logger.info( + "Process %s restarted with pid %s", + new_process.name, + new_process.pid, + ) workers[self.worker_num] = new_process _wait_for_worker_startup(new_process, event) @@ -139,7 +143,7 @@ def _signal_handler(signum: int, _frame: Any) -> None: if current_process().name.startswith("worker"): raise KeyboardInterrupt - logger.debug(f"Got signal {signum}.") + logger.debug("Got signal %s.", signum) action_queue.put(action_to_send) logger.info("Workers are scheduled for shutdown.") @@ -167,7 +171,7 @@ def __init__( if args.reload and observer is not None: watch_paths = args.reload_dirs if args.reload_dirs else ["."] for path_to_watch in watch_paths: - logger.debug(f"Watching directory: {path_to_watch}") + logger.debug("Watching directory: %s", path_to_watch) observer.schedule( FileWatcher( callback=schedule_workers_reload, @@ -267,7 +271,7 @@ def start(self) -> int | None: # noqa: C901 # We bulk_process all pending events. while not self.action_queue.empty(): action = self.action_queue.get() - logging.debug(f"Got event: {action}") + logging.debug("Got event: %s", action) if isinstance(action, ReloadAllAction): action.handle( workers_num=len(self.workers), @@ -295,7 +299,7 @@ def start(self) -> int | None: # noqa: C901 for worker_num, worker in enumerate(self.workers): if not worker.is_alive(): - logger.info(f"{worker.name} is dead. Scheduling reload.") + logger.info("%s is dead. Scheduling reload.", worker.name) self.action_queue.put( ReloadOneAction( worker_num=worker_num, diff --git a/taskiq/cli/worker/run.py b/taskiq/cli/worker/run.py index 24d8f8db..a9350dc3 100644 --- a/taskiq/cli/worker/run.py +++ b/taskiq/cli/worker/run.py @@ -103,7 +103,7 @@ def interrupt_handler(signum: int, _frame: Any) -> None: :param _frame: current execution frame. :raises KeyboardInterrupt: if termination hasn't begun. """ - logger.debug(f"Got signal {signum}.") + logger.debug("Got signal %s.", signum) nonlocal shutdown_event nonlocal hardkill_counter # Soft kill is a signal to start shutdown. diff --git a/taskiq/kicker.py b/taskiq/kicker.py index 356a3de5..305ec9d2 100644 --- a/taskiq/kicker.py +++ b/taskiq/kicker.py @@ -154,7 +154,10 @@ async def kiq( :returns: taskiq task. """ logger.debug( - f"Kicking {self.task_name} with args={args} and kwargs={kwargs}.", + "Kicking %s with args=%s and kwargs=%s.", + self.task_name, + args, + kwargs, ) message = self._prepare_message(*args, **kwargs) for middleware in self.broker.middlewares: diff --git a/taskiq/middlewares/prometheus_middleware.py b/taskiq/middlewares/prometheus_middleware.py index 56837cf3..a7713d3e 100644 --- a/taskiq/middlewares/prometheus_middleware.py +++ b/taskiq/middlewares/prometheus_middleware.py @@ -36,7 +36,7 @@ def __init__( if not metrics_path.exists(): metrics_path.mkdir(parents=True) - logger.debug(f"Setting up multiproc dir to {metrics_path}") + logger.debug("Setting up multiproc dir to %s", metrics_path) os.environ["PROMETHEUS_MULTIPROC_DIR"] = str(metrics_path) diff --git a/taskiq/receiver/receiver.py b/taskiq/receiver/receiver.py index 1257e9b1..6a297d56 100644 --- a/taskiq/receiver/receiver.py +++ b/taskiq/receiver/receiver.py @@ -170,7 +170,7 @@ async def callback( # noqa: C901, PLR0912 exc_info=True, ) return - logger.debug(f"Received message: {taskiq_msg}") + logger.debug("Received message: %s", taskiq_msg) task = self.broker.find_task(taskiq_msg.task_name) if task is None: logger.warning( @@ -222,11 +222,7 @@ async def callback( # noqa: C901, PLR0912 await maybe_awaitable(middleware.post_save(taskiq_msg, result)) except Exception as exc: - logger.exception( - "Can't set result in result backend. Cause: %s", - exc, - exc_info=True, - ) + logger.exception("Can't set result in result backend.") if raise_err: raise exc @@ -373,11 +369,7 @@ async def run_task( # noqa: C901, PLR0912, PLR0915 ) except BaseException as exc: found_exception = exc - logger.error( - "Exception found while executing function: %s", - exc, - exc_info=True, - ) + logger.exception("Exception found while executing function.") # Stop the timer. execution_time = time() - start_time if dep_ctx: @@ -668,7 +660,8 @@ async def runner( # asyncio.wait will throw an error if there is nothing to wait for if tasks: logger.info( - f"Waiting for {len(tasks)} running tasks to complete...", + "Waiting for %d running tasks to complete...", + len(tasks), ) await asyncio.wait(tasks, timeout=self.wait_tasks_timeout) logger.info("No more tasks to wait for. Shutting down.") diff --git a/taskiq/schedule_sources/label_based.py b/taskiq/schedule_sources/label_based.py index 49984fce..663e1db0 100644 --- a/taskiq/schedule_sources/label_based.py +++ b/taskiq/schedule_sources/label_based.py @@ -37,8 +37,10 @@ async def startup(self) -> None: if task.broker != self.broker: # if task broker doesn't match self, something is probably wrong logger.warning( - f"Broker for {task_name} `{task.broker}` doesn't " - f"match scheduler's broker `{self.broker}`", + "Broker for %s `%s` doesn't match scheduler's broker `%s`", + task_name, + task.broker, + self.broker, ) continue for schedule in task.labels.get("schedule", []): diff --git a/uv.lock b/uv.lock index 6c81b4c9..7b60db6c 100644 --- a/uv.lock +++ b/uv.lock @@ -304,7 +304,7 @@ name = "cffi" version = "2.0.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pycparser", marker = "implementation_name != 'PyPy'" }, + { name = "pycparser" }, ] sdist = { url = "https://files.pythonhosted.org/packages/eb/56/b1ba7935a17738ae8453301356628e8147c79dbb825bcbc73dc7401f9846/cffi-2.0.0.tar.gz", hash = "sha256:44d1b5909021139fe36001ae048dbdde8214afa20200eda0f64c068cac5d5529", size = 523588, upload-time = "2025-09-08T23:24:04.541Z" } wheels = [ @@ -538,7 +538,7 @@ name = "exceptiongroup" version = "1.3.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "typing-extensions", marker = "python_full_version < '3.13'" }, + { name = "typing-extensions" }, ] sdist = { url = "https://files.pythonhosted.org/packages/0b/9f/a65090624ecf468cdca03533906e7c69ed7588582240cfe7cc9e770b50eb/exceptiongroup-1.3.0.tar.gz", hash = "sha256:b241f5885f560bc56a59ee63ca4c6a8bfa46ae4ad651af316d4e81817bb9fd88", size = 29749, upload-time = "2025-05-10T17:42:51.123Z" } wheels = [ @@ -1762,28 +1762,27 @@ wheels = [ [[package]] name = "ruff" -version = "0.14.5" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/82/fa/fbb67a5780ae0f704876cb8ac92d6d76da41da4dc72b7ed3565ab18f2f52/ruff-0.14.5.tar.gz", hash = "sha256:8d3b48d7d8aad423d3137af7ab6c8b1e38e4de104800f0d596990f6ada1a9fc1", size = 5615944, upload-time = "2025-11-13T19:58:51.155Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/68/31/c07e9c535248d10836a94e4f4e8c5a31a1beed6f169b31405b227872d4f4/ruff-0.14.5-py3-none-linux_armv6l.whl", hash = "sha256:f3b8248123b586de44a8018bcc9fefe31d23dda57a34e6f0e1e53bd51fd63594", size = 13171630, upload-time = "2025-11-13T19:57:54.894Z" }, - { url = "https://files.pythonhosted.org/packages/8e/5c/283c62516dca697cd604c2796d1487396b7a436b2f0ecc3fd412aca470e0/ruff-0.14.5-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:f7a75236570318c7a30edd7f5491945f0169de738d945ca8784500b517163a72", size = 13413925, upload-time = "2025-11-13T19:57:59.181Z" }, - { url = "https://files.pythonhosted.org/packages/b6/f3/aa319f4afc22cb6fcba2b9cdfc0f03bbf747e59ab7a8c5e90173857a1361/ruff-0.14.5-py3-none-macosx_11_0_arm64.whl", hash = "sha256:6d146132d1ee115f8802356a2dc9a634dbf58184c51bff21f313e8cd1c74899a", size = 12574040, upload-time = "2025-11-13T19:58:02.056Z" }, - { url = "https://files.pythonhosted.org/packages/f9/7f/cb5845fcc7c7e88ed57f58670189fc2ff517fe2134c3821e77e29fd3b0c8/ruff-0.14.5-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e2380596653dcd20b057794d55681571a257a42327da8894b93bbd6111aa801f", size = 13009755, upload-time = "2025-11-13T19:58:05.172Z" }, - { url = "https://files.pythonhosted.org/packages/21/d2/bcbedbb6bcb9253085981730687ddc0cc7b2e18e8dc13cf4453de905d7a0/ruff-0.14.5-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2d1fa985a42b1f075a098fa1ab9d472b712bdb17ad87a8ec86e45e7fa6273e68", size = 12937641, upload-time = "2025-11-13T19:58:08.345Z" }, - { url = "https://files.pythonhosted.org/packages/a4/58/e25de28a572bdd60ffc6bb71fc7fd25a94ec6a076942e372437649cbb02a/ruff-0.14.5-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:88f0770d42b7fa02bbefddde15d235ca3aa24e2f0137388cc15b2dcbb1f7c7a7", size = 13610854, upload-time = "2025-11-13T19:58:11.419Z" }, - { url = "https://files.pythonhosted.org/packages/7d/24/43bb3fd23ecee9861970978ea1a7a63e12a204d319248a7e8af539984280/ruff-0.14.5-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:3676cb02b9061fee7294661071c4709fa21419ea9176087cb77e64410926eb78", size = 15061088, upload-time = "2025-11-13T19:58:14.551Z" }, - { url = "https://files.pythonhosted.org/packages/23/44/a022f288d61c2f8c8645b24c364b719aee293ffc7d633a2ca4d116b9c716/ruff-0.14.5-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b595bedf6bc9cab647c4a173a61acf4f1ac5f2b545203ba82f30fcb10b0318fb", size = 14734717, upload-time = "2025-11-13T19:58:17.518Z" }, - { url = "https://files.pythonhosted.org/packages/58/81/5c6ba44de7e44c91f68073e0658109d8373b0590940efe5bd7753a2585a3/ruff-0.14.5-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f55382725ad0bdb2e8ee2babcbbfb16f124f5a59496a2f6a46f1d9d99d93e6e2", size = 14028812, upload-time = "2025-11-13T19:58:20.533Z" }, - { url = "https://files.pythonhosted.org/packages/ad/ef/41a8b60f8462cb320f68615b00299ebb12660097c952c600c762078420f8/ruff-0.14.5-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7497d19dce23976bdaca24345ae131a1d38dcfe1b0850ad8e9e6e4fa321a6e19", size = 13825656, upload-time = "2025-11-13T19:58:23.345Z" }, - { url = "https://files.pythonhosted.org/packages/7c/00/207e5de737fdb59b39eb1fac806904fe05681981b46d6a6db9468501062e/ruff-0.14.5-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:410e781f1122d6be4f446981dd479470af86537fb0b8857f27a6e872f65a38e4", size = 13959922, upload-time = "2025-11-13T19:58:26.537Z" }, - { url = "https://files.pythonhosted.org/packages/bc/7e/fa1f5c2776db4be405040293618846a2dece5c70b050874c2d1f10f24776/ruff-0.14.5-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:c01be527ef4c91a6d55e53b337bfe2c0f82af024cc1a33c44792d6844e2331e1", size = 12932501, upload-time = "2025-11-13T19:58:29.822Z" }, - { url = "https://files.pythonhosted.org/packages/67/d8/d86bf784d693a764b59479a6bbdc9515ae42c340a5dc5ab1dabef847bfaa/ruff-0.14.5-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:f66e9bb762e68d66e48550b59c74314168ebb46199886c5c5aa0b0fbcc81b151", size = 12927319, upload-time = "2025-11-13T19:58:32.923Z" }, - { url = "https://files.pythonhosted.org/packages/ac/de/ee0b304d450ae007ce0cb3e455fe24fbcaaedae4ebaad6c23831c6663651/ruff-0.14.5-py3-none-musllinux_1_2_i686.whl", hash = "sha256:d93be8f1fa01022337f1f8f3bcaa7ffee2d0b03f00922c45c2207954f351f465", size = 13206209, upload-time = "2025-11-13T19:58:35.952Z" }, - { url = "https://files.pythonhosted.org/packages/33/aa/193ca7e3a92d74f17d9d5771a765965d2cf42c86e6f0fd95b13969115723/ruff-0.14.5-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:c135d4b681f7401fe0e7312017e41aba9b3160861105726b76cfa14bc25aa367", size = 13953709, upload-time = "2025-11-13T19:58:39.002Z" }, - { url = "https://files.pythonhosted.org/packages/cc/f1/7119e42aa1d3bf036ffc9478885c2e248812b7de9abea4eae89163d2929d/ruff-0.14.5-py3-none-win32.whl", hash = "sha256:c83642e6fccfb6dea8b785eb9f456800dcd6a63f362238af5fc0c83d027dd08b", size = 12925808, upload-time = "2025-11-13T19:58:42.779Z" }, - { url = "https://files.pythonhosted.org/packages/3b/9d/7c0a255d21e0912114784e4a96bf62af0618e2190cae468cd82b13625ad2/ruff-0.14.5-py3-none-win_amd64.whl", hash = "sha256:9d55d7af7166f143c94eae1db3312f9ea8f95a4defef1979ed516dbb38c27621", size = 14331546, upload-time = "2025-11-13T19:58:45.691Z" }, - { url = "https://files.pythonhosted.org/packages/e5/80/69756670caedcf3b9be597a6e12276a6cf6197076eb62aad0c608f8efce0/ruff-0.14.5-py3-none-win_arm64.whl", hash = "sha256:4b700459d4649e2594b31f20a9de33bc7c19976d4746d8d0798ad959621d64a4", size = 13433331, upload-time = "2025-11-13T19:58:48.434Z" }, +version = "0.16.5" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f3/85/c8e12473c93018f92d19dd988a294202e1c27426c47ec4de53ffb847b8d8/ruff-0.16.5.tar.gz", hash = "sha256:1b88500f9ffbcab3dedb0082c9f9492e91ec3d618aac1236a3e0189938f7040b", size = 4912003, upload-time = "2026-08-27T16:34:18.258Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c6/b6/77c90a970fe2dae17a723acbd011043ea97c98d7deacccefdc4ba74ec512/ruff-0.16.5-py3-none-linux_armv6l.whl", hash = "sha256:12e5f673e774c35fbb62f288809c7653b73445f8ecec6b6063fd6ea3521aa14b", size = 10011941, upload-time = "2026-08-27T16:33:41.287Z" }, + { url = "https://files.pythonhosted.org/packages/4b/46/6cf67cf6411885a1d6f7f6d801682f155536a85176d10b605e2ceffed8bd/ruff-0.16.5-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:eda58a5802de40e7ed5b32b64e0b32539338cc6fcd2c78f61e3ad6a0d79f51c3", size = 10204049, upload-time = "2026-08-27T16:33:44.056Z" }, + { url = "https://files.pythonhosted.org/packages/46/fd/c8720ca7a090abf0c2fef4abe8a5ef6e5127ed15196d8886ff75a2b370e2/ruff-0.16.5-py3-none-macosx_11_0_arm64.whl", hash = "sha256:c5ae9a7b9a8875131f40f8fe967cc86abf899779efd663cb7ce3d572d01da7eb", size = 9809037, upload-time = "2026-08-27T16:33:46.257Z" }, + { url = "https://files.pythonhosted.org/packages/43/45/a684caacdedaca180f52bacccc40bf0789d2c5a7c75f25324853e9eaedb5/ruff-0.16.5-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7b719b0a1f4d59710d283ab2965f621684a108a9e41da622e3b23f0326cd0025", size = 9964129, upload-time = "2026-08-27T16:33:48.352Z" }, + { url = "https://files.pythonhosted.org/packages/9e/f2/5d2bcdaca6b5b93d1b4dfc166cd2aebf7680143a1b38a28759df13a94d31/ruff-0.16.5-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2298f2780ed1be0c5cb1361e32ab7b1467f3cce7dabe101d2210a314f2fe42e9", size = 9821518, upload-time = "2026-08-27T16:33:50.57Z" }, + { url = "https://files.pythonhosted.org/packages/aa/ff/011cce29accf9257d5974145b733fc653a37985ed6825413a3987cefbfe0/ruff-0.16.5-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:258f29035a2dd021e7861e631b227a5b3f14e50c1184c9a6a122c5f4576154d7", size = 10534835, upload-time = "2026-08-27T16:33:52.522Z" }, + { url = "https://files.pythonhosted.org/packages/d7/5a/f0cf109bada9bba0e96c90c21c9f9251803f57225c32d293327a03c710d6/ruff-0.16.5-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b9a4f0432966834019c74d1b7e5c51224305d7713f3d7faf3e7451f1a3be3cde", size = 11252550, upload-time = "2026-08-27T16:33:54.521Z" }, + { url = "https://files.pythonhosted.org/packages/63/4d/1d481aaea2046c6a7ed7c291f9004c669cce3c087b6b376ed5b08271e3fe/ruff-0.16.5-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b5eb3a8c3d0ade9cea42b591fd530368e8798380e30e0a308b85a5cf718f09ea", size = 10777949, upload-time = "2026-08-27T16:33:56.88Z" }, + { url = "https://files.pythonhosted.org/packages/ee/34/ee245ca55f64443233034b3d02b03236b19242004281247c079390b7facd/ruff-0.16.5-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ef0f69e191a13a3c9816f63163c88790cb12cd157bbbb384e9c44745702ab105", size = 10311656, upload-time = "2026-08-27T16:33:59.12Z" }, + { url = "https://files.pythonhosted.org/packages/a7/4d/c33a333e341c0a2b96c715b52d89a606f5a34cd4ac493cd9b8d0187186b8/ruff-0.16.5-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:0eeab41fbea2c42f98dfb9822cdccda9d24ba38d49f6dc945b5c236d48f0ef29", size = 10532125, upload-time = "2026-08-27T16:34:01.166Z" }, + { url = "https://files.pythonhosted.org/packages/30/e1/a64cef78b40192497bb98a27a8aa8f2c98ee9ee15bc97f7712d94ef32937/ruff-0.16.5-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:f0768e9df4300713fff30733c87575f68b6f1d8de41184e505b7fdd9c0c95eaf", size = 10097648, upload-time = "2026-08-27T16:34:03.16Z" }, + { url = "https://files.pythonhosted.org/packages/cc/4e/4cdc9ed3c3e109d2f71e62572a37457298d7bc7501ec3138babb7ed32bbd/ruff-0.16.5-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:95cc70cdc7aa80c338de356279d2adbeb2de0f520b9ecd8aba75b94e95e02f91", size = 9829344, upload-time = "2026-08-27T16:34:05.134Z" }, + { url = "https://files.pythonhosted.org/packages/39/4a/31ed35ce31729955fc583ee0d176d6e784c1290cb0b0a75cb2134c1ab72a/ruff-0.16.5-py3-none-musllinux_1_2_i686.whl", hash = "sha256:d185c8398ded1bfd91c0c2cb258346307571eccc473a8490af8c3977399c384a", size = 10277117, upload-time = "2026-08-27T16:34:07.425Z" }, + { url = "https://files.pythonhosted.org/packages/a8/a0/60356d86687b4b666d593df213f4dc3041750d024cb7bf2cfa81cfd65c2e/ruff-0.16.5-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:fb8e3a3c4c6a784150a7ced53b015f4b253fc2bf97a610886419ead64b4756ef", size = 10711653, upload-time = "2026-08-27T16:34:09.712Z" }, + { url = "https://files.pythonhosted.org/packages/ed/20/656d67f5b25ca9bda4e02b1de25867b2954e1d19e03648060f167ad0f4cc/ruff-0.16.5-py3-none-win32.whl", hash = "sha256:288b0a5f080492fe5635db849f9e2e84aa3cce7b7f0e955997d416c507c76a26", size = 10034250, upload-time = "2026-08-27T16:34:11.8Z" }, + { url = "https://files.pythonhosted.org/packages/5b/42/ee8e68a207b9127fcde6c3d7e197def432f346cb1af159e1fa14ca0d1cdc/ruff-0.16.5-py3-none-win_amd64.whl", hash = "sha256:ddc6385fb2137f616357ca03d6c74f4be987f80fed4008566b754f6032b8546f", size = 10516714, upload-time = "2026-08-27T16:34:13.963Z" }, + { url = "https://files.pythonhosted.org/packages/73/e3/7df5a396e445b9ba49ce9a9437439a4d80042c61c0ade199abf8d16de1ac/ruff-0.16.5-py3-none-win_arm64.whl", hash = "sha256:a64abe90968719b851bb7cedffaa8753fbdbdadab483089682db623f3edc587e", size = 10391564, upload-time = "2026-08-27T16:34:16.064Z" }, ] [[package]] @@ -1901,7 +1900,7 @@ dev = [ { name = "pytest", specifier = ">=9.0.1" }, { name = "pytest-cov", specifier = ">=7.0.0" }, { name = "pytest-xdist", extras = ["psutil"], specifier = ">=3.8.0" }, - { name = "ruff", specifier = ">=0.14.5" }, + { name = "ruff", specifier = ">=0.16.5" }, { name = "tox", specifier = ">=4.32.0" }, { name = "tox-uv", specifier = ">=1.29.0" }, { name = "tzdata", marker = "sys_platform == 'win32'", specifier = ">=2025.2" },