[project] name = "voicebox-backend" version = "0.5.0" requires-python = ">=3.12" # --------------------------------------------------------------------------- # Ruff – linter + formatter # --------------------------------------------------------------------------- [tool.ruff] target-version = "py312" line-length = 120 src = ["."] # Files/dirs to skip entirely. extend-exclude = [ "voicebox-server.spec", "build_binary.py", ] [tool.ruff.lint] select = [ "F", # pyflakes "E", # pycodestyle errors "W", # pycodestyle warnings "I", # isort "N", # pep8-naming "UP", # pyupgrade (modernize syntax for 3.12) "B", # flake8-bugbear "A", # flake8-builtins (shadowing built-in names) "SIM", # flake8-simplify "T20", # flake8-print (flag print() calls) "RET", # flake8-return "PIE", # misc lints "PT", # flake8-pytest-style "RUF", # ruff-specific rules "ERA", # commented-out code detection "FIX", # flag TODO/FIXME/HACK/XXX for review ] ignore = [ # Allow print() in existing code -- remove items from this list as files # are migrated to logging during the refactor. "T201", # print() found # These conflict with the formatter or are too noisy during migration: "E501", # line too long (formatter handles this) "RET504", # unnecessary assignment before return "SIM108", # use ternary operator (sometimes less readable) "B008", # function call in default argument (FastAPI Depends() pattern) "UP007", # use X | Y for union (auto-fixed by UP, but noisy on big diffs) # Existing-violation baseline so ruff can gate CI. Remove entries from # this list as the remaining occurrences are fixed; counts are as of # 2026-07-26 after the auto-fix pass. "B904", # raise without `from` inside except (49) -- needs per-site from err/from None "SIM105", # try/except/pass instead of contextlib.suppress (14) "N806", # non-lowercase variable in function (9) "RUF002", # ambiguous unicode in docstring (6) "F841", # unused variable (5) "N803", # invalid argument name (5) "B007", # unused loop control variable (4) "ERA001", # commented-out code (4) "SIM102", # collapsible if (4) "SIM117", # multiple with statements (4) "SIM115", # open() without context manager (3) "RUF001", # ambiguous unicode in string (2) "RUF012", # mutable class default (2) "SIM110", # reimplemented builtin (2) "RUF006", # asyncio dangling task (1) "RUF034", # useless if-else (1) ] # Per-file rule overrides. [tool.ruff.lint.per-file-ignores] # Tests can use assert, print, magic values, and script-style setup freely. "tests/**" = ["S101", "T201", "PLR2004", "ERA001", "E402", "PT011", "PT018", "PT019"] # __init__.py re-exports are expected to have unused imports. "**/__init__.py" = ["F401"] # Entry points and scripts legitimately use print. "main.py" = ["T201"] # AMD GPU env vars must be set before torch import. "app.py" = ["E402"] # Environment and stdout hardening must run before heavy imports. "server.py" = ["T201", "E402"] "backends/__init__.py" = ["E402"] "backends/mlx_backend.py" = ["E402"] "backends/pytorch_backend.py" = ["E402"] [tool.ruff.lint.isort] known-first-party = ["backend"] # Group "from backend.*" imports into the first-party section. force-single-line = false combine-as-imports = true [tool.ruff.format] quote-style = "double" indent-style = "space" docstring-code-format = true # --------------------------------------------------------------------------- # pytest # --------------------------------------------------------------------------- [tool.pytest.ini_options] testpaths = ["tests"] asyncio_mode = "auto" markers = [ "slow: long-running tests, deselect with '-m \"not slow\"'", "timeout: per-test timeout in seconds (enforced only when pytest-timeout is installed)", ]