Skip to content

call-layout

A call carrying enough arguments to read as a wall of positionals folds better one argument per line, where the eye reads each binding on its own and a later edit touches a single line.

takes a call whose argument count exceeds max-args and breaks it so each argument lands on its own line in keyword form, leaving shorter calls inline.

The pass fires only on a call every argument of which is keyword-expressible. A positional argument resolves to its parameter name through the call site's in-module binding, so the exploded form reads name=value whatever order the source passed it. A positional-only prefix, a * or ** unpacking, and a positional call whose callee does not resolve to a module function each leave the call inline, because the rule cannot name those arguments. A from x import * clouds resolution the same way, since the wildcard can rebind any name the visible def appears to define, leaving the call inline even though the source shows a matching signature. The expanded form lays each argument one indent step past the call, the closing ) dropping to the call's own indent, and a nested eligible call in an argument value explodes in the same pass.

Where an exploded keyword's value is a dict, list, or comprehension an earlier pass already broke across lines,

re-indents that block to the keyword column rather than splicing it in at its old position, its body one step past the keyword and its closing bracket back at the keyword column. A value whose lines run through a multi-line string keeps its source shape, leaving the string's interior untouched.

The rule reshapes layout and nothing more, leaving argument order to

, which runs ahead of it, so disabling alphabetization leaves the exploded arguments in source order. The = spacing stays with , and whether the last argument carries a trailing comma stays with , which the explode carries through untouched.

Configuration

KeyTypeDefaultMeaning
enabledbooltrueToggles the rule on or off.
max-argspositive int | false3Explodes a call to one keyword argument per line once its argument count exceeds the cap. false disables the count trigger and leaves every call inline.

The Canonical Case

A four-argument call to an in-module function explodes to one keyword argument per line, each positional argument named from the resolved signature and the closing ) dropping to the call's own indent.

def connect(host, port, timeout, user):
    return (host, port, timeout, user)


session = connect(
    host=h,
    port=p,
    timeout=t,
    user=u
)
python

More Examples

The call carries three arguments, at max-args, so the count trigger leaves it inline. Its line still crosses code-line-length, so the width trigger explodes it to one keyword per line regardless of the count. The *-line-length cap is a hard constraint the count knob sits beneath.

An eligible call passed as an argument value explodes alongside its enclosing call, the recursion resolving both levels before the rule returns so the layout is stable in one pass.

The callee binds its leading arguments positionally, so the call cannot take full keyword form. The width trigger explodes it positionally rather than leaving it inline, one argument per line with the closing ) at the call's indent.

A call explodes to one keyword per line while one keyword holds a single-line dict value. The value stays inline rather than re-indenting, since a single-line collection block has no rows to shift.

The callee resolves outside the module, so the call cannot take keyword form. The width trigger still answers it, exploding the positional arguments one per line with the closing ) at the call's indent, so no configuration leaves an over-cap call inline.

An all-keyword method call explodes the same as a free function, the attribute callee carrying its arguments without any signature resolution.

A four-argument all-keyword call explodes regardless of where its callee is defined, because every argument already names its parameter and needs no signature resolution.

max-args = false opts out of the count trigger, yet the width trigger stays live, so a call whose line crosses code-line-length still explodes. No configuration leaves an over-cap call inline.

A call explodes to one keyword per line while one keyword already carries a dict value spread one entry per line. That block re-indents so its entries sit at the keyword's item-indent plus a step and its } at the keyword column, rather than splicing in at the dict's original indentation.

The same re-indent a dict value takes carries a list value. A call explodes to one keyword per line while one keyword already holds a list spread across rows, and that block shifts so its rows sit at the keyword's item-indent plus a step and its ] at the keyword column.

No Change

A three-argument call sits at the default max-args cap and reads fine on one line, so the rule leaves it untouched.

No Change

A from x import * can rebind the callee at runtime, so the rule declines to name the positional arguments against the source-visible def and leaves the call as written.