diff --git a/pyproject.toml b/pyproject.toml index 6751e32..1799f82 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -41,10 +41,16 @@ src = ["src", "tests"] extend-exclude = ["*.md"] [tool.ruff.lint] -select = ["E", "F", "W", "I", "N", "UP", "B", "A", "C4", "SIM", "PTH", "RET", "ARG", "TID", "TC", "RUF"] +select = ["E", "F", "W", "I", "N", "UP", "B", "A", "C4", "SIM", "PTH", "RET", "ARG", "TID", "TC", "RUF", "S"] +# S607: binaries are looked up on PATH on purpose and preflight-checked with +# shutil.which; hardcoding absolute paths would be less portable, not safer. +ignore = ["S607"] [tool.ruff.lint.per-file-ignores] -"tests/*" = ["ARG001", "ARG002"] +# S101: asserts are the point of a test file. +"tests/*" = ["ARG001", "ARG002", "S101"] +# Throwaway benchmarks, not pipeline code. +"scripts/*" = ["S603"] [tool.pyright] include = ["src", "tests"] diff --git a/src/ccn_transcribe/media/ffmpeg.py b/src/ccn_transcribe/media/ffmpeg.py index dbce174..ceb40d7 100644 --- a/src/ccn_transcribe/media/ffmpeg.py +++ b/src/ccn_transcribe/media/ffmpeg.py @@ -35,7 +35,8 @@ REQUIRED_BINARIES = ("ffmpeg", "ffprobe") def _run(args: list[str], *, check: bool = True) -> subprocess.CompletedProcess[bytes]: try: - return subprocess.run(args, capture_output=True, check=check) + # Argument lists are built here from fixed templates; never a shell string. + return subprocess.run(args, capture_output=True, check=check) # noqa: S603 except FileNotFoundError as exc: raise errors.PreflightError( f"{args[0]} is not installed or not on PATH", diff --git a/tests/conftest.py b/tests/conftest.py index 24ce174..eae905f 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -10,7 +10,7 @@ if TYPE_CHECKING: def _run(args: list[str]) -> None: - subprocess.run(args, capture_output=True, check=True) + subprocess.run(args, capture_output=True, check=True) # noqa: S603 @pytest.fixture(scope="session")