Skip to content

Python

Files ending in .py are formatted by the Python pack (rainbow_fmt.languages.python, grammar tree-sitter-python). The defaults follow PEP 8 and Black's main rules; byte-identical Black output is not a goal, and where users differ there is an option.

import os
def connect(host,port = 5432,*,timeout=None) :
  result=open_connection(host_name_argument, port_number_argument, timeout_value)
  return result

becomes

import os


def connect(host, port=5432, *, timeout=None):
    result = open_connection(
        host_name_argument, port_number_argument, timeout_value
    )
    return result

What changes and what does not

The pack changes layout only. Strings (prefixes, quotes, escapes, f-string contents, the lines of multi-line strings and docstrings), numbers and comment texts are printed as written, and parentheses are never added or removed.

  • Indentation comes from the tree (core.indent_style, core.indent_size); elif, else, except, finally and case are aligned with their statement.
  • Spacing within a line: one space around binary, comparison, boolean and assignment operators, ->, :=, and after commas and colons; none inside brackets, before the (/[ of calls and subscripts, around ., after unary operators and */** unpacking, or around the = of keyword arguments and unannotated defaults (def f(a: int = 1, b=2)). ** hugs simple operands (x**2, but x ** f(y)). Slice colons get spaces only when an operand is complex, and not on an omitted side (a[1:2], a[x + 1 :]).
  • Brackets (calls, parameters, collections, subscripts, parenthesized expressions and imports, with (…), type parameters, patterns) are printed flat if they fit. Otherwise a collection (list, set, dict, tuple, parenthesized import list) goes one item per line; the other brackets first try their items on one indented line:
result = some_function_name(
    argument_number_one, argument_number_two, argument_3
)
data = {
    "key": [1, 2, 3],
    "other": {"nested": True, "list": [4, 5, 6]},
    "more": 1,
}

One item per line gets a trailing comma (shared.trailing_comma, whose default is "multiline" for Python). The last bracket of a line breaks first (x = a.query(y).filter( …). - Inside brackets, an item that still does not fit breaks at the operators of its lowest-precedence level (all at once; or before and), before the for/if of a comprehension, before the if/else of a conditional expression, and between the parts of an implicit string concatenation. Outside brackets nothing breaks, so a long line without brackets stays long. - Blank lines: none at the start of the file or of a block; around definitions see definition_blank_lines. - Comments: a comment after code stays on its line, after inline_comment_spaces spaces; a comment on its own line is indented to its block (the tree decides: a comment before else at the if level belongs to the if). A comment inside brackets stays with its item (after the comma) and forces the brackets to break. - One-liners and semicolons are kept (if x: pass, a = 1; b = 2), with normalized spacing. - Inline directives (# rainbow: off, # fmt: off, # fmt: skip, # rainbow: set …) keep statements as written or change options for one statement (configuration.md). - Backslash continuations: a statement with one (for a compound statement, its header up to the colon) is printed as written, apart from the indentation of its first line.

Options

Key Values Default
language.python.bracket_wrap "magic_trailing_comma": a trailing comma in the source keeps the items one per line (not the comma of a 1-tuple or a subscript); "fit": trailing commas do not force a break and are removed when a list is joined; "preserve": a line break between two items keeps them one per line, a line break only after the opening bracket keeps the brackets broken "magic_trailing_comma"
language.python.binary_operator_break "before" or "after" the operators of a broken expression (PEP 8 recommends before) "before"
language.python.definition_blank_lines "enforce": exactly top_level_blank_lines around top-level def/class (comments directly above belong to the definition) and nested_blank_lines around nested ones; "cap": those counts are maxima; "preserve": at most core.max_blank_lines "enforce"
language.python.top_level_blank_lines integer >= 0; also the maximum between other top-level statements 2
language.python.nested_blank_lines integer >= 0 1
language.python.inline_comment_spaces integer >= 1 2
language.python.statement_blank_lines "preserve": as written; "separate": in a function body, a blank line before and after a for/while loop, after an if statement, and before an if that follows another if or a loop (never removed: at most max_blank_lines; comment lines directly above a statement move with it) "preserve"
language.python.docstrings "preserve": as written; "aligned": the summary on the opening line, the closing """ on a line of its own, the lines after the summary aligned three columns in (under its first letter), keeping their relative indentation "preserve"
language.python.bracket_hug true: a list, tuple or set whose items are all non-empty dicts hugs them ([{ … }, { … }]) when it does not fit on one line false
shared.trailing_comma "never", "multiline" "multiline" for Python

With bracket_wrap = "magic_trailing_comma" and trailing_comma = "never", no commas are added, but a trailing comma in the source is kept: it is what keeps the list broken. Inside blocks, blank lines between statements other than definitions are limited by core.max_blank_lines.

Limitations

  • No .pyi stubs yet, no quote or number normalization, no comment normalization (#x stays), no docstring re-indentation.
  • Parentheses are never added, so return, assignment right-hand sides and if conditions without brackets are not broken (Black adds parentheses to break them).
  • Black breaks the parameters rather than a subscript in a return annotation; rainbow-fmt breaks the last bracket.
  • The grammar (tree-sitter-python 0.25) does not parse PEP 696 type parameter defaults (class C[T = int], Python 3.13); such files are reported as syntax errors and left unchanged.