shed-parentheses
FormattingSheds a grouping parenthesis pair that binds nothing, reflowing the expression onto the line it now fits.
A super(Button, self) call restates the enclosing class and the bound instance that the interpreter already resolves from the method it sits in. The reader parses two arguments to learn nothing the surrounding def did not already say, and the restatement goes stale the moment the class is renamed.
super() form whose behavior is unchanged and whose intent reads at a glance.The rewrite fires only where the bare call resolves the same pair, so the first argument must name the one enclosing class (or the __class__ cell directly) and the second must name the enclosing callable's first positional parameter, whether that reads self, cls, or a positional-only receiver. A call keeps its arguments where they name anything else, where a comprehension or a lambda taking no positional parameter stands between the call and its method, where an enclosing scope binds the class name to something other than the class, where the class is a @dataclass(slots=True) whose generated replacement the bare call's cell does not follow, where a comment sits inside the argument list, and where the module binds super or __class__ itself.
Deleting the arguments pulls every token after them leftward, so a later line of the same statement that the author aligned against a column at or past those arguments would be left pointing at a position that moved. The rule declines rather than strand it, which is the same call
makes when a multi-line import would break its continuation indent. A line hanging one indent step under the statement keeps its depth and the rewrite proceeds, since nothing it was measured against moved.The pass runs after
, so most such lines never reach it. A call the author hand-wrapped has by then either rejoined onto one row or settled into a flush column whose body hangs at a fixed indent, and neither shape hangs off the parenthesis the deletion moves. What still takes the decline is a continuation the layout rules do not own, a grouping pair around a binary expression being the common one.| Key | Type | Default | Meaning |
|---|---|---|---|
enabled | bool | true | Toggles the rule on or off. |
A super(Button, self) call inside Button.render drops to super(), since the interpreter resolves the same class and instance from the enclosing method.
class Widget:
def render(self):
return ""
class Button(Widget):
def render(self):
return super().render() + "!"
A classmethod naming cls and a method whose self sits before a / marker each shorten, the rewrite reading whichever parameter holds the leading positional slot.
A super(...) call sitting in an f-string replacement field shortens like any other, the walk reaching the expression the field interpolates.
A super(...) call in an if header loses its arguments while every line of the body below keeps its indentation, the shift stopping at the end of the header's own logical line.
A super(...) call whose sibling arguments hang one step under the statement rather than aligning to the open parenthesis loses its own arguments and leaves every hanging line where it stands.
A super(...) call whose arguments sit one per line collapses onto the callee's own line, the deletion spanning everything between the parentheses.
An async def shortens the way any method does, and so does a closure whose own first positional parameter is the receiver, the rewrite reading the innermost callable rather than the method around it.
A super(__class__, self) call shortens the same way the class-name form does, because __class__ already names the cell the bare form reads.
A method on a @dataclass(slots=True) class keeps the written form, because that decorator builds a replacement class the bare call's cell does not follow.
A super(...) call inside a comprehension, a parameterless lambda, or a closure taking no arguments keeps its written form, because none of those frames carries the leading positional argument the bare call reads.
An argument list carrying a comment keeps its written form, since deleting the span would take the comment with it.
A super(...) call whose argument list carries a multi-line string keeps its arguments, since shifting a later line would respell that string rather than re-indent a continuation.
A second argument naming a parameter other than the receiver, and a first argument naming a class other than the enclosing one, each keep the written form, since the bare call would resolve a different pair.
Sheds a grouping parenthesis pair that binds nothing, reflowing the expression onto the line it now fits.
Drops a redundant -> None return annotation, since an omitted one already reads as returning nothing.
Rewrites Optional[T], Union[X, Y], and the typing generics to the T | None, X | Y, and builtin forms the target runtime carries.
For per-statement opt-outs, the Suppression chapter covers the # prose: skip[shed-super-args] directive, which holds every line a wrapped statement spans.