This project uses modern Python code quality tools to maintain consistency and catch issues early.
- Black - Opinionated code formatter
- Ruff - Fast Python linter (replaces flake8, isort, and more)
- mypy - Static type checker
All tools are configured in pyproject.toml:
- Black: 100 character line length, Python 3.13 target
- Ruff: Comprehensive linting rules including import sorting, code simplification, and bug detection
- mypy: Type checking with relaxed settings (can be made stricter later)
# Auto-fix formatting and linting issues
./fix.sh
# Run all quality checks (no changes)
./check.sh# Format code with Black
./format.sh
# Run linter
./lint.sh
# Type check
./typecheck.shAlways run the fix script to auto-format and fix linting issues:
./fix.shThen verify everything passes:
./check.shAdd to your CI pipeline:
# Check formatting (fails if not formatted)
uv run black --check backend/
# Check linting
uv run ruff check backend/
# Run type checks
uv run mypy backend/E- pycodestyle errorsW- pycodestyle warningsF- pyflakesI- isort (import sorting)B- flake8-bugbearC4- flake8-comprehensionsUP- pyupgradeARG- flake8-unused-argumentsSIM- flake8-simplify
Some issues require manual intervention:
- E402 (Module level import not at top) - Fixed by moving imports to the top
- SIM108 (Use ternary operator) - Simplified if-else to ternary
- B905 (zip without strict) - Added
strict=Trueto zip calls - Type annotations - mypy will highlight these (optional to fix)
Type checking is currently set to disallow_untyped_defs = false to allow gradual adoption. To make it stricter:
-
Edit
pyproject.toml:[tool.mypy] disallow_untyped_defs = true
-
Add type hints to functions:
def my_function(param: str) -> int: return len(param)
-
Run
./typecheck.shto verify
Install these extensions:
- Python (Microsoft)
- Black Formatter
- Ruff
Add to .vscode/settings.json:
{
"python.formatting.provider": "black",
"editor.formatOnSave": true,
"python.linting.enabled": true,
"ruff.enable": true
}- Go to Settings → Tools → Black
- Enable "Run Black on save"
- Go to Settings → Tools → External Tools
- Add Ruff as an external tool
chmod +x *.shsed -i 's/\r$//' *.shEnsure dependencies are installed:
uv syncThese dev dependencies were added to pyproject.toml:
[dependency-groups]
dev = [
"black>=26.1.0",
"mypy>=1.19.1",
"ruff>=0.14.14",
]To update them:
uv lock --upgrade