astral-sh/ruff
Rules registry
Where rule codes live, how they're organized, and how to look them up.
Source of truth
Single file: crates/ruff_linter/src/codes.rs. Every rule code (F401, B008, RUF019, etc.) is declared there with its rule struct and category. The schema generator and the docs site both read this mapping.
Categories
Rules are grouped by origin (Flake8 plugin name, Pylint, pyupgrade, isort, etc.) plus a few first-party Ruff families:
| Prefix(es) | Source / family |
|---|---|
F |
Pyflakes |
E, W |
pycodestyle errors / warnings |
C90 |
mccabe complexity |
I |
isort |
N |
pep8-naming |
D |
pydocstyle |
UP |
pyupgrade |
YTT |
flake8-2020 |
ANN |
flake8-annotations |
ASYNC |
flake8-async |
S |
flake8-bandit |
BLE |
flake8-blind-except |
FBT |
flake8-boolean-trap |
B |
flake8-bugbear |
A |
flake8-builtins |
COM |
flake8-commas |
CPY |
flake8-copyright |
C4 |
flake8-comprehensions |
DTZ |
flake8-datetimez |
T10 |
flake8-debugger |
DJ |
flake8-django |
EM |
flake8-errmsg |
EXE |
flake8-executable |
FA |
flake8-future-annotations |
ISC |
flake8-implicit-str-concat |
ICN |
flake8-import-conventions |
LOG |
flake8-logging |
G |
flake8-logging-format |
INP |
flake8-no-pep420 |
PIE |
flake8-pie |
T20 |
flake8-print |
PYI |
flake8-pyi |
PT |
flake8-pytest-style |
Q |
flake8-quotes |
RSE |
flake8-raise |
RET |
flake8-return |
SLF |
flake8-self |
SIM |
flake8-simplify |
SLOT |
flake8-slots |
TID |
flake8-tidy-imports |
TD, FIX |
flake8-todos / flake8-fixme |
TC |
flake8-type-checking |
ARG |
flake8-unused-arguments |
PTH |
flake8-use-pathlib |
TRY |
tryceratops |
FLY |
flynt |
NPY |
NumPy-specific |
AIR |
Airflow-specific |
PERF |
Perflint |
FURB |
refurb |
PD |
pandas-vet |
PGH |
pygrep-hooks |
PL, PLC, PLE, PLR, PLW |
Pylint |
RUF |
First-party Ruff rules |
FAST |
FastAPI-specific |
(Some less-common families omitted.)
Implementation locations
Each prefix maps to a directory under crates/ruff_linter/src/rules/<plugin>/. The plugin folder contains a rules/ subdirectory with one .rs file per rule. Snapshots and fixtures live alongside.
Selectors
Users select rules with code or category names:
--select Fenables all Pyflakes rules.--select F4enables only theF4group.--select F401enables a single rule.--select ALLenables everything (rarely used in practice).--select EXTENDextends the existing set rather than replacing.
The selector grammar lives in crates/ruff_linter/src/rule_selector.rs.
Rule redirects
When a rule is renumbered or renamed, crates/ruff_linter/src/rule_redirects.rs keeps the old code resolvable so user configurations don't break. This is the only place where you'll ever see a "deprecated" code.
Rule explanations
Every rule has triple-slash documentation on its struct:
- What it does — one-paragraph summary.
- Why is this bad? — motivation.
- Example — minimal Python sample.
- Use instead — preferred alternative.
- Options — any rule-specific configuration.
- References — link to the upstream tool / PEP / issue.
These doc comments are rendered:
- On the docs site under
Rules. - By
ruff rule <code>at the CLI. - In editor hovers via the LSP.
ty diagnostics
ty's diagnostics are managed separately in crates/ty_python_semantic/src/lint.rs. They have short string ids (invalid-assignment, protocol-violation) instead of letter+number codes, and severity overrides via [lint] in the project config.
Where to look for "I just want to read all rules"
crates/ruff_linter/src/codes.rs— the registry.crates/ruff_linter/src/rules/*/rules/*.rs— implementations and docs.docs/— rendered docs (built by mkdocs from this metadata viacargo dev generate-all).
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.