Open-Source Wikis

/

Ruff

/

Features

/

Linter

astral-sh/ruff

Linter

End-to-end view of how Ruff's linter turns a Python file into diagnostics.

What the user sees

ruff check src/

For each file, Ruff reports issues like:

src/foo.py:3:1: F401 [*] `os` imported but unused
src/foo.py:8:5: E711 Comparison to `None` should be `is None`

[*] means a fix is available. With --fix they're applied; with --unsafe-fixes even unsafe ones are.

End-to-end pipeline

graph TD
    User[user runs ruff check]
    CLI[ruff CLI<br/>crates/ruff]
    Workspace[ruff_workspace<br/>resolve Settings]
    Walker[ignore::WalkBuilder]
    Files[file list]
    Cache[ruff cache check]
    Parser[ruff_python_parser]
    Index[ruff_python_index]
    Sem[ruff_python_semantic::SemanticModel]
    Linter[ruff_linter::check_path]
    Checkers[checkers/ast.rs<br/>checkers/tokens.rs<br/>checkers/physical_lines.rs<br/>checkers/logical_lines.rs<br/>checkers/imports.rs<br/>checkers/filesystem.rs<br/>checkers/noqa.rs]
    Diag[Vec<Diagnostic>]
    Fixer[ruff_linter::fix]
    Printer[crates/ruff/src/printer.rs]
    Output[stdout / file]

    User --> CLI
    CLI --> Workspace
    CLI --> Walker
    Walker --> Files
    Files --> Cache
    Cache --> Parser
    Parser --> Index
    Index --> Sem
    Parser --> Linter
    Sem --> Linter
    Linter --> Checkers
    Checkers --> Diag
    Diag --> Fixer
    Fixer --> Printer
    Printer --> Output

Pieces in detail

Stage Where Notes
Argument parsing crates/ruff/src/args.rs Clap-derived Args.
Settings resolution crates/ruff_workspace/src/resolver.rs Walks for pyproject.toml / ruff.toml, applies CLI overrides.
File discovery crates/ruff/src/resolve.rs Uses the ignore crate; respects .gitignore, .ignore, and Ruff's exclude.
Parallelism rayon::par_iter One Rust-side concurrent task per file.
Caching crates/ruff/src/cache.rs Per-package cache file under .ruff_cache/.
Parsing ruff_python_parser Permissive, error-recovering.
Lint pipeline ruff_linter Orchestrates checkers, manages SemanticModel.
Semantic model ruff_python_semantic Built up by the AST checker as it walks.
Output crates/ruff/src/printer.rs Multiple formats: text, concise, JSON, GitHub, SARIF, etc.

Rule selection

--select and --ignore are parsed by ruff_linter::rule_selector. Selectors can be:

  • A specific code (F401)
  • A prefix (F, E5)
  • A category (ALL, EXTEND)
  • A plugin name (flake8-bugbear)

Combined with select, extend-select, ignore, and extend-ignore from the configuration file. The end result is a RuleTable consulted by every checker.

Per-file overrides

per-file-ignores (and extend-per-file-ignores) attach to glob patterns. Before checking each file, the linter swaps in the matching RuleTable.

noqa

# noqa comments are parsed line-by-line by crates/ruff_linter/src/noqa.rs. Diagnostics emitted on a line whose noqa list covers the rule are suppressed at the end of the pipeline. Bare # noqa (no codes) suppresses all rules.

The noqa checker also flags unused/unknown directives, so codebases don't accumulate stale suppressions.

Output formats

Selected by --output-format. Implementations live in crates/ruff/src/printer.rs:

Format Use case
text (default) Terminal display with color and snippets.
concise One line per diagnostic.
grouped Grouped by file.
json Machine-readable (one JSON object).
json-lines One JSON object per line.
junit XML for test runners.
github GitHub Actions annotations.
gitlab GitLab Code Quality.
sarif SARIF for security scanning tools.
azure Azure Pipelines.
pylint Pylint-compatible.

Performance notes

  • File reading and parsing dominate cold-cache runs.
  • Hot caches reduce work to "stat, hash, compare key" per file.
  • rayon parallelism is per-file.
  • Most rules are O(AST size) at most; the AST checker dispatches by node kind so adding a rule rarely shows up as a hot spot.

Where to start when extending

  • Add a rule: see ruff_linter.
  • Tune file discovery: crates/ruff/src/resolve.rs.
  • Add an output format: crates/ruff/src/printer.rs + args.rs.
  • Add a configuration option: ruff_workspace.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Linter – Ruff wiki | Factory