Description
Black produces two different idempotent outputs for consecutive @overload function definitions depending on the initial whitespace between them. Both outputs are stable (running Black again produces no changes), but they correspond to the same AST.
This means Black does not converge to a single canonical form for this pattern — the output depends on the input formatting, not only on the AST.
Steps to reproduce
Input A — no blank lines between overloads:
from typing import overload
@overload
def f(x: int) -> int: ...
@overload
def f(x: str) -> str: ...
def f(x): ...
Input B — two blank lines between overloads:
from typing import overload
@overload
def f(x: int) -> int: ...
@overload
def f(x: str) -> str: ...
def f(x): ...
Running black --check on both files exits with code 0 (no changes).
Both parse to the same AST (ast.dump comparison returns True).
Expected behavior
I would expect Black to normalize both inputs to a single canonical layout, since they represent the same AST and neither contains comments or other distinguishing CST information.
Environment
- Reproduced on Black 24.4.2 and 26.1.0
- Python 3.12
Question
Is this intentional behavior (e.g. preserving the author's grouping intent), or should Black canonicalize blank lines between consecutive @overload definitions?
Description
Black produces two different idempotent outputs for consecutive
@overloadfunction definitions depending on the initial whitespace between them. Both outputs are stable (running Black again produces no changes), but they correspond to the same AST.This means Black does not converge to a single canonical form for this pattern — the output depends on the input formatting, not only on the AST.
Steps to reproduce
Input A — no blank lines between overloads:
Input B — two blank lines between overloads:
Running
black --checkon both files exits with code 0 (no changes).Both parse to the same AST (
ast.dumpcomparison returnsTrue).Expected behavior
I would expect Black to normalize both inputs to a single canonical layout, since they represent the same AST and neither contains comments or other distinguishing CST information.
Environment
Question
Is this intentional behavior (e.g. preserving the author's grouping intent), or should Black canonicalize blank lines between consecutive
@overloaddefinitions?