Do not add an extra blank line to an import line that has fmt disabled (#3610)
This commit is contained in:
parent
fc6cea0f0e
commit
268dcb677c
@ -10,6 +10,9 @@
|
|||||||
|
|
||||||
<!-- Changes that affect Black's stable style -->
|
<!-- Changes that affect Black's stable style -->
|
||||||
|
|
||||||
|
- Import lines with `# fmt: skip` and `# fmt: off` no longer have an extra blank line
|
||||||
|
added when they are right after another import line (#3610)
|
||||||
|
|
||||||
### Preview style
|
### Preview style
|
||||||
|
|
||||||
<!-- Changes that affect Black's preview style -->
|
<!-- Changes that affect Black's preview style -->
|
||||||
|
@ -203,6 +203,7 @@ def convert_one_fmt_off_pair(node: Node) -> bool:
|
|||||||
STANDALONE_COMMENT,
|
STANDALONE_COMMENT,
|
||||||
hidden_value,
|
hidden_value,
|
||||||
prefix=standalone_comment_prefix,
|
prefix=standalone_comment_prefix,
|
||||||
|
fmt_pass_converted_first_leaf=first_leaf_of(first),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
return True
|
return True
|
||||||
|
@ -195,6 +195,26 @@ def opens_block(self) -> bool:
|
|||||||
return False
|
return False
|
||||||
return self.leaves[-1].type == token.COLON
|
return self.leaves[-1].type == token.COLON
|
||||||
|
|
||||||
|
def is_fmt_pass_converted(
|
||||||
|
self, *, first_leaf_matches: Optional[Callable[[Leaf], bool]] = None
|
||||||
|
) -> bool:
|
||||||
|
"""Is this line converted from fmt off/skip code?
|
||||||
|
|
||||||
|
If first_leaf_matches is not None, it only returns True if the first
|
||||||
|
leaf of converted code matches.
|
||||||
|
"""
|
||||||
|
if len(self.leaves) != 1:
|
||||||
|
return False
|
||||||
|
leaf = self.leaves[0]
|
||||||
|
if (
|
||||||
|
leaf.type != STANDALONE_COMMENT
|
||||||
|
or leaf.fmt_pass_converted_first_leaf is None
|
||||||
|
):
|
||||||
|
return False
|
||||||
|
return first_leaf_matches is None or first_leaf_matches(
|
||||||
|
leaf.fmt_pass_converted_first_leaf
|
||||||
|
)
|
||||||
|
|
||||||
def contains_standalone_comments(self, depth_limit: int = sys.maxsize) -> bool:
|
def contains_standalone_comments(self, depth_limit: int = sys.maxsize) -> bool:
|
||||||
"""If so, needs to be split before emitting."""
|
"""If so, needs to be split before emitting."""
|
||||||
for leaf in self.leaves:
|
for leaf in self.leaves:
|
||||||
@ -597,6 +617,7 @@ def _maybe_empty_lines(self, current_line: Line) -> Tuple[int, int]:
|
|||||||
self.previous_line
|
self.previous_line
|
||||||
and self.previous_line.is_import
|
and self.previous_line.is_import
|
||||||
and not current_line.is_import
|
and not current_line.is_import
|
||||||
|
and not current_line.is_fmt_pass_converted(first_leaf_matches=is_import)
|
||||||
and depth == self.previous_line.depth
|
and depth == self.previous_line.depth
|
||||||
):
|
):
|
||||||
return (before or 1), 0
|
return (before or 1), 0
|
||||||
|
@ -392,6 +392,10 @@ class Leaf(Base):
|
|||||||
_prefix = "" # Whitespace and comments preceding this token in the input
|
_prefix = "" # Whitespace and comments preceding this token in the input
|
||||||
lineno: int = 0 # Line where this token starts in the input
|
lineno: int = 0 # Line where this token starts in the input
|
||||||
column: int = 0 # Column where this token starts in the input
|
column: int = 0 # Column where this token starts in the input
|
||||||
|
# If not None, this Leaf is created by converting a block of fmt off/skip
|
||||||
|
# code, and `fmt_pass_converted_first_leaf` points to the first Leaf in the
|
||||||
|
# converted code.
|
||||||
|
fmt_pass_converted_first_leaf: Optional["Leaf"] = None
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
@ -401,6 +405,7 @@ def __init__(
|
|||||||
prefix: Optional[Text] = None,
|
prefix: Optional[Text] = None,
|
||||||
fixers_applied: List[Any] = [],
|
fixers_applied: List[Any] = [],
|
||||||
opening_bracket: Optional["Leaf"] = None,
|
opening_bracket: Optional["Leaf"] = None,
|
||||||
|
fmt_pass_converted_first_leaf: Optional["Leaf"] = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""
|
"""
|
||||||
Initializer.
|
Initializer.
|
||||||
@ -419,6 +424,7 @@ def __init__(
|
|||||||
self.fixers_applied: Optional[List[Any]] = fixers_applied[:]
|
self.fixers_applied: Optional[List[Any]] = fixers_applied[:]
|
||||||
self.children = []
|
self.children = []
|
||||||
self.opening_bracket = opening_bracket
|
self.opening_bracket = opening_bracket
|
||||||
|
self.fmt_pass_converted_first_leaf = fmt_pass_converted_first_leaf
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
"""Return a canonical string representation."""
|
"""Return a canonical string representation."""
|
||||||
|
@ -195,7 +195,6 @@ def single_literal_yapf_disable():
|
|||||||
from third_party import X, Y, Z
|
from third_party import X, Y, Z
|
||||||
|
|
||||||
from library import some_connection, some_decorator
|
from library import some_connection, some_decorator
|
||||||
|
|
||||||
# fmt: off
|
# fmt: off
|
||||||
from third_party import (X,
|
from third_party import (X,
|
||||||
Y, Z)
|
Y, Z)
|
||||||
|
19
tests/data/simple_cases/fmtpass_imports.py
Normal file
19
tests/data/simple_cases/fmtpass_imports.py
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
# Regression test for https://github.com/psf/black/issues/3438
|
||||||
|
|
||||||
|
import ast
|
||||||
|
import collections # fmt: skip
|
||||||
|
import dataclasses
|
||||||
|
# fmt: off
|
||||||
|
import os
|
||||||
|
# fmt: on
|
||||||
|
import pathlib
|
||||||
|
|
||||||
|
import re # fmt: skip
|
||||||
|
import secrets
|
||||||
|
|
||||||
|
# fmt: off
|
||||||
|
import sys
|
||||||
|
# fmt: on
|
||||||
|
|
||||||
|
import tempfile
|
||||||
|
import zoneinfo
|
Loading…
Reference in New Issue
Block a user