From 06101b31848d2b8555e0be10400a9beead7d39f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Max=20G=C3=B6rner?= <5477952+MaxG87@users.noreply.github.com> Date: Mon, 6 Jul 2026 22:13:28 +0200 Subject: [PATCH 1/6] refactor: Drop B008 suppression by using t.Annotated --- .../butter-backup/src/butter_backup/cli.py | 38 ++++++++++--------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/projects/butter-backup/src/butter_backup/cli.py b/projects/butter-backup/src/butter_backup/cli.py index 5a36d55..952ca3f 100644 --- a/projects/butter-backup/src/butter_backup/cli.py +++ b/projects/butter-backup/src/butter_backup/cli.py @@ -161,7 +161,7 @@ def _open_device( @app.command() def open( # noqa: A001 - dest: Path | None = typer.Argument(None), # noqa: B008 + dest: t.Annotated[Path | None, typer.Argument()] = None, config: Path | None = CONFIG_OPTION, verbose: int = VERBOSITY_OPTION, ) -> None: @@ -278,22 +278,26 @@ def backup( @app.command() def format_device( - backend: ValidBackends = typer.Argument(...), # noqa: B008 - device: Path = typer.Argument( # noqa: B008 - ..., exists=True, dir_okay=False, readable=False - ), - file_system: ValidFileSystems | None = typer.Option( # noqa: B008 - None, - "--file-system", - help="Dateisystem für das Restic-Backend. Andere Werte als `btrfs` nur für das" - "Restic-Backend gültig. Unterstützte Dateisysteme: btrfs, ext4.", - ), - config_to: Path | None = typer.Option( # noqa: B008 - None, - help="Datei, in welche die generierte Konfiguration geschrieben werden" - " soll. Die angegebene Datei darf nicht existieren. Wenn nicht" - " angegeben, wird die Konfiguration auf STDOUT ausgegeben.", - ), + backend: t.Annotated[ValidBackends, typer.Argument()], + device: t.Annotated[ + Path, typer.Argument(exists=True, dir_okay=False, readable=False) + ], + file_system: t.Annotated[ + ValidFileSystems | None, + typer.Option( + "--file-system", + help="Dateisystem für das Restic-Backend. Andere Werte als `btrfs` nur für das" + "Restic-Backend gültig. Unterstützte Dateisysteme: btrfs, ext4.", + ), + ] = None, + config_to: t.Annotated[ + Path | None, + typer.Option( + help="Datei, in welche die generierte Konfiguration geschrieben werden" + " soll. Die angegebene Datei darf nicht existieren. Wenn nicht" + " angegeben, wird die Konfiguration auf STDOUT ausgegeben.", + ), + ] = None, verbose: int = VERBOSITY_OPTION, ) -> None: """ From eb31117e69c03d3d758c94f4b0a3370fecfcf599 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Max=20G=C3=B6rner?= <5477952+MaxG87@users.noreply.github.com> Date: Mon, 6 Jul 2026 22:13:28 +0200 Subject: [PATCH 2/6] lint: Stop importing collection base classes from typing --- projects/butter-backup/src/butter_backup/cli.py | 3 ++- projects/butter-backup/tests/test_backup_backends.py | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/projects/butter-backup/src/butter_backup/cli.py b/projects/butter-backup/src/butter_backup/cli.py index 952ca3f..9061802 100644 --- a/projects/butter-backup/src/butter_backup/cli.py +++ b/projects/butter-backup/src/butter_backup/cli.py @@ -5,9 +5,10 @@ import os import sys import typing as t +from collections.abc import Callable from pathlib import Path from tempfile import mkdtemp -from typing import Any, Callable +from typing import Any import shell_interface as sh import storage_device_managers as sdm diff --git a/projects/butter-backup/tests/test_backup_backends.py b/projects/butter-backup/tests/test_backup_backends.py index 1974f3b..146ef0f 100644 --- a/projects/butter-backup/tests/test_backup_backends.py +++ b/projects/butter-backup/tests/test_backup_backends.py @@ -3,9 +3,10 @@ import os import typing as t from collections import Counter +from collections.abc import Iterable from pathlib import Path from tempfile import TemporaryDirectory -from typing import Iterable, overload +from typing import overload from uuid import uuid4 import pytest From 9165de691bb164790a8748a564347fc41338dac8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Max=20G=C3=B6rner?= <5477952+MaxG87@users.noreply.github.com> Date: Mon, 6 Jul 2026 22:13:28 +0200 Subject: [PATCH 3/6] lint: Modernise type hints in shell-interface --- .../shell-interface/src/shell_interface/shell_interface.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/projects/shell-interface/src/shell_interface/shell_interface.py b/projects/shell-interface/src/shell_interface/shell_interface.py index 2a7ea69..9897aaa 100644 --- a/projects/shell-interface/src/shell_interface/shell_interface.py +++ b/projects/shell-interface/src/shell_interface/shell_interface.py @@ -5,7 +5,6 @@ import subprocess from pathlib import Path from types import SimpleNamespace -from typing import List, Optional, Union try: from loguru import logger # type: ignore[import, unused-ignore] @@ -16,8 +15,8 @@ logger.debug = lambda msg: None # type: ignore[assignment, unused-ignore] logger.error = lambda msg: None # type: ignore[assignment, unused-ignore] -StrPathList = List[Union[str, Path]] -_CMD_LIST = Union[List[str], List[Path], StrPathList] +StrPathList = list[str | Path] +_CMD_LIST = list[str] | list[Path] | StrPathList class PassCmdError(RuntimeError): @@ -31,7 +30,7 @@ class ShellInterfaceError(RuntimeError): def run_cmd( *, cmd: _CMD_LIST, - env: Optional[dict[str, str]] = None, + env: dict[str, str] | None = None, capture_output: bool = False, ) -> subprocess.CompletedProcess[bytes]: """ From b3528bb1aa2cde871205bf808796ef6968162106 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Max=20G=C3=B6rner?= <5477952+MaxG87@users.noreply.github.com> Date: Mon, 6 Jul 2026 22:13:28 +0200 Subject: [PATCH 4/6] lint: Activate rules UP und FURB --- pyproject.toml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index f809169..5b62c14 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -41,6 +41,7 @@ select = [ "C", "E", "F", + "FURB", "I", "ISC", "PIE", @@ -49,6 +50,7 @@ select = [ "RUF", "SIM", "TID", + "UP", "W", "YTT", ] From 1436e8530860079a76f9c9118800d589bb717270 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Max=20G=C3=B6rner?= <5477952+MaxG87@users.noreply.github.com> Date: Mon, 6 Jul 2026 22:15:54 +0200 Subject: [PATCH 5/6] refactor: Rewrite CONFIG_OPTION to use t.Annotated --- projects/butter-backup/src/butter_backup/cli.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/projects/butter-backup/src/butter_backup/cli.py b/projects/butter-backup/src/butter_backup/cli.py index 9061802..2b52c13 100644 --- a/projects/butter-backup/src/butter_backup/cli.py +++ b/projects/butter-backup/src/butter_backup/cli.py @@ -134,7 +134,7 @@ def _skip_device( return False -CONFIG_OPTION = typer.Option(None, exists=True, dir_okay=False) +CONFIG_OPTION = typer.Option(exists=True, dir_okay=False) VERBOSITY_OPTION = typer.Option(0, "--verbose", "-v", count=True) @@ -163,7 +163,7 @@ def _open_device( @app.command() def open( # noqa: A001 dest: t.Annotated[Path | None, typer.Argument()] = None, - config: Path | None = CONFIG_OPTION, + config: t.Annotated[Path | None, CONFIG_OPTION] = None, verbose: int = VERBOSITY_OPTION, ) -> None: """ @@ -199,7 +199,10 @@ def open( # noqa: A001 @app.command() -def close(config: Path | None = CONFIG_OPTION, verbose: int = VERBOSITY_OPTION) -> None: +def close( + config: t.Annotated[Path | None, CONFIG_OPTION] = None, + verbose: int = VERBOSITY_OPTION, +) -> None: """ Schließe alle geöffneten Speichermedien @@ -231,7 +234,8 @@ def close(config: Path | None = CONFIG_OPTION, verbose: int = VERBOSITY_OPTION) @app.command() def backup( - config: Path | None = CONFIG_OPTION, verbose: int = VERBOSITY_OPTION + config: t.Annotated[Path | None, CONFIG_OPTION] = None, + verbose: int = VERBOSITY_OPTION, ) -> None: """ Führe Sicherheitskopien durch From d8116345af6d228074e27859e41f506db6c7316a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Max=20G=C3=B6rner?= <5477952+MaxG87@users.noreply.github.com> Date: Mon, 6 Jul 2026 22:15:54 +0200 Subject: [PATCH 6/6] refactor: Rewrite VERBOSITY_OPTION to use t.Annotated --- projects/butter-backup/src/butter_backup/cli.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/projects/butter-backup/src/butter_backup/cli.py b/projects/butter-backup/src/butter_backup/cli.py index 2b52c13..cb567eb 100644 --- a/projects/butter-backup/src/butter_backup/cli.py +++ b/projects/butter-backup/src/butter_backup/cli.py @@ -135,7 +135,7 @@ def _skip_device( CONFIG_OPTION = typer.Option(exists=True, dir_okay=False) -VERBOSITY_OPTION = typer.Option(0, "--verbose", "-v", count=True) +VERBOSITY_OPTION = typer.Option("--verbose", "-v", count=True) def _open_device( @@ -164,7 +164,7 @@ def _open_device( def open( # noqa: A001 dest: t.Annotated[Path | None, typer.Argument()] = None, config: t.Annotated[Path | None, CONFIG_OPTION] = None, - verbose: int = VERBOSITY_OPTION, + verbose: t.Annotated[int, VERBOSITY_OPTION] = 0, ) -> None: """ Öffne alle in der Konfiguration gelisteten Speichermedien @@ -201,7 +201,7 @@ def open( # noqa: A001 @app.command() def close( config: t.Annotated[Path | None, CONFIG_OPTION] = None, - verbose: int = VERBOSITY_OPTION, + verbose: t.Annotated[int, VERBOSITY_OPTION] = 0, ) -> None: """ Schließe alle geöffneten Speichermedien @@ -235,7 +235,7 @@ def close( @app.command() def backup( config: t.Annotated[Path | None, CONFIG_OPTION] = None, - verbose: int = VERBOSITY_OPTION, + verbose: t.Annotated[int, VERBOSITY_OPTION] = 0, ) -> None: """ Führe Sicherheitskopien durch @@ -303,7 +303,7 @@ def format_device( " angegeben, wird die Konfiguration auf STDOUT ausgegeben.", ), ] = None, - verbose: int = VERBOSITY_OPTION, + verbose: t.Annotated[int, VERBOSITY_OPTION] = 0, ) -> None: """ Richtet Speichermedium für butter-backup ein