From a5196e6f1f450e4c8da0e514e01873a0cc1e1a3c Mon Sep 17 00:00:00 2001 From: cobalt <61329810+RedGuy12@users.noreply.github.com> Date: Thu, 25 Jan 2024 03:31:49 -0600 Subject: [PATCH] fix: Don't normalize whitespace before fmt:skip comments (#4146) Signed-off-by: RedGuy12 --- CHANGES.md | 1 + src/black/comments.py | 14 +++++++++++--- src/black/mode.py | 1 + tests/data/cases/fmtskip9.py | 9 +++++++++ 4 files changed, 22 insertions(+), 3 deletions(-) create mode 100644 tests/data/cases/fmtskip9.py diff --git a/CHANGES.md b/CHANGES.md index 0e2974d706e..2fe14cd5246 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -56,6 +56,7 @@ release: - Format module docstrings the same as class and function docstrings (#4095) - Fix crash when using a walrus in a dictionary (#4155) - Fix unnecessary parentheses when wrapping long dicts (#4135) +- Stop normalizing spaces before `# fmt: skip` comments (#4146) ### Configuration diff --git a/src/black/comments.py b/src/black/comments.py index 910e1b760f0..ea54e2468c9 100644 --- a/src/black/comments.py +++ b/src/black/comments.py @@ -3,7 +3,7 @@ from functools import lru_cache from typing import Collection, Final, Iterator, List, Optional, Tuple, Union -from black.mode import Mode +from black.mode import Mode, Preview from black.nodes import ( CLOSING_BRACKETS, STANDALONE_COMMENT, @@ -46,6 +46,7 @@ class ProtoComment: newlines: int # how many newlines before the comment consumed: int # how many characters of the original leaf's prefix did we consume form_feed: bool # is there a form feed before the comment + leading_whitespace: str # leading whitespace before the comment, if any def generate_comments(leaf: LN) -> Iterator[Leaf]: @@ -88,7 +89,9 @@ def list_comments(prefix: str, *, is_endmarker: bool) -> List[ProtoComment]: form_feed = False for index, full_line in enumerate(re.split("\r?\n", prefix)): consumed += len(full_line) + 1 # adding the length of the split '\n' - line = full_line.lstrip() + match = re.match(r"^(\s*)(\S.*|)$", full_line) + assert match + whitespace, line = match.groups() if not line: nlines += 1 if "\f" in full_line: @@ -113,6 +116,7 @@ def list_comments(prefix: str, *, is_endmarker: bool) -> List[ProtoComment]: newlines=nlines, consumed=consumed, form_feed=form_feed, + leading_whitespace=whitespace, ) ) form_feed = False @@ -230,7 +234,11 @@ def convert_one_fmt_off_pair( standalone_comment_prefix += fmt_off_prefix hidden_value = comment.value + "\n" + hidden_value if _contains_fmt_skip_comment(comment.value, mode): - hidden_value += " " + comment.value + hidden_value += ( + comment.leading_whitespace + if Preview.no_normalize_fmt_skip_whitespace in mode + else " " + ) + comment.value if hidden_value.endswith("\n"): # That happens when one of the `ignored_nodes` ended with a NEWLINE # leaf (possibly followed by a DEDENT). diff --git a/src/black/mode.py b/src/black/mode.py index 1b97f3508ee..a1519f17bcc 100644 --- a/src/black/mode.py +++ b/src/black/mode.py @@ -174,6 +174,7 @@ class Preview(Enum): string_processing = auto() hug_parens_with_braces_and_square_brackets = auto() unify_docstring_detection = auto() + no_normalize_fmt_skip_whitespace = auto() wrap_long_dict_values_in_parens = auto() multiline_string_handling = auto() diff --git a/tests/data/cases/fmtskip9.py b/tests/data/cases/fmtskip9.py new file mode 100644 index 00000000000..30085bdd973 --- /dev/null +++ b/tests/data/cases/fmtskip9.py @@ -0,0 +1,9 @@ +# flags: --preview +print () # fmt: skip +print () # fmt:skip + + +# output + +print () # fmt: skip +print () # fmt:skip