align-colons
AlignmentPads the space before : so consecutive dict entries, annotated assignments, signature annotations, and docstring entries share one column, with a docstring entry's parenthesized type in a column of its own.
align-imports pads the space before the import keyword across consecutive from … import … statements (or before as across consecutive import … as … statements) so the keyword sits at one column, leaving the module names flush left and the imported names starting at one column to the right. An import block pairs the module a name comes from with the name it brings in, and at varying widths neither reads as a column until the keyword between them lines up.
The rule reads each block as the run of consecutive imports at the same indentation. A blank line, an own-line comment, or a statement of another kind ends the run. alphabetize-siblings sorts the entries within each block and space-statements separates the sections by category, both before this rule measures a column. bare-imports reports on the choice between a bare and a from import without rewriting, so its finding is advice to the author rather than an input to this rule. The Pipeline Order reference lists where each runs.
| Key | Type | Default | Meaning |
|---|---|---|---|
enabled | bool | true | Turns the rule on or off. |
max-shift | positive int | 0 | false | 16 | How far apart the widest and narrowest rows of a run may be for the run to still align on one column. A positive N caps that gap, 0 forbids any padding so every row sits flush, and false lifts the cap so a run of any width aligns on one column. A row marked # prose: skip stays out of its group. |
max-shift limits how much padding one import keyword may take. The rule reads each block of imports in source order and extends a column while the gap between the widest and narrowest module names stays within the limit, starting a new column at the first import that would exceed it. Setting max-shift to false removes the limit, so a block of any width aligns on one column, and 0 forbids padding altogether. The per-rule facets reference covers the full semantics.
Four from … import … statements sit on consecutive lines, and collections is the widest module among them. Every import keyword moves to the column one space past collections, so the imported names OrderedDict, Optional, path, and join start at one column and read as a list.
from collections import OrderedDict
from typing import Optional
from sys import path
from os.path import join
import os sits between two pairs of aliased imports, and LOG_LEVEL = "INFO" sits between two from imports. import os has no as to align, so it splits the run in two, leaving collections and datetime on one as column above it and re and json on another below. The assignment ends a run the same way, so from sys import path and from typing import Optional each stay as written in a run of one.
import collections_with_a_very_long_module_name as long sits below three short aliased imports and above import json as j. The wide import ends the run and keeps its single space, because padding os and re out to its as column would exceed max-shift. datetime, os, and re align their as keywords in the run above it, and json below it stays as written in a run of one.
from re import loads is nine characters narrower than from collections import Counter below it, and from dataclasses import field closes the run. The run still aligns on the import keyword, with re padded out to the column collections and dataclasses share, because a spread of nine sits within the default max-shift.
import collections as c, datetime as dt, functools as fn, and itertools as it sit on four consecutive lines. Every as moves to the column one space past collections, the widest module name, so the aliases c, dt, fn, and it start at one column and read as a list.
An own-line comment sits between from typing import Optional and from sys import path, and import re as regex carries a trailing comment. The own-line comment splits the from imports into two runs, so typing pads to match collections and sys pads only to match os.path. The trailing comment sits inside its row rather than between rows, so re and json still align their as keywords as one run.
The from imports already share the import column collections sets, and the import … as lines below already share an as column. The rule emits no edit, because every gap already sits at its target width, so the output matches the input byte for byte.
The module top carries from __future__ import annotations, three aliased imports out of order, and three blank lines before def add. The directive is removed, collections, numpy, and requests sort, their as keywords pad into one column, and the gap closes to two blank lines before the function.
Bare, external from, and local imports sit scrambled together, with myapp named in first-party. group-imports partitions them into bare, external, and local sections, alphabetize-siblings sorts the names within each section, space-statements writes one blank line between sections, and align-imports pads the import keyword into a column within each section.
Pads the space before : so consecutive dict entries, annotated assignments, signature annotations, and docstring entries share one column, with a docstring entry's parenthesized type in a column of its own.
Pads the space before = so consecutive assignments, annotated parameter defaults, and an exploded call's keyword arguments share one column.
Sorts sibling entries whose order carries no meaning, covering import names, dict keys, class-body members, keyword arguments, and docstring entries.
Reports an unaliased bare import reached through at most max-attributes distinct attributes, which a from x import … would replace.
Sets the blank-line count between module-level definitions, class members, import groups, and the __main__ guard to PEP 8's canonical values.
Folds each single-statement case arm onto one line and pads the space before its : so consecutive arms share one column.