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. Members above align among themselves, members below align among themselves, and the outlier collapses to one space. Each sub-group settles on a different = 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.