From 49e83954c5f140b65d616f79b0607f7bf73acc9f Mon Sep 17 00:00:00 2001 From: Qubasa Date: Tue, 8 Jul 2025 12:46:44 +0700 Subject: [PATCH] clan-cli: Fix regression in ruff linter, where linter rules got overriden by local pyproject.toml clan-app: Fix ruff regression where linter rules got overriden by local pyproject.toml --- pkgs/clan-app/clan-app.code-workspace | 3 +++ pkgs/clan-app/clan_app/__init__.py | 4 ++-- pkgs/clan-app/clan_app/api/file_gtk.py | 6 ++---- pkgs/clan-app/pyproject.toml | 1 - pkgs/clan-cli/clan_cli/__init__.py | 2 +- pkgs/clan-cli/clan_cli/flash/automount.py | 2 +- pkgs/clan-cli/clan_cli/templates/__init__.py | 1 + .../clan-cli/clan_cli/tests/test_clan_nix_attrset.py | 3 +-- pkgs/clan-cli/clan_cli/vars/check.py | 4 ++-- pkgs/clan-cli/clan_cli/vars/generate.py | 9 ++++++--- .../clan_cli/vars/secret_modules/password_store.py | 9 ++++----- pkgs/clan-cli/clan_cli/vms/qemu.py | 4 ++-- pkgs/clan-cli/clan_lib/api/__init__.py | 4 ++-- pkgs/clan-cli/clan_lib/api/serde.py | 9 +++------ pkgs/clan-cli/clan_lib/api/serde_deserialize_test.py | 2 +- pkgs/clan-cli/clan_lib/async_run/__init__.py | 12 ++++++------ pkgs/clan-cli/clan_lib/flake/flake.py | 2 +- pkgs/clan-cli/clan_lib/machines/delete.py | 2 +- pkgs/clan-cli/clan_lib/nix_models/clan.py | 3 --- pkgs/clan-cli/clan_lib/ssh/remote_test.py | 2 +- pkgs/clan-cli/clan_lib/tests/test_create.py | 2 +- pkgs/clan-cli/docs.py | 2 +- pkgs/clan-cli/pyproject.toml | 5 +---- 23 files changed, 43 insertions(+), 50 deletions(-) diff --git a/pkgs/clan-app/clan-app.code-workspace b/pkgs/clan-app/clan-app.code-workspace index 96aacafba..75aed69ac 100644 --- a/pkgs/clan-app/clan-app.code-workspace +++ b/pkgs/clan-app/clan-app.code-workspace @@ -23,6 +23,9 @@ }, { "path": "../clan-cli/clan_lib" + }, + { + "path": "ui-2d" } ], "settings": { diff --git a/pkgs/clan-app/clan_app/__init__.py b/pkgs/clan-app/clan_app/__init__.py index 47125c580..8945d37c2 100644 --- a/pkgs/clan-app/clan_app/__init__.py +++ b/pkgs/clan-app/clan_app/__init__.py @@ -4,10 +4,10 @@ import sys from clan_cli.profiler import profile -log = logging.getLogger(__name__) - from clan_app.app import ClanAppOptions, app_run +log = logging.getLogger(__name__) + @profile def main(argv: list[str] = sys.argv) -> int: diff --git a/pkgs/clan-app/clan_app/api/file_gtk.py b/pkgs/clan-app/clan_app/api/file_gtk.py index d3deef616..b7a9ea983 100644 --- a/pkgs/clan-app/clan_app/api/file_gtk.py +++ b/pkgs/clan-app/clan_app/api/file_gtk.py @@ -1,16 +1,14 @@ -import gi - -gi.require_version("Gtk", "4.0") - import logging import time from pathlib import Path from typing import Any +import gi from clan_lib.api import ApiError, ErrorDataClass, SuccessDataClass from clan_lib.api.directory import FileRequest from gi.repository import Gio, GLib, Gtk +gi.require_version("Gtk", "4.0") log = logging.getLogger(__name__) diff --git a/pkgs/clan-app/pyproject.toml b/pkgs/clan-app/pyproject.toml index 25147331f..a0034fb6e 100644 --- a/pkgs/clan-app/pyproject.toml +++ b/pkgs/clan-app/pyproject.toml @@ -35,4 +35,3 @@ warn_redundant_casts = true disallow_untyped_calls = true disallow_untyped_defs = true no_implicit_optional = true - diff --git a/pkgs/clan-cli/clan_cli/__init__.py b/pkgs/clan-cli/clan_cli/__init__.py index b45d2c37e..d163ca33a 100644 --- a/pkgs/clan-cli/clan_cli/__init__.py +++ b/pkgs/clan-cli/clan_cli/__init__.py @@ -15,8 +15,8 @@ from . import ( clan, secrets, select, - templates, state, + templates, vms, ) from .arg_actions import AppendOptionAction diff --git a/pkgs/clan-cli/clan_cli/flash/automount.py b/pkgs/clan-cli/clan_cli/flash/automount.py index 9b1f10ab3..953f9123f 100644 --- a/pkgs/clan-cli/clan_cli/flash/automount.py +++ b/pkgs/clan-cli/clan_cli/flash/automount.py @@ -14,7 +14,7 @@ log = logging.getLogger(__name__) @contextmanager def pause_automounting( devices: list[Path], machine: Machine, request_graphical: bool = False -) -> Generator[None, None, None]: +) -> Generator[None]: """ Pause automounting on the device for the duration of this context manager diff --git a/pkgs/clan-cli/clan_cli/templates/__init__.py b/pkgs/clan-cli/clan_cli/templates/__init__.py index 5e052f111..1696b625f 100644 --- a/pkgs/clan-cli/clan_cli/templates/__init__.py +++ b/pkgs/clan-cli/clan_cli/templates/__init__.py @@ -1,5 +1,6 @@ # !/usr/bin/env python3 import argparse + from .list import register_list_parser diff --git a/pkgs/clan-cli/clan_cli/tests/test_clan_nix_attrset.py b/pkgs/clan-cli/clan_cli/tests/test_clan_nix_attrset.py index 458185d7e..6994f7681 100644 --- a/pkgs/clan-cli/clan_cli/tests/test_clan_nix_attrset.py +++ b/pkgs/clan-cli/clan_cli/tests/test_clan_nix_attrset.py @@ -1,11 +1,10 @@ -import pytest from pathlib import Path +import pytest from clan_cli.tests.fixtures_flakes import FlakeForTest from clan_lib.cmd import run from clan_lib.flake import Flake from clan_lib.nix import nix_command - from clan_lib.templates import list_templates from clan_lib.templates.filesystem import copy_from_nixstore diff --git a/pkgs/clan-cli/clan_cli/vars/check.py b/pkgs/clan-cli/clan_cli/vars/check.py index 0c3fe484b..9da277db9 100644 --- a/pkgs/clan-cli/clan_cli/vars/check.py +++ b/pkgs/clan-cli/clan_cli/vars/check.py @@ -1,11 +1,11 @@ import argparse import logging +from typing import TYPE_CHECKING from clan_cli.completions import add_dynamic_completer, complete_machines from clan_lib.errors import ClanError -from clan_lib.machines.machines import Machine from clan_lib.flake import Flake -from typing import TYPE_CHECKING +from clan_lib.machines.machines import Machine if TYPE_CHECKING: from .generate import Var diff --git a/pkgs/clan-cli/clan_cli/vars/generate.py b/pkgs/clan-cli/clan_cli/vars/generate.py index 85c98ff56..4b9e701c1 100644 --- a/pkgs/clan-cli/clan_cli/vars/generate.py +++ b/pkgs/clan-cli/clan_cli/vars/generate.py @@ -54,7 +54,8 @@ class Generator: @cached_property def exists(self) -> bool: - assert self.machine is not None and self._flake is not None + assert self.machine is not None + assert self._flake is not None return check_vars(self.machine, self._flake, generator_name=self.name) @classmethod @@ -116,7 +117,8 @@ class Generator: return generators def final_script(self) -> Path: - assert self.machine is not None and self._flake is not None + assert self.machine is not None + assert self._flake is not None from clan_lib.machines.machines import Machine from clan_lib.nix import nix_test_store @@ -131,7 +133,8 @@ class Generator: return output def validation(self) -> str | None: - assert self.machine is not None and self._flake is not None + assert self.machine is not None + assert self._flake is not None from clan_lib.machines.machines import Machine machine = Machine(name=self.machine, flake=self._flake) diff --git a/pkgs/clan-cli/clan_cli/vars/secret_modules/password_store.py b/pkgs/clan-cli/clan_cli/vars/secret_modules/password_store.py index 86f0e706c..3512e5ec3 100644 --- a/pkgs/clan-cli/clan_cli/vars/secret_modules/password_store.py +++ b/pkgs/clan-cli/clan_cli/vars/secret_modules/password_store.py @@ -1,7 +1,7 @@ import io import logging -import tarfile import subprocess +import tarfile from collections.abc import Iterable from pathlib import Path from tempfile import TemporaryDirectory @@ -79,7 +79,7 @@ class SecretStore(StoreBase): return Path(self.entry_prefix) / self.rel_dir(generator, name) def _run_pass( - self, *args: str, input: bytes | None = None, check: bool = True + self, *args: str, input: bytes | None = None, check: bool = True # noqa: A002 ) -> subprocess.CompletedProcess[bytes]: cmd = [self._pass_command, *args] # We need bytes support here, so we can not use clan cmd. @@ -88,8 +88,7 @@ class SecretStore(StoreBase): return subprocess.run( cmd, input=input, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, + capture_output=True, check=check, ) @@ -152,7 +151,7 @@ class SecretStore(StoreBase): if not local_hash: return True - from clan_lib.cmd import RunOpts, Log + from clan_lib.cmd import Log, RunOpts remote_hash = host.run( [ diff --git a/pkgs/clan-cli/clan_cli/vms/qemu.py b/pkgs/clan-cli/clan_cli/vms/qemu.py index 3113d644e..bb4c6b977 100644 --- a/pkgs/clan-cli/clan_cli/vms/qemu.py +++ b/pkgs/clan-cli/clan_cli/vms/qemu.py @@ -139,7 +139,7 @@ def qemu_command( "-chardev", f"socket,path={qga_socket_file},server=on,wait=off,id=qga0", "-device", "virtio-serial", "-device", "virtserialport,chardev=qga0,name=org.qemu.guest_agent.0", - ] # fmt: on + ] if interactive: command.extend( [ @@ -187,7 +187,7 @@ class QMPWrapper: self._qga_socket: Path = state_dir / "qga.sock" @contextmanager - def qmp_ctx(self) -> Generator[QEMUMonitorProtocol, None, None]: + def qmp_ctx(self) -> Generator[QEMUMonitorProtocol]: rpath = self._qmp_socket.resolve() if not rpath.exists(): msg = f"qmp socket {rpath} does not exist. Is the VM running?" diff --git a/pkgs/clan-cli/clan_lib/api/__init__.py b/pkgs/clan-cli/clan_lib/api/__init__.py index 64a9df0ae..70fe330ea 100644 --- a/pkgs/clan-cli/clan_lib/api/__init__.py +++ b/pkgs/clan-cli/clan_lib/api/__init__.py @@ -9,7 +9,6 @@ from types import ModuleType from typing import ( Annotated, Any, - Generic, Literal, TypeVar, get_type_hints, @@ -17,6 +16,7 @@ from typing import ( from clan_lib.api.util import JSchemaTypeError from clan_lib.errors import ClanError + from .serde import dataclass_to_dict, from_dict, sanitize_string log = logging.getLogger(__name__) @@ -38,7 +38,7 @@ class ApiError: @dataclass -class SuccessDataClass(Generic[ResponseDataType]): +class SuccessDataClass[ResponseDataType]: op_key: str status: Annotated[Literal["success"], "The status of the response."] data: ResponseDataType diff --git a/pkgs/clan-cli/clan_lib/api/serde.py b/pkgs/clan-cli/clan_lib/api/serde.py index f5940e065..795b08d2b 100644 --- a/pkgs/clan-cli/clan_lib/api/serde.py +++ b/pkgs/clan-cli/clan_lib/api/serde.py @@ -156,12 +156,9 @@ def is_type_in_union(union_type: type | UnionType, target_type: type) -> bool: return True # For generic types like dict[str, str], check their origin elif get_origin(arg) is not None: - if get_origin(arg) == target_type: - return True - # Also check if target_type is a generic with same origin - elif get_origin(target_type) is not None and get_origin( + if get_origin(arg) == target_type or (get_origin(target_type) is not None and get_origin( arg - ) == get_origin(target_type): + ) == get_origin(target_type)): return True # For actual classes, use issubclass elif inspect.isclass(arg) and inspect.isclass(target_type): @@ -329,7 +326,7 @@ def construct_value( raise ClanError(msg) -def construct_dataclass( +def construct_dataclass[T: dataclass]( t: type[T], data: dict[str, Any], path: list[str] | None = None ) -> T: """ diff --git a/pkgs/clan-cli/clan_lib/api/serde_deserialize_test.py b/pkgs/clan-cli/clan_lib/api/serde_deserialize_test.py index 817e5a86c..d4d2fc46f 100644 --- a/pkgs/clan-cli/clan_lib/api/serde_deserialize_test.py +++ b/pkgs/clan-cli/clan_lib/api/serde_deserialize_test.py @@ -6,9 +6,9 @@ import pytest # Functions to test from clan_lib.api import dataclass_to_dict, from_dict +from clan_lib.api.serde import is_type_in_union from clan_lib.errors import ClanError from clan_lib.machines import machines -from clan_lib.api.serde import is_type_in_union def test_simple() -> None: diff --git a/pkgs/clan-cli/clan_lib/async_run/__init__.py b/pkgs/clan-cli/clan_lib/async_run/__init__.py index 94f5db70c..8d7f8d728 100644 --- a/pkgs/clan-cli/clan_lib/async_run/__init__.py +++ b/pkgs/clan-cli/clan_lib/async_run/__init__.py @@ -5,7 +5,7 @@ import types import uuid from collections.abc import Callable from dataclasses import dataclass, field -from typing import IO, Any, Generic, ParamSpec, TypeVar +from typing import IO, Any, ParamSpec, TypeVar from clan_lib.errors import ClanError @@ -39,7 +39,7 @@ Q = TypeVar("Q") # Data type for the async_opts.data field @dataclass -class AsyncResult(Generic[R]): +class AsyncResult[R]: _result: R | Exception @property @@ -120,7 +120,7 @@ def set_async_ctx(ctx: AsyncContext) -> None: ASYNC_CTX_THREAD_LOCAL.async_ctx = ctx -class AsyncThread(threading.Thread, Generic[P, R]): +class AsyncThread[**P, R](threading.Thread): function: Callable[P, R] args: tuple[Any, ...] kwargs: dict[str, Any] @@ -169,7 +169,7 @@ class AsyncThread(threading.Thread, Generic[P, R]): @dataclass -class AsyncFuture(Generic[R]): +class AsyncFuture[R]: _tid: str _runtime: "AsyncRuntime" @@ -214,11 +214,11 @@ class AsyncFuture(Generic[R]): @dataclass -class AsyncFutureRef(AsyncFuture[R], Generic[R, Q]): +class AsyncFutureRef[R, Q](AsyncFuture[R]): ref: Q | None -class AsyncOptsRef(AsyncOpts, Generic[Q]): +class AsyncOptsRef[Q](AsyncOpts): ref: Q | None = None diff --git a/pkgs/clan-cli/clan_lib/flake/flake.py b/pkgs/clan-cli/clan_lib/flake/flake.py index 1b4d75e71..332ec436a 100644 --- a/pkgs/clan-cli/clan_lib/flake/flake.py +++ b/pkgs/clan-cli/clan_lib/flake/flake.py @@ -747,7 +747,7 @@ class Flake: ClanError: If the number of outputs does not match the number of selectors. AssertionError: If the cache or flake cache path is not properly initialized. """ - from clan_lib.cmd import run, RunOpts, Log + from clan_lib.cmd import Log, RunOpts, run from clan_lib.dirs import select_source from clan_lib.nix import ( nix_build, diff --git a/pkgs/clan-cli/clan_lib/machines/delete.py b/pkgs/clan-cli/clan_lib/machines/delete.py index 86be5abb6..d0c2beecc 100644 --- a/pkgs/clan-cli/clan_lib/machines/delete.py +++ b/pkgs/clan-cli/clan_lib/machines/delete.py @@ -9,10 +9,10 @@ from clan_cli.secrets.secrets import ( list_secrets, ) -from clan_lib.persist.inventory_store import InventoryStore from clan_lib.api import API from clan_lib.dirs import specific_machine_dir from clan_lib.machines.machines import Machine +from clan_lib.persist.inventory_store import InventoryStore log = logging.getLogger(__name__) diff --git a/pkgs/clan-cli/clan_lib/nix_models/clan.py b/pkgs/clan-cli/clan_lib/nix_models/clan.py index b8f0f282f..55278eb4e 100644 --- a/pkgs/clan-cli/clan_lib/nix_models/clan.py +++ b/pkgs/clan-cli/clan_lib/nix_models/clan.py @@ -1,9 +1,6 @@ # DO NOT EDIT THIS FILE MANUALLY. IT IS GENERATED. # This file was generated by running `pkgs/clan-cli/clan_lib.inventory/update.sh` # -# ruff: noqa: N815 -# ruff: noqa: N806 -# ruff: noqa: F401 # fmt: off from typing import Any, Literal, NotRequired, TypedDict diff --git a/pkgs/clan-cli/clan_lib/ssh/remote_test.py b/pkgs/clan-cli/clan_lib/ssh/remote_test.py index 6d8a094b7..e3fdd71f1 100644 --- a/pkgs/clan-cli/clan_lib/ssh/remote_test.py +++ b/pkgs/clan-cli/clan_lib/ssh/remote_test.py @@ -103,7 +103,7 @@ def test_parse_deployment_address( else: @contextlib.contextmanager - def noop() -> Generator[None, Any, None]: + def noop() -> Generator[None, Any]: yield maybe_check_exception = noop() # type: ignore diff --git a/pkgs/clan-cli/clan_lib/tests/test_create.py b/pkgs/clan-cli/clan_lib/tests/test_create.py index 7a0a23311..fea9f3b95 100644 --- a/pkgs/clan-cli/clan_lib/tests/test_create.py +++ b/pkgs/clan-cli/clan_lib/tests/test_create.py @@ -22,7 +22,6 @@ from clan_lib.cmd import RunOpts, run from clan_lib.dirs import specific_machine_dir from clan_lib.errors import ClanError from clan_lib.flake import Flake -from clan_lib.persist.inventory_store import InventoryStore from clan_lib.machines.machines import Machine from clan_lib.nix import nix_command from clan_lib.nix_models.clan import ( @@ -32,6 +31,7 @@ from clan_lib.nix_models.clan import ( Unknown, ) from clan_lib.nix_models.clan import InventoryMachineDeploy as MachineDeploy +from clan_lib.persist.inventory_store import InventoryStore from clan_lib.persist.util import set_value_by_path from clan_lib.ssh.remote import Remote, check_machine_ssh_login diff --git a/pkgs/clan-cli/docs.py b/pkgs/clan-cli/docs.py index abd6aeadc..5df120e16 100644 --- a/pkgs/clan-cli/docs.py +++ b/pkgs/clan-cli/docs.py @@ -1,6 +1,6 @@ import argparse -import sys import re +import sys from dataclasses import dataclass from pathlib import Path diff --git a/pkgs/clan-cli/pyproject.toml b/pkgs/clan-cli/pyproject.toml index c203368e0..72496bda6 100644 --- a/pkgs/clan-cli/pyproject.toml +++ b/pkgs/clan-cli/pyproject.toml @@ -54,7 +54,4 @@ warn_redundant_casts = true disallow_untyped_calls = true disallow_untyped_defs = true no_implicit_optional = true -exclude = "clan_lib.nixpkgs" - -[tool.ruff] -target-version = "py313" \ No newline at end of file +exclude = "clan_lib.nixpkgs" \ No newline at end of file