4.2 KiB
| title | type | status | date |
|---|---|---|---|
| feat: Activate pre-commit hooks (black, ruff, isort) | feat | active | 2026-04-24 |
Activate Pre-commit Hooks
Overview
.pre-commit-config.yaml exists but is explicitly disabled ("intentionally minimal and does not enable hooks by installing them"). Activating black, ruff, and isort would enforce CODE_STYLE.md conventions automatically and eliminate style-only review comments.
Problem Frame
- Code style is documented in CODE_STYLE.md but not enforced automatically
- Contributors may submit PRs with inconsistent formatting
- Review time is spent on style nits instead of logic
- No CI check for formatting violations
Requirements Trace
- R1. Pre-commit hooks run black, ruff, and isort
- R2. Hooks are enforced in CI (fail build on violations)
- R3. Hooks use the same versions as pyproject.toml dev dependencies
- R4. Initial run reformats existing code without breaking tests
Scope Boundaries
Included:
- Update
.pre-commit-config.yaml - Add CI workflow step for pre-commit
- Run initial format across codebase
Excluded:
- Adding new linters or rules
- Changing CODE_STYLE.md conventions
- Fixing logic bugs found by ruff (separate PR)
Key Technical Decisions
- Use pre-commit.ci or GitHub Action — pre-commit.ci is zero-config but may not work on Gitea. Use a GitHub Actions step as fallback.
- Single large format commit — Run once, commit formatting changes separately from config changes so reviewers can see the diff.
- Skip tests during format — Formatting should not change behavior, but run tests after to verify.
Implementation Units
- U1. Update .pre-commit-config.yaml
Goal: Enable black, ruff, and isort with versions matching pyproject.toml.
Requirements: R1, R3
Dependencies: None
Files:
- Modify:
.pre-commit-config.yaml
Approach:
- Remove the "does not enable hooks" comment
- Add repos for black, ruff, isort with pinned versions
- Set ruff to match CODE_STYLE.md rules
- Configure isort profile (black-compatible)
Test scenarios:
- Happy path:
pre-commit run --all-filescompletes successfully - Error path: A file with style violations fails the hook
- Integration: Versions match pyproject.toml dev deps
Verification:
pre-commit run --all-filesruns without config errors
- U2. Add pre-commit CI step
Goal: Block PRs that violate formatting rules.
Requirements: R2
Dependencies: U1
Files:
- Modify:
.github/workflows/pytest.yml(or create separate lint.yml)
Approach:
- Add a job that runs
pre-commit run --all-files - Use the same uv setup as the pytest workflow
- Install pre-commit via uv
Test scenarios:
- Happy path: Clean code passes pre-commit CI
- Error path: Violations fail the CI job
Verification:
- Pushing a formatting violation fails the check
- Pushing clean code passes
- U3. Run initial format across codebase
Goal: Bring all existing code into compliance so future PRs only touch their own changes.
Requirements: R4
Dependencies: U1
Files:
- Modify: All Python files (mechanical reformatting)
Approach:
- Run
pre-commit run --all-files - Commit formatting changes separately
- Run full test suite:
uv run pytest tests/ -q
Execution note: This is a mechanical change. Characterization tests should pass unchanged. If tests fail, the formatter broke something — investigate before committing.
Test scenarios:
- Integration: All existing tests pass after formatting
- Edge case: No logic changes introduced by formatting
Verification:
uv run pytest tests/ -qpassesgit diffshows only whitespace/import changes
Risks & Dependencies
| Risk | Mitigation |
|---|---|
| Massive format commit obscures git blame | Use .git-blame-ignore-revs to ignore the format commit |
| Ruff finds existing logic issues | Fix or suppress in separate PR; don't mix with activation |
| Contributors without pre-commit installed | CI catches it; add setup note to README |
Documentation / Operational Notes
- Add pre-commit setup to README quickstart
- Document
.git-blame-ignore-revsusage
Sources & References
- Config:
.pre-commit-config.yaml - Style guide:
CODE_STYLE.md - Dependencies:
pyproject.toml