From 6929d23aaff7e54b9a9bf5476cd56dbb2a7bba41 Mon Sep 17 00:00:00 2001 From: mkb79 Date: Fri, 7 Aug 2026 21:28:33 +0200 Subject: [PATCH] style: apply Ruff's safe autofixes The baseline added with #281 recorded 442 findings. 219 of them Ruff can fix on its own without changing behaviour, so this applies them and shrinks the baseline accordingly. Fully gone, 23 rules: the type annotation modernization the project's own target-version already implies (UP006/UP007/UP045, 98 findings), import sorting (I001), docstring formatting (D2xx/D4xx), quote style (Q000), redundant f-strings and conversions (F541, RUF010), and a handful of one-off simplifications (UP009, UP015, UP025, UP032, UP034, UP035, PLR5501, RUF021, RUF022, RUF100). 442 findings -> 230 168 file/rule pairs in the baseline -> 75 29 files with findings -> 23 Nothing was fixed with --unsafe-fixes; those 109 remain untouched because they can change behaviour and deserve to be read one by one. `ruff check --fix` reorders imports, which left `src/audible_cli/__init__.py` unformatted even though it had been clean. It is formatted here and dropped from the formatter's exclude list. The remainder is dominated by G004 (78 f-strings in logging calls), D415 (60 docstring endings) and W291 (24 trailing whitespace), none of which Ruff will fix on its own. --- docs/source/conf.py | 2 + plugin_cmds/cmd_decrypt.py | 50 +++++++++--------- plugin_cmds/cmd_get-annotations.py | 4 +- plugin_cmds/cmd_goodreads-transform.py | 10 ++-- plugin_cmds/cmd_image-urls.py | 1 + plugin_cmds/cmd_listening-stats.py | 9 ++-- plugin_cmds/convert_oa_cred.py | 11 ++-- pyi_entrypoint.py | 2 +- pyproject.toml | 51 +++++++++---------- src/audible_cli/__init__.py | 4 +- src/audible_cli/__main__.py | 1 + src/audible_cli/_logging.py | 12 ++--- src/audible_cli/cli.py | 9 ++-- src/audible_cli/cmds/__init__.py | 8 +-- src/audible_cli/cmds/cmd_activation_bytes.py | 2 +- src/audible_cli/cmds/cmd_download.py | 34 ++++++------- src/audible_cli/cmds/cmd_library.py | 12 ++--- src/audible_cli/cmds/cmd_manage.py | 8 +-- src/audible_cli/cmds/cmd_quickstart.py | 8 +-- src/audible_cli/cmds/cmd_wishlist.py | 14 +++--- src/audible_cli/config.py | 31 ++++++------ src/audible_cli/constants.py | 3 +- src/audible_cli/decorators.py | 9 ++-- src/audible_cli/downloader.py | 53 ++++++++++---------- src/audible_cli/exceptions.py | 2 +- src/audible_cli/models.py | 49 +++++++++--------- src/audible_cli/plugins.py | 42 ++++++---------- src/audible_cli/utils.py | 23 ++++----- utils/update_chapter_titles.py | 5 +- 29 files changed, 225 insertions(+), 244 deletions(-) diff --git a/docs/source/conf.py b/docs/source/conf.py index 5c7d3226..9497168c 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -12,6 +12,8 @@ # import os import sys + + sys.path.insert(0, os.path.abspath("../../src")) import audible_cli diff --git a/plugin_cmds/cmd_decrypt.py b/plugin_cmds/cmd_decrypt.py index 8a09304a..dc428c64 100644 --- a/plugin_cmds/cmd_decrypt.py +++ b/plugin_cmds/cmd_decrypt.py @@ -13,7 +13,7 @@ import operator import pathlib import re -import subprocess # noqa: S404 +import subprocess import tempfile import typing as t from enum import Enum @@ -50,9 +50,9 @@ def is_supported_file(cls, value): def _get_input_files( - files: t.Union[t.Tuple[str], t.List[str]], + files: tuple[str] | list[str], recursive: bool = True -) -> t.List[pathlib.Path]: +) -> list[pathlib.Path]: filenames = [] for filename in files: # if the shell does not do filename globbing @@ -60,7 +60,7 @@ def _get_input_files( if ( len(expanded) == 0 - and '*' not in filename + and "*" not in filename and not SupportedFiles.is_supported_file(filename) ): raise click.BadParameter("{filename}: file not found or supported.") @@ -74,7 +74,7 @@ def _get_input_files( return filenames -def recursive_lookup_dict(key: str, dictionary: t.Dict[str, t.Any]) -> t.Any: +def recursive_lookup_dict(key: str, dictionary: dict[str, t.Any]) -> t.Any: if key in dictionary: return dictionary[key] for value in dictionary.values(): @@ -85,7 +85,7 @@ def recursive_lookup_dict(key: str, dictionary: t.Dict[str, t.Any]) -> t.Any: continue else: return item - + raise KeyError @@ -104,12 +104,12 @@ def get_aaxc_credentials(voucher_file: pathlib.Path): class ApiChapterInfo: - def __init__(self, content_metadata: t.Dict[str, t.Any]) -> None: + def __init__(self, content_metadata: dict[str, t.Any]) -> None: chapter_info = self._parse(content_metadata) self._chapter_info = chapter_info @classmethod - def from_file(cls, file: t.Union[pathlib.Path, str]) -> "ApiChapterInfo": + def from_file(cls, file: pathlib.Path | str) -> "ApiChapterInfo": file = pathlib.Path(file) if not file.exists() or not file.is_file(): raise ChapterError(f"Chapter file {file} not found.") @@ -118,7 +118,7 @@ def from_file(cls, file: t.Union[pathlib.Path, str]) -> "ApiChapterInfo": return cls(content_json) @staticmethod - def _parse(content_metadata: t.Dict[str, t.Any]) -> t.Dict[str, t.Any]: + def _parse(content_metadata: dict[str, t.Any]) -> dict[str, t.Any]: if "chapters" in content_metadata: return content_metadata @@ -167,17 +167,17 @@ def is_accurate(self): def _separate_intro_outro(self, chapters): echo("Separate Audible Brand Intro and Outro to own Chapter.") chapters.sort(key=operator.itemgetter("start_offset_ms")) - + first = chapters[0] intro_dur_ms = self.get_intro_duration_ms() first["start_offset_ms"] = intro_dur_ms first["start_offset_sec"] = round(first["start_offset_ms"] / 1000) first["length_ms"] -= intro_dur_ms - + last = chapters[-1] outro_dur_ms = self.get_outro_duration_ms() last["length_ms"] -= outro_dur_ms - + chapters.append( { "length_ms": intro_dur_ms, @@ -197,13 +197,13 @@ def _separate_intro_outro(self, chapters): } ) chapters.sort(key=operator.itemgetter("start_offset_ms")) - + return chapters def _remove_intro_outro(self, chapters): echo("Delete Audible Brand Intro and Outro.") chapters.sort(key=operator.itemgetter("start_offset_ms")) - + intro_dur_ms = self.get_intro_duration_ms() outro_dur_ms = self.get_outro_duration_ms() @@ -216,14 +216,14 @@ def _remove_intro_outro(self, chapters): last = chapters[-1] last["length_ms"] -= outro_dur_ms - + return chapters class FFMeta: SECTION = re.compile(r"\[(?P
[^]]+)\]") OPTION = re.compile(r"(?P