Fix: --line-ranges dedents a # fmt: off in the middle of a decorator (#4084)

Fixes #4068
This commit is contained in:
Riyazuddin Khan 2023-12-04 23:40:03 +05:30 committed by GitHub
parent 66ec056e39
commit 3416b2c82d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 44 additions and 8 deletions

View File

@ -8,7 +8,8 @@
### Stable style ### Stable style
<!-- Changes that affect Black's stable style --> - Fix bug where `# fmt: off` automatically dedents when used with the `--line-ranges`
option, even when it is not within the specified line range. (#4084)
### Preview style ### Preview style

View File

@ -1180,7 +1180,7 @@ def _format_str_once(
for feature in {Feature.PARENTHESIZED_CONTEXT_MANAGERS} for feature in {Feature.PARENTHESIZED_CONTEXT_MANAGERS}
if supports_feature(versions, feature) if supports_feature(versions, feature)
} }
normalize_fmt_off(src_node, mode) normalize_fmt_off(src_node, mode, lines)
if lines: if lines:
# This should be called after normalize_fmt_off. # This should be called after normalize_fmt_off.
convert_unchanged_lines(src_node, lines) convert_unchanged_lines(src_node, lines)

View File

@ -1,7 +1,7 @@
import re import re
from dataclasses import dataclass from dataclasses import dataclass
from functools import lru_cache from functools import lru_cache
from typing import Final, Iterator, List, Optional, Union from typing import Collection, Final, Iterator, List, Optional, Tuple, Union
from black.mode import Mode, Preview from black.mode import Mode, Preview
from black.nodes import ( from black.nodes import (
@ -161,14 +161,18 @@ def make_comment(content: str) -> str:
return "#" + content return "#" + content
def normalize_fmt_off(node: Node, mode: Mode) -> None: def normalize_fmt_off(
node: Node, mode: Mode, lines: Collection[Tuple[int, int]]
) -> None:
"""Convert content between `# fmt: off`/`# fmt: on` into standalone comments.""" """Convert content between `# fmt: off`/`# fmt: on` into standalone comments."""
try_again = True try_again = True
while try_again: while try_again:
try_again = convert_one_fmt_off_pair(node, mode) try_again = convert_one_fmt_off_pair(node, mode, lines)
def convert_one_fmt_off_pair(node: Node, mode: Mode) -> bool: def convert_one_fmt_off_pair(
node: Node, mode: Mode, lines: Collection[Tuple[int, int]]
) -> bool:
"""Convert content of a single `# fmt: off`/`# fmt: on` into a standalone comment. """Convert content of a single `# fmt: off`/`# fmt: on` into a standalone comment.
Returns True if a pair was converted. Returns True if a pair was converted.
@ -213,7 +217,18 @@ def convert_one_fmt_off_pair(node: Node, mode: Mode) -> bool:
prefix[:previous_consumed] + "\n" * comment.newlines prefix[:previous_consumed] + "\n" * comment.newlines
) )
hidden_value = "".join(str(n) for n in ignored_nodes) hidden_value = "".join(str(n) for n in ignored_nodes)
comment_lineno = leaf.lineno - comment.newlines
if comment.value in FMT_OFF: if comment.value in FMT_OFF:
fmt_off_prefix = ""
if len(lines) > 0 and not any(
comment_lineno >= line[0] and comment_lineno <= line[1]
for line in lines
):
# keeping indentation of comment by preserving original whitespaces.
fmt_off_prefix = prefix.split(comment.value)[0]
if "\n" in fmt_off_prefix:
fmt_off_prefix = fmt_off_prefix.split("\n")[-1]
standalone_comment_prefix += fmt_off_prefix
hidden_value = comment.value + "\n" + hidden_value hidden_value = comment.value + "\n" + hidden_value
if _contains_fmt_skip_comment(comment.value, mode): if _contains_fmt_skip_comment(comment.value, mode):
hidden_value += " " + comment.value hidden_value += " " + comment.value

View File

@ -1,4 +1,4 @@
# flags: --line-ranges=12-12 # flags: --line-ranges=12-12 --line-ranges=21-21
# NOTE: If you need to modify this file, pay special attention to the --line-ranges= # NOTE: If you need to modify this file, pay special attention to the --line-ranges=
# flag above as it's formatting specifically these lines. # flag above as it's formatting specifically these lines.
@ -11,9 +11,19 @@ class MyClass:
def method(): def method():
print ( "str" ) print ( "str" )
@decor(
a=1,
# fmt: off
b=(2, 3),
# fmt: on
)
def func():
pass
# output # output
# flags: --line-ranges=12-12 # flags: --line-ranges=12-12 --line-ranges=21-21
# NOTE: If you need to modify this file, pay special attention to the --line-ranges= # NOTE: If you need to modify this file, pay special attention to the --line-ranges=
# flag above as it's formatting specifically these lines. # flag above as it's formatting specifically these lines.
@ -25,3 +35,13 @@ class MyClass:
# fmt: on # fmt: on
def method(): def method():
print("str") print("str")
@decor(
a=1,
# fmt: off
b=(2, 3),
# fmt: on
)
def func():
pass