# Pin a compatible hook revision

Identity: Python / Pre-commit Configuration.
Recorded Ruff pin: v0.16.6. Source version: 2026.10.4.

Quoted from [Python: Pre-commit Configuration](/guides/languages/python/#pre-commit-configuration).

Hook revisions **MUST** be pinned to a tag that exists in the hook repository
and **MUST** be new enough to parse the project's `target-version`.

**Why**: Ruff 0.8.0 rejects this guide's Ruff configuration outright —
`unknown variant py314, expected one of py37 ... py313` — and Mypy 1.13.0 cannot
parse a t-string, reporting `invalid syntax; you likely need to run mypy using
Python 3.14 or newer`. A stale pin is not a conservative choice; it is a
lint stage that never runs.

```yaml
repos:
  - repo: https://github.com/astral-sh/ruff-pre-commit
    rev: v0.16.6
    hooks:
      - id: ruff-check
        args: [--fix]
      - id: ruff-format

  - repo: https://github.com/pre-commit/mirrors-mypy
    rev: v2.3.1
    hooks:
      - id: mypy
        args: [--strict]

  - repo: https://github.com/semgrep/semgrep
    rev: v1.176.0
    hooks:
      - id: semgrep
        args: [--config=p/python, --config=p/security-audit, --error]

  - repo: https://github.com/jendrikseipp/vulture
    rev: v2.16
    hooks:
      - id: vulture
        args: [src/, --min-confidence=90]
```

## Don't: illustrative counterexample

```yaml
rev: v0.8.0
hooks:
  - id: ruff
```

Both Ruff examples use `https://github.com/astral-sh/ruff-pre-commit`.

## Trace this rule

1. **Obligation.** The tag must exist and the hook must parse the target. Both conditions apply.
2. **Examples.** The full configuration is quoted from the guide. The bad example illustrates
   the incompatible Ruff revision described in its rationale; it is not an executed fixture.
3. **Checker.** Review required. This site build does not run a compatibility or tag-existence check.
4. **Context.** Read the [complete Python guide](/guides/languages/python/#pre-commit-configuration) for configuration and migration notes.
