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
This commit is contained in:
Qubasa
2025-07-08 12:46:44 +07:00
parent de664fbf17
commit f854c39292
23 changed files with 43 additions and 50 deletions

View File

@@ -23,6 +23,9 @@
}, },
{ {
"path": "../clan-cli/clan_lib" "path": "../clan-cli/clan_lib"
},
{
"path": "ui-2d"
} }
], ],
"settings": { "settings": {

View File

@@ -4,10 +4,10 @@ import sys
from clan_cli.profiler import profile from clan_cli.profiler import profile
log = logging.getLogger(__name__)
from clan_app.app import ClanAppOptions, app_run from clan_app.app import ClanAppOptions, app_run
log = logging.getLogger(__name__)
@profile @profile
def main(argv: list[str] = sys.argv) -> int: def main(argv: list[str] = sys.argv) -> int:

View File

@@ -1,16 +1,14 @@
import gi
gi.require_version("Gtk", "4.0")
import logging import logging
import time import time
from pathlib import Path from pathlib import Path
from typing import Any from typing import Any
import gi
from clan_lib.api import ApiError, ErrorDataClass, SuccessDataClass from clan_lib.api import ApiError, ErrorDataClass, SuccessDataClass
from clan_lib.api.directory import FileRequest from clan_lib.api.directory import FileRequest
from gi.repository import Gio, GLib, Gtk from gi.repository import Gio, GLib, Gtk
gi.require_version("Gtk", "4.0")
log = logging.getLogger(__name__) log = logging.getLogger(__name__)

View File

@@ -35,4 +35,3 @@ warn_redundant_casts = true
disallow_untyped_calls = true disallow_untyped_calls = true
disallow_untyped_defs = true disallow_untyped_defs = true
no_implicit_optional = true no_implicit_optional = true

View File

@@ -15,8 +15,8 @@ from . import (
clan, clan,
secrets, secrets,
select, select,
templates,
state, state,
templates,
vms, vms,
) )
from .arg_actions import AppendOptionAction from .arg_actions import AppendOptionAction

View File

@@ -14,7 +14,7 @@ log = logging.getLogger(__name__)
@contextmanager @contextmanager
def pause_automounting( def pause_automounting(
devices: list[Path], machine: Machine, request_graphical: bool = False 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 Pause automounting on the device for the duration of this context
manager manager

View File

@@ -1,5 +1,6 @@
# !/usr/bin/env python3 # !/usr/bin/env python3
import argparse import argparse
from .list import register_list_parser from .list import register_list_parser

View File

@@ -1,11 +1,10 @@
import pytest
from pathlib import Path from pathlib import Path
import pytest
from clan_cli.tests.fixtures_flakes import FlakeForTest from clan_cli.tests.fixtures_flakes import FlakeForTest
from clan_lib.cmd import run from clan_lib.cmd import run
from clan_lib.flake import Flake from clan_lib.flake import Flake
from clan_lib.nix import nix_command from clan_lib.nix import nix_command
from clan_lib.templates import list_templates from clan_lib.templates import list_templates
from clan_lib.templates.filesystem import copy_from_nixstore from clan_lib.templates.filesystem import copy_from_nixstore

View File

@@ -1,11 +1,11 @@
import argparse import argparse
import logging import logging
from typing import TYPE_CHECKING
from clan_cli.completions import add_dynamic_completer, complete_machines from clan_cli.completions import add_dynamic_completer, complete_machines
from clan_lib.errors import ClanError from clan_lib.errors import ClanError
from clan_lib.machines.machines import Machine
from clan_lib.flake import Flake from clan_lib.flake import Flake
from typing import TYPE_CHECKING from clan_lib.machines.machines import Machine
if TYPE_CHECKING: if TYPE_CHECKING:
from .generate import Var from .generate import Var

View File

@@ -54,7 +54,8 @@ class Generator:
@cached_property @cached_property
def exists(self) -> bool: 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) return check_vars(self.machine, self._flake, generator_name=self.name)
@classmethod @classmethod
@@ -116,7 +117,8 @@ class Generator:
return generators return generators
def final_script(self) -> Path: 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.machines.machines import Machine
from clan_lib.nix import nix_test_store from clan_lib.nix import nix_test_store
@@ -131,7 +133,8 @@ class Generator:
return output return output
def validation(self) -> str | None: 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 from clan_lib.machines.machines import Machine
machine = Machine(name=self.machine, flake=self._flake) machine = Machine(name=self.machine, flake=self._flake)

View File

@@ -1,7 +1,7 @@
import io import io
import logging import logging
import tarfile
import subprocess import subprocess
import tarfile
from collections.abc import Iterable from collections.abc import Iterable
from pathlib import Path from pathlib import Path
from tempfile import TemporaryDirectory from tempfile import TemporaryDirectory
@@ -79,7 +79,7 @@ class SecretStore(StoreBase):
return Path(self.entry_prefix) / self.rel_dir(generator, name) return Path(self.entry_prefix) / self.rel_dir(generator, name)
def _run_pass( 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]: ) -> subprocess.CompletedProcess[bytes]:
cmd = [self._pass_command, *args] cmd = [self._pass_command, *args]
# We need bytes support here, so we can not use clan cmd. # We need bytes support here, so we can not use clan cmd.
@@ -88,8 +88,7 @@ class SecretStore(StoreBase):
return subprocess.run( return subprocess.run(
cmd, cmd,
input=input, input=input,
stdout=subprocess.PIPE, capture_output=True,
stderr=subprocess.PIPE,
check=check, check=check,
) )
@@ -152,7 +151,7 @@ class SecretStore(StoreBase):
if not local_hash: if not local_hash:
return True return True
from clan_lib.cmd import RunOpts, Log from clan_lib.cmd import Log, RunOpts
remote_hash = host.run( remote_hash = host.run(
[ [

View File

@@ -139,7 +139,7 @@ def qemu_command(
"-chardev", f"socket,path={qga_socket_file},server=on,wait=off,id=qga0", "-chardev", f"socket,path={qga_socket_file},server=on,wait=off,id=qga0",
"-device", "virtio-serial", "-device", "virtio-serial",
"-device", "virtserialport,chardev=qga0,name=org.qemu.guest_agent.0", "-device", "virtserialport,chardev=qga0,name=org.qemu.guest_agent.0",
] # fmt: on ]
if interactive: if interactive:
command.extend( command.extend(
[ [
@@ -187,7 +187,7 @@ class QMPWrapper:
self._qga_socket: Path = state_dir / "qga.sock" self._qga_socket: Path = state_dir / "qga.sock"
@contextmanager @contextmanager
def qmp_ctx(self) -> Generator[QEMUMonitorProtocol, None, None]: def qmp_ctx(self) -> Generator[QEMUMonitorProtocol]:
rpath = self._qmp_socket.resolve() rpath = self._qmp_socket.resolve()
if not rpath.exists(): if not rpath.exists():
msg = f"qmp socket {rpath} does not exist. Is the VM running?" msg = f"qmp socket {rpath} does not exist. Is the VM running?"

View File

@@ -9,7 +9,6 @@ from types import ModuleType
from typing import ( from typing import (
Annotated, Annotated,
Any, Any,
Generic,
Literal, Literal,
TypeVar, TypeVar,
get_type_hints, get_type_hints,
@@ -17,6 +16,7 @@ from typing import (
from clan_lib.api.util import JSchemaTypeError from clan_lib.api.util import JSchemaTypeError
from clan_lib.errors import ClanError from clan_lib.errors import ClanError
from .serde import dataclass_to_dict, from_dict, sanitize_string from .serde import dataclass_to_dict, from_dict, sanitize_string
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@@ -38,7 +38,7 @@ class ApiError:
@dataclass @dataclass
class SuccessDataClass(Generic[ResponseDataType]): class SuccessDataClass[ResponseDataType]:
op_key: str op_key: str
status: Annotated[Literal["success"], "The status of the response."] status: Annotated[Literal["success"], "The status of the response."]
data: ResponseDataType data: ResponseDataType

View File

@@ -156,12 +156,9 @@ def is_type_in_union(union_type: type | UnionType, target_type: type) -> bool:
return True return True
# For generic types like dict[str, str], check their origin # For generic types like dict[str, str], check their origin
elif get_origin(arg) is not None: elif get_origin(arg) is not None:
if get_origin(arg) == target_type: if get_origin(arg) == target_type or (get_origin(target_type) is not None and get_origin(
return True
# Also check if target_type is a generic with same origin
elif get_origin(target_type) is not None and get_origin(
arg arg
) == get_origin(target_type): ) == get_origin(target_type)):
return True return True
# For actual classes, use issubclass # For actual classes, use issubclass
elif inspect.isclass(arg) and inspect.isclass(target_type): elif inspect.isclass(arg) and inspect.isclass(target_type):
@@ -329,7 +326,7 @@ def construct_value(
raise ClanError(msg) raise ClanError(msg)
def construct_dataclass( def construct_dataclass[T: dataclass](
t: type[T], data: dict[str, Any], path: list[str] | None = None t: type[T], data: dict[str, Any], path: list[str] | None = None
) -> T: ) -> T:
""" """

View File

@@ -6,9 +6,9 @@ import pytest
# Functions to test # Functions to test
from clan_lib.api import dataclass_to_dict, from_dict 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.errors import ClanError
from clan_lib.machines import machines from clan_lib.machines import machines
from clan_lib.api.serde import is_type_in_union
def test_simple() -> None: def test_simple() -> None:

View File

@@ -5,7 +5,7 @@ import types
import uuid import uuid
from collections.abc import Callable from collections.abc import Callable
from dataclasses import dataclass, field 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 from clan_lib.errors import ClanError
@@ -39,7 +39,7 @@ Q = TypeVar("Q") # Data type for the async_opts.data field
@dataclass @dataclass
class AsyncResult(Generic[R]): class AsyncResult[R]:
_result: R | Exception _result: R | Exception
@property @property
@@ -120,7 +120,7 @@ def set_async_ctx(ctx: AsyncContext) -> None:
ASYNC_CTX_THREAD_LOCAL.async_ctx = ctx ASYNC_CTX_THREAD_LOCAL.async_ctx = ctx
class AsyncThread(threading.Thread, Generic[P, R]): class AsyncThread[**P, R](threading.Thread):
function: Callable[P, R] function: Callable[P, R]
args: tuple[Any, ...] args: tuple[Any, ...]
kwargs: dict[str, Any] kwargs: dict[str, Any]
@@ -169,7 +169,7 @@ class AsyncThread(threading.Thread, Generic[P, R]):
@dataclass @dataclass
class AsyncFuture(Generic[R]): class AsyncFuture[R]:
_tid: str _tid: str
_runtime: "AsyncRuntime" _runtime: "AsyncRuntime"
@@ -214,11 +214,11 @@ class AsyncFuture(Generic[R]):
@dataclass @dataclass
class AsyncFutureRef(AsyncFuture[R], Generic[R, Q]): class AsyncFutureRef[R, Q](AsyncFuture[R]):
ref: Q | None ref: Q | None
class AsyncOptsRef(AsyncOpts, Generic[Q]): class AsyncOptsRef[Q](AsyncOpts):
ref: Q | None = None ref: Q | None = None

View File

@@ -747,7 +747,7 @@ class Flake:
ClanError: If the number of outputs does not match the number of selectors. 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. 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.dirs import select_source
from clan_lib.nix import ( from clan_lib.nix import (
nix_build, nix_build,

View File

@@ -9,10 +9,10 @@ from clan_cli.secrets.secrets import (
list_secrets, list_secrets,
) )
from clan_lib.persist.inventory_store import InventoryStore
from clan_lib.api import API from clan_lib.api import API
from clan_lib.dirs import specific_machine_dir from clan_lib.dirs import specific_machine_dir
from clan_lib.machines.machines import Machine from clan_lib.machines.machines import Machine
from clan_lib.persist.inventory_store import InventoryStore
log = logging.getLogger(__name__) log = logging.getLogger(__name__)

View File

@@ -1,9 +1,6 @@
# DO NOT EDIT THIS FILE MANUALLY. IT IS GENERATED. # DO NOT EDIT THIS FILE MANUALLY. IT IS GENERATED.
# This file was generated by running `pkgs/clan-cli/clan_lib.inventory/update.sh` # 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 # fmt: off
from typing import Any, Literal, NotRequired, TypedDict from typing import Any, Literal, NotRequired, TypedDict

View File

@@ -103,7 +103,7 @@ def test_parse_deployment_address(
else: else:
@contextlib.contextmanager @contextlib.contextmanager
def noop() -> Generator[None, Any, None]: def noop() -> Generator[None, Any]:
yield yield
maybe_check_exception = noop() # type: ignore maybe_check_exception = noop() # type: ignore

View File

@@ -22,7 +22,6 @@ from clan_lib.cmd import RunOpts, run
from clan_lib.dirs import specific_machine_dir from clan_lib.dirs import specific_machine_dir
from clan_lib.errors import ClanError from clan_lib.errors import ClanError
from clan_lib.flake import Flake from clan_lib.flake import Flake
from clan_lib.persist.inventory_store import InventoryStore
from clan_lib.machines.machines import Machine from clan_lib.machines.machines import Machine
from clan_lib.nix import nix_command from clan_lib.nix import nix_command
from clan_lib.nix_models.clan import ( from clan_lib.nix_models.clan import (
@@ -32,6 +31,7 @@ from clan_lib.nix_models.clan import (
Unknown, Unknown,
) )
from clan_lib.nix_models.clan import InventoryMachineDeploy as MachineDeploy 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.persist.util import set_value_by_path
from clan_lib.ssh.remote import Remote, check_machine_ssh_login from clan_lib.ssh.remote import Remote, check_machine_ssh_login

View File

@@ -1,6 +1,6 @@
import argparse import argparse
import sys
import re import re
import sys
from dataclasses import dataclass from dataclasses import dataclass
from pathlib import Path from pathlib import Path

View File

@@ -55,6 +55,3 @@ disallow_untyped_calls = true
disallow_untyped_defs = true disallow_untyped_defs = true
no_implicit_optional = true no_implicit_optional = true
exclude = "clan_lib.nixpkgs" exclude = "clan_lib.nixpkgs"
[tool.ruff]
target-version = "py313"