@@ -711,6 +711,10 @@ def _format_block_header(node: Node, fmt: Formatter) -> list[Node]:
711711def _needs_blank_line_before (child : Node , indent : int , line_length : int ) -> bool :
712712 """Check if a blank separator line should precede this child node."""
713713 prev = child .prev_named_sibling
714+ # Empty comments preceding this child will be dropped — look past them
715+ # so we evaluate against the real prior content.
716+ while prev and prev .type == "comment" and _is_empty_comment (prev ):
717+ prev = prev .prev_named_sibling
714718 if not prev :
715719 return False
716720
@@ -743,12 +747,6 @@ def _needs_blank_line_before(child: Node, indent: int, line_length: int) -> bool
743747 if child .type == "comment" :
744748 if _is_empty_comment (child ):
745749 return False
746- # Empty comments preceding this one will be dropped — look past them
747- # so we treat the comment as following the real prior content.
748- while prev and prev .type == "comment" and _is_empty_comment (prev ):
749- prev = prev .prev_named_sibling
750- if prev is None :
751- return False
752750 # Top-level comment after a complete block — visually separates them
753751 if prev .type in BLOCK_TYPES :
754752 return True
@@ -783,12 +781,27 @@ def _needs_blank_line_before(child: Node, indent: int, line_length: int) -> bool
783781
784782
785783def _is_empty_comment (node : Node ) -> bool :
786- """Check if a bare '#' comment should be dropped (not between other comments)."""
784+ """Check if a bare '#' comment should be dropped.
785+
786+ A run of bare '#' between two non-empty comments collapses to a
787+ single '#' — the first in the run is kept, the rest are dropped.
788+ Bare '#' not flanked by real comments is always dropped."""
787789 if text (node ).strip () != "#" :
788790 return False
789791 prev = node .prev_named_sibling
792+ # Not the first in a run of '#' — a kept '#' precedes us, drop.
793+ if prev and prev .type == "comment" and text (prev ).strip () == "#" :
794+ return True
795+ # First in a run — kept only if a non-empty comment sits on each side
796+ # (forward search walks past the rest of the run to find one).
797+ if not (prev and prev .type == "comment" ):
798+ return True
790799 nxt = node .next_named_sibling
791- return not (prev and prev .type == "comment" and nxt and nxt .type == "comment" )
800+ while nxt and nxt .type == "comment" and text (nxt ).strip () == "#" :
801+ nxt = nxt .next_named_sibling
802+ if not (nxt and nxt .type == "comment" ):
803+ return True
804+ return False
792805
793806
794807def _skip_comments (sibling : Node | None , direction : str = "next" ) -> Node | None :
0 commit comments