Skip to content

align-equals โ€‹

A run of consecutive bindings sits at the same indentation, the eye walks down the page, and every = sign lands at a different column. The reader stops at each line to find where the assignment splits.

gathers those runs into a single column, so a stretch of bindings reads as a list of values rather than a stack of expressions.

The rule walks consecutive single-target assignments at the same indentation level, picking up type annotations when present and treating augmented assignments (+=, |=) and walrus operators (:=) as non-members. The same alignment also runs across consecutive annotated function-parameter default values, so a signature with several param: type = default entries aligns its = column the same way a stretch of module-level bindings does. A blank line, a comment line, or a non-assignment statement resets the group, leaving each contiguous run aligned in isolation. Once an alignment group lands,

prunes any one-member residue so a lone binding reads as plain code.

Configuration โ€‹

KeyTypeDefaultMeaning
enabledbooltrueToggle the rule on or off
max-shiftpositive int8Ceiling on per-line padding
max-shift-policy"split" | "drop""split"How to handle a group whose widest member exceeds max-shift. See the per-rule knobs for the full semantics

max-shift caps the per-line padding the alignment can introduce. When a group's widest member would force more padding than the cap allows, max-shift-policy decides the fallback shape, which defaults to "split". The per-rule knobs reference covers the "drop" policy.

The Canonical Case โ€‹

Three consecutive bindings with varying left-hand widths align on the = sign. The eye drops down the column of equals signs and reads the right-hand sides as a parallel list.

python
x       = 1
foo     = 2
bar_baz = 3

More Examples โ€‹

An outlier target partitions the group under the default split policy. The width bands seed from the widest member down, so the outlier sits alone collapsed to one space while every other member shares the dominant = column.

An augmented assignment like beta += 2 aligns its = on the shared column, so the + sits one column before the equals shared by the neighboring plain bindings.

A blank line between two runs splits them into independent groups, so each side settles on its own = column rather than aligning across the gap.

A comment line between two runs splits them into independent groups, mirroring the blank-line boundary, so each side lands on its own = column.

Annotated parameter defaults align across a multi-line signature. The = column sits one space past the widest annotation, with shorter rows padded between the annotation and =.

An annotated assignment carrying an initializer like beta: int = 2 joins the run, its effective left-hand width extending through the annotation so its = lands on the shared column with the plain bindings alongside.

No Change

A run whose = already share a column is idempotent under the rule, so no edit fires and the group passes through unchanged.

No Change

A chained assignment like a = b = 1 carries two = tokens, so the rule skips it rather than guess which one to align, while the surrounding single-target binding aligns around it.

No Change

A parameter whose annotation spans multiple lines breaks the parameter run. The surrounding parameters have widths that would align if grouped, yet they stay unpadded as singletons.