Skip to content

group-imports

A reader scanning a module's head wants to know at a glance what it draws on and from where. When the imports arrive in the order they were typed, the standard library, the third-party packages, and the project's own modules tangle together, and the reader has to read each line to place it.

partitions a contiguous import run into three canonical sections, the bare import statements first, the external from … import … statements next, and the local-package imports last:

SectionHolds
Bareimport os, import numpy as np
External fromfrom collections import Counter
Local-packagerelative imports and any package on the first-party list

The rule relocates imports into their section, the move that makes the grouping a structural concern rather than an alphabetizing one. It leaves the order of the names within a section untouched, the sort within each left to

, so the two agree on the grouping through one shared classifier rather than each deciding membership on its own. A run already sitting in section order passes through with no edit.

A from import is local when it is relative (from . import x, from ..pkg import y) or its module's root package appears on the first-party list. A bare import is local when any aliased root package is first-party. Everything else outside the standard from shape stays bare, and a name the rule cannot classify is no import at all and pins where it sits, ending the run.

A recognized section marker (a hand-drawn banner like # --- Typing --- or a ## hash heading) divides a run into independent sections, so an author who grouped imports under a divider keeps that grouping and no import crosses the marker into the section above it.

owns the single blank line dividing one canonical section from the next, and and act on the grouped result, aligning the import keyword within each section and splitting an over-long from import across lines.

Pair with

to sort the names within each section, with to align the import keyword across the freshly grouped block, and with for the blank line between sections.

Configuration

KeyTypeDefaultMeaning
enabledbooltrueToggle the rule on or off

is a single on/off toggle. Left on, it partitions every import run into the canonical sections. Turned off with group-imports = false, the imports read as one flat block and sorts them together rather than within sections. The imports.first-party list under [imports] (see the configuration reference) names the packages that join the local-package section alongside relative imports.

The Canonical Case

A scrambled run of bare, external from, and relative imports partitions into the three canonical sections. The names within a section keep their source order, the sort left to alphabetize, so sys stays ahead of os here, and the blank line dividing one section from the next is left to blank-lines.

python
import sys
import os
from typing import Any
from collections import Counter
from myapp import app
from . import shared

More Examples

A banner divides a run into independent sections, so each partitions on its own and no import crosses the divider into the section above it.

The rule reaches into compound-statement arms, so a mixed run guarded by if TYPE_CHECKING: groups in place the same as a module-level run.

The rule reaches into every nested body, so a function whose first lines mix a bare and a from import groups them in place the same as a module run.

No Change

A run already sitting in bare → external from → local-package order emits no edit, the rule firing only when the partition would relocate an import.