Open-Source Wikis

/

Ruff

/

Crates

/

`ruff_python_formatter`

astral-sh/ruff

ruff_python_formatter

Ruff's Python formatter. Source: crates/ruff_python_formatter/.

Purpose

Take a parsed Python file (an AST plus its trivia) and emit formatted source code. Default style targets compatibility with Black, with a small set of intentional divergences that are tracked and documented.

History

The first commit landed in February 2023. The formatter is built on a fork of Rome's rome_formatter (now crates/ruff_formatter), which provides the IR-based formatting engine. By late 2023 the formatter was stable and Black-compatible enough to be the default ruff format.

Directory layout

crates/ruff_python_formatter/
├── src/
│   ├── lib.rs
│   ├── format.rs            # top-level format_module / format_expression
│   ├── statement/           # one module per statement kind
│   ├── expression/          # one module per expression kind
│   ├── pattern/             # PEP 634 patterns
│   ├── comments/            # trivia / comment placement
│   ├── prelude.rs           # re-exports for rule files
│   ├── builders.rs          # combinator helpers
│   ├── string/, number/     # literal formatting
│   ├── …
├── resources/test/fixtures/ # Python input files
├── tests/                   # snapshot tests
└── snapshots/

Key abstractions

Type Purpose
PyFormatContext Carries source code, options, and comments through the format tree.
Format<PyFormatContext> The trait every AST node implements. Produces formatter IR (FormatElement).
format!, write! macros (re-exported from ruff_formatter) Compose IR.
Comments Mapping from AST nodes to leading/trailing/dangling comments.

How it works

graph TD
    Source[Python source]
    Parser[ruff_python_parser]
    AST[Mod + Tokens + Trivia]
    CommentMap[Comments map<br/>leading / trailing / dangling]
    IR[FormatElement IR<br/>ruff_formatter]
    Output[Formatted source]

    Source --> Parser
    Parser --> AST
    AST --> CommentMap
    AST --> IR
    CommentMap --> IR
    IR --> Output
  1. Parse the input.
  2. Build a comments map that attaches each comment to a "host" AST node and a position (leading / trailing / dangling). This is the trickiest part of the formatter: where a comment ends up after formatting depends on its surrounding tree shape.
  3. Format the tree by walking nodes and emitting IR via the Format trait. Each node decides how to handle its own children, line breaks, and parenthesization.
  4. Print the IR with a target line width, expanding or collapsing groups based on what fits.

Black compatibility

The formatter aims to produce Black-equivalent output for valid input. Differences are:

  • Tracked in the formatter's CHANGELOG.md and the Black-divergence table.
  • Gated behind preview = true when intentional divergence is in flight.

cargo dev format-dev runs the formatter against a curated corpus and checks that two passes produce identical output (idempotency).

Stability

Stability — format(format(x)) == format(x) — is enforced by both the dev harness and a fuzz target. Any rule that breaks idempotency is treated as a bug.

Integration points

  • Consumed by ruff CLI (ruff format), ruff_server (format on save), ruff_wasm.
  • Depends on ruff_python_parser, ruff_python_ast, ruff_python_trivia, ruff_formatter (the engine).
  • Snapshot fixtures shared with the upstream Black project where possible.

Modifying the formatter

  • Most changes go in expression/ or statement/<construct>.rs. Pick the file whose name matches the AST node kind.

  • Comment placement issues usually live in comments/.

  • After any change, run:

    cargo nextest run -p ruff_python_formatter
    cargo dev format-dev --stability-check
  • Snapshot deltas should be small. Big snapshot churn usually means an unintended ripple — review carefully before committing.

See features/formatter for the user-facing perspective.

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

`ruff_python_formatter` – Ruff wiki | Factory