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
<!-- 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

View File

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

View File

@ -1,7 +1,7 @@
import re
from dataclasses import dataclass
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.nodes import (
@ -161,14 +161,18 @@ def make_comment(content: str) -> str:
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."""
try_again = True
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.
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
)
hidden_value = "".join(str(n) for n in ignored_nodes)
comment_lineno = leaf.lineno - comment.newlines
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
if _contains_fmt_skip_comment(comment.value, mode):
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=
# flag above as it's formatting specifically these lines.
@ -11,9 +11,19 @@ class MyClass:
def method():
print ( "str" )
@decor(
a=1,
# fmt: off
b=(2, 3),
# fmt: on
)
def func():
pass
# 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=
# flag above as it's formatting specifically these lines.
@ -25,3 +35,13 @@ class MyClass:
# fmt: on
def method():
print("str")
@decor(
a=1,
# fmt: off
b=(2, 3),
# fmt: on
)
def func():
pass