Skip to content

band-constants โ€‹

A reader opening a module wants its shape to declare itself: what it draws on, what it defines, and the values that fall out of those definitions. When constants sit wherever they were typed, that shape blurs, a configuration value buried between two functions reading no differently from a table derived from them.

gathers module-level constants into two bands, a leading band directly below the imports and a trailing band beneath the definitions, so a module reads top to bottom as its imports, its leading constants, its definitions, then the constants derived from them.

BandHolds
Leadinga constant whose value reaches only imports, builtins, literals, or fellow leading constants
Trailinga constant that names a function or class defined later in the module

The rule relocates a constant into its band, the move that makes the banding a structural concern rather than an alphabetizing one. Each band sorts within its dependency tier by (tier, name), so a constant another constant reads stays above its reader, and the tiering and soundness analysis it rests on lives in the shared tiering primitive that

reads for its definition runs too.

Only an evaluation-time reference binds the order, a right-hand side, a decorator, a default argument, a base class, or a non-deferred annotation. A constant a function reads only inside its body still rides the leading band, because the body does not run at import time. A constant the rule cannot place safely (a reassigned name, a value naming an unresolved reference, or a line a suppression directive or a # prose: keep marker covers) pins where the author left it, and a reference graph that forms a cycle leaves every constant in place.

An own-line comment above a constant rides into the band with it, so a note stays attached to the value it describes. A decorative banner (# --- Configuration ---) is the exception, reading as a section divider that pins the constant beneath it, and a band never crosses such a marker into the section above it.

sections the import run before seats the leading band beneath it, and settles the spacing around the definitions, leaving to own the single blank line dividing the imports from the leading band.

Pair with

to sort the names within each import section and the definition runs, with to partition the imports the leading band seats below, and with to flag a SCREAMING_CASE name whose reassignment pins it out of a band.

Configuration โ€‹

KeyTypeDefaultMeaning
enabledbooltrueToggle the rule on or off

is a single on/off toggle. Left on, it gathers every relocatable module constant into the leading and trailing bands. Turned off with band-constants = false, the constants stay in place among their neighbors. The imports.first-party list under [imports] (see the configuration reference) decides which imports the leading band seats below, since a first-party package's imports group with the local-package section.

The Canonical Case โ€‹

A module-level constant whose value reaches only imports, builtins, and literals rides a leading band directly below the imports, while one that names a later definition pools into a trailing band beneath the definitions. Here TIMEOUT lifts above build into the leading band and SESSION, which calls build, drains to the trailing band, so the module reads as its imports, its leading constants, its definitions, then the constants derived from them.

python
import logging

TIMEOUT = 30


def build(spec):
    return logging.getLogger(spec)


SESSION = build("app")

More Examples โ€‹

A constant whose value touches only literals rides the leading band directly below the imports, hoisting above a function that reads it inside its body, because a body reference defers to call time and constrains no order.

A constant calling a function that reaches a class through a default argument pools beneath both the function and the class, since the call's eval-time surface threads CONFIG past build and the Widget its default names.

A constant naming a module-level function pools into the trailing band beneath the definitions, never rising above the make it names, because evaluating its right-hand side reaches that definition at once.

Banding forward-attaches the own-line prose comment to TTL_SECONDS and hoists the pair into the leading band above render, collapsing the blank line the comment formerly sat above so the comment hugs the constant it describes.

REGISTRY reaches the build_default definition, so it pools into the trailing band beneath the definitions, carrying its own-line prose comment down with it.

A three-tier dependency chain reorders within each tier without crossing tier boundaries. RADIUS is tier 0, DIAMETER is tier 1, and AREA is tier 2, so two tier-0 constants swap relative to source while staying above tier 1.

A module-level run terminates at a # fmt: off block. Assigns above the block sort within their run, the suppression directive bounds its own verbatim scope, and no run forms across the bracket.

No Change

Any Call on a binding's right-hand side skips the entire run. The call could carry observable side effects, so reordering would risk running them out of source order. Source order survives intact.