Skip to content

In stub files, enforce a blank line between a function and a decorated class definition#5092

Open
AlexWaygood wants to merge 4 commits intopsf:mainfrom
AlexWaygood:alex/decorated-function-before-class
Open

In stub files, enforce a blank line between a function and a decorated class definition#5092
AlexWaygood wants to merge 4 commits intopsf:mainfrom
AlexWaygood:alex/decorated-function-before-class

Conversation

@AlexWaygood
Copy link
Copy Markdown
Contributor

Description

In .pyi stub files, Black already enforces a blank line before a (decorated or undecorated) class definition in many situations. However, it fails to do so if the decorated class definition is immediately preceded by a function.

For this example file, saved as foo.pyi:

def a(): ...
class A: ...

@deco
class B: ...
@deco
class C: ...

def d(): ...

@deco
class D: ...

def e(): ...
@deco
class E: ...

Black applies this formatting on main with --preview

--- foo.pyi	2026-04-11 13:21:51.522132+00:00
+++ foo.pyi	2026-04-11 13:22:54.144533+00:00
@@ -1,15 +1,16 @@
 def a(): ...
+
 class A: ...
 
 @deco
 class B: ...
+
 @deco
 class C: ...
 
 def d(): ...
-
 @deco
 class D: ...
 
 def e(): ...
 @deco

On this PR branch, the formatting changes to:

--- foo.pyi	2026-04-11 13:21:51.522132+00:00
+++ foo.pyi	2026-04-11 13:23:18.497329+00:00
@@ -1,16 +1,19 @@
 def a(): ...
+
 class A: ...
 
 @deco
 class B: ...
+
 @deco
 class C: ...
 
 def d(): ...
 
 @deco
 class D: ...
 
 def e(): ...
+
 @deco
 class E: ...

which feels much more consistent.

The fix adds a _decorator_decorates_class() helper that walks the AST to check whether a decorator line decorates a classdef node, and uses it to insert a blank line in _maybe_empty_lines_for_class_or_def when appropriate.

Fixes #4256. The same bug was fixed in the Ruff formatter in June, in astral-sh/ruff#18888

Checklist - did you ...

  • Implement any code style changes under the --preview style, following the stability policy?
  • Add an entry in CHANGES.md if necessary?
  • Add / update tests if necessary?
  • Add new / update outdated documentation?

@AlexWaygood AlexWaygood changed the title In stub files, enforce a blank line between a function and a decorate… In stub files, enforce a blank line between a function and a decorated class definition Apr 11, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 11, 2026

diff-shades results comparing this PR (49f7333) to main (0eddb3d):

--preview style (View full diff):
╭─────────────────────── Summary ────────────────────────╮
│ 2 projects & 36 files changed / 60 changes [+60/-0]    │
│                                                        │
│ ... out of 2 911 008 lines, 13 690 files & 22 projects │
╰────────────────────────────────────────────────────────╯

Differences found.

--stable style: no changes


What is this? | Workflow run | diff-shades documentation

@AlexWaygood
Copy link
Copy Markdown
Contributor Author

The diff-shades preview changes all look like clear improvements to me

@AlexWaygood AlexWaygood marked this pull request as ready for review April 11, 2026 13:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Black removes blank lines in between a function and a decorated class in a stub file

2 participants