align-colons
AlignmentAligns the : separator across dict literals, annotated assignments, function-signature annotations, and Google-style docstring sections.
An alignment group exists to give the reader's eye a column to drop down. With two or more members the column carries information, where each row reads as a row in a table. With exactly one member the column becomes a single cell, and padding it to a width that no sibling matches adds visual noise without payoff.
strips the pre-: padding from every :-alignment context that resolves to a single member, so a one-key dict, a one-arg signature, or a one-field dataclass reads as plain code instead of a one-row table.The rule operates on the :-shaped contexts that
match-arm context that covers. Multi-member groups whose :s sit on distinct lines and open at a shared column pass through this rule untouched, since the colon-alignment surfaces own them. A run whose rows open at differing columns realizes no shared column, so its padding strips here the way a singleton's does. The =-alignment from and the import-keyword alignment from carry their own one-member fallbacks and don't need pruning here.Beyond the pre-: gap, the rule settles the run after a colon to one space wherever that colon introduces a value, so a stray x: int reads as x: int and a missing space in x:int fills to one. A match-arm body keeps the spacing
(, [, or {, or directly before its closer, lines up with nothing, so int(a ) settles to int(a) and [ 1, 2 ] to [1, 2]. Each side strips on its own, and only where the pad shares a line with the content beside it, so a closer on its own line keeps its indent. The braces of an f-string or t-string replacement field are not delimiters this rule touches, wherein a debug f"{ total = }" keeps the spaces it echoes into its output. On a [ 1, 2, ], drops the comma while this rule clears both pads.| Key | Type | Default | Meaning |
|---|---|---|---|
enabled | bool | true | Toggles the rule on or off. |
enabled. Turning it off leaves one-member alignment contexts as one-row tables (a one-key dict reading with the same padding a multi-key dict would carry), which is rarely what a project wants in practice.A one-key dict literal drops its pre-: padding, reading as a plain key-value pair rather than a one-row table.
single = {"only_key": compute_value()}
paired = {
"first" : 1,
"second" : 2,
}
nested = {
"outer": {"inner": "value"},
}
Interior padding strips only when it shares a line with the content it pads. A closing bracket on its own line carries leading indent rather than a stranded space, so the rule leaves it while the same-line collection beside it tightens.
A docstring Args: section with one entry strips the pre-: padding on that entry. A section with two or more entries keeps its padding for align_colons to align in a separate pass.
A single-parameter signature with extra padding before its : is the canonical singleton shape, so the rule strips that padding to zero. Multi-parameter signatures collapsed onto one line do the same, because every : shares a line and has no column to align against. Spread across multiple lines, they stay padded for align_colons.
A pre-collapsed one-arm match carries one space before its colon. The rule strips the gap, leaving the : flush against the pattern.
The braces of an f-string or t-string replacement field are not the delimiters this rule touches, so a debug f"{ total = }" keeps the spaces it echoes into its output, whereas a real set literal beside it still strips.
A multi-line single-parameter signature strips its pre-: padding, since the lone parameter and its : share a line with non-zero width. A multi-line multi-parameter signature qualifies two distinct-line members, so the rule defers to align_colons and the padding stays.
The run after the colon settles to one space by measuring against the value's parenthesis-aware start, so the wrapping ( stays where it is. A {"key": (1, 2)} reads as {"key": (1, 2)} with the tuple's parentheses untouched.
A space run directly after an opening (, [, or { or directly before its closer lines up with nothing, so the rule pulls the delimiter tight against its content wherever the pad appears.
Class fields, dict literals, and function parameters interleave singleton contexts with multi-item groups. Singletons strip their pre-: padding while multi-line multi-item groups stay padded for align_colons. A multi-item group squashed onto one line strips too, because same-line : have no column to align against.
An annotated assignment that survives its aligned group as a lone row keeps the pre-: padding that once lined up with a column now gone. A module-level _handlers : Dict[Text, Callable] = {} and a function-body timeout : int = 30 each shed that padding down to name:, since no
An unannotated self yields a None that splits the parameter slice into runs. A method with one annotated parameter after self forms a singleton run that strips its pre-: padding, as does a keyword-only parameter introduced by *. Two annotated parameters land a size-two run on one line, which strips because same-line : have no column to align against.
The run after a colon that aligns with nothing settles to one space, whichever context carries the colon. A one-key dict value, a lone annotated parameter, and a function-body annotation each read as name: value, collapsing a padded payload: dict and inserting the missing space into result:int.
Every singleton context already carries zero pre-: padding. The rule recognizes each gap as empty and emits no edits, so the output equals the input byte-for-byte and the pipeline reports no change.
Aligns the : separator across dict literals, annotated assignments, function-signature annotations, and Google-style docstring sections.
Aligns the = separator across consecutive single-target assignments, annotated function-parameter defaults, and an exploded call's keyword arguments.
Aligns the import and as keywords across consecutive import statements.
Aligns the post-pattern : across single-expression case bodies inside a match statement.
Removes trailing commas from collections, signatures, calls, and every other bracketed container.