parent
1abcffc818
commit
7b5a657285
@ -15,6 +15,8 @@
|
||||
of Black would incorrectly format the contents of certain unusual f-strings containing
|
||||
nested strings with the same quote type. Now, Black will crash on such strings until
|
||||
support for the new f-string syntax is implemented. (#4270)
|
||||
- Fixed a bug where line-ranges exceeding the last code line would not work as expected
|
||||
(#4273)
|
||||
|
||||
### Preview style
|
||||
|
||||
|
@ -84,7 +84,12 @@
|
||||
parse_ast,
|
||||
stringify_ast,
|
||||
)
|
||||
from black.ranges import adjusted_lines, convert_unchanged_lines, parse_line_ranges
|
||||
from black.ranges import (
|
||||
adjusted_lines,
|
||||
convert_unchanged_lines,
|
||||
parse_line_ranges,
|
||||
sanitized_lines,
|
||||
)
|
||||
from black.report import Changed, NothingChanged, Report
|
||||
from black.trans import iter_fexpr_spans
|
||||
from blib2to3.pgen2 import token
|
||||
@ -1220,6 +1225,10 @@ def f(
|
||||
hey
|
||||
|
||||
"""
|
||||
if lines:
|
||||
lines = sanitized_lines(lines, src_contents)
|
||||
if not lines:
|
||||
return src_contents # Nothing to format
|
||||
dst_contents = _format_str_once(src_contents, mode=mode, lines=lines)
|
||||
# Forced second pass to work around optional trailing commas (becoming
|
||||
# forced trailing commas on pass 2) interacting differently with optional
|
||||
|
@ -45,6 +45,34 @@ def is_valid_line_range(lines: Tuple[int, int]) -> bool:
|
||||
return not lines or lines[0] <= lines[1]
|
||||
|
||||
|
||||
def sanitized_lines(
|
||||
lines: Collection[Tuple[int, int]], src_contents: str
|
||||
) -> Collection[Tuple[int, int]]:
|
||||
"""Returns the valid line ranges for the given source.
|
||||
|
||||
This removes ranges that are entirely outside the valid lines.
|
||||
|
||||
Other ranges are normalized so that the start values are at least 1 and the
|
||||
end values are at most the (1-based) index of the last source line.
|
||||
"""
|
||||
if not src_contents:
|
||||
return []
|
||||
good_lines = []
|
||||
src_line_count = src_contents.count("\n")
|
||||
if not src_contents.endswith("\n"):
|
||||
src_line_count += 1
|
||||
for start, end in lines:
|
||||
if start > src_line_count:
|
||||
continue
|
||||
# line-ranges are 1-based
|
||||
start = max(start, 1)
|
||||
if end < start:
|
||||
continue
|
||||
end = min(end, src_line_count)
|
||||
good_lines.append((start, end))
|
||||
return good_lines
|
||||
|
||||
|
||||
def adjusted_lines(
|
||||
lines: Collection[Tuple[int, int]],
|
||||
original_source: str,
|
||||
|
36
tests/data/cases/line_ranges_exceeding_end.py
Normal file
36
tests/data/cases/line_ranges_exceeding_end.py
Normal file
@ -0,0 +1,36 @@
|
||||
# flags: --line-ranges=6-1000
|
||||
# NOTE: If you need to modify this file, pay special attention to the --line-ranges=
|
||||
# flag above as it's formatting specifically these lines.
|
||||
def foo1(parameter_1, parameter_2, parameter_3, parameter_4, parameter_5, parameter_6, parameter_7): pass
|
||||
def foo2(parameter_1, parameter_2, parameter_3, parameter_4, parameter_5, parameter_6, parameter_7): pass
|
||||
def foo3(parameter_1, parameter_2, parameter_3, parameter_4, parameter_5, parameter_6, parameter_7): pass
|
||||
def foo4(parameter_1, parameter_2, parameter_3, parameter_4, parameter_5, parameter_6, parameter_7): pass
|
||||
|
||||
# output
|
||||
# flags: --line-ranges=6-1000
|
||||
# NOTE: If you need to modify this file, pay special attention to the --line-ranges=
|
||||
# flag above as it's formatting specifically these lines.
|
||||
def foo1(parameter_1, parameter_2, parameter_3, parameter_4, parameter_5, parameter_6, parameter_7): pass
|
||||
def foo2(parameter_1, parameter_2, parameter_3, parameter_4, parameter_5, parameter_6, parameter_7): pass
|
||||
def foo3(
|
||||
parameter_1,
|
||||
parameter_2,
|
||||
parameter_3,
|
||||
parameter_4,
|
||||
parameter_5,
|
||||
parameter_6,
|
||||
parameter_7,
|
||||
):
|
||||
pass
|
||||
|
||||
|
||||
def foo4(
|
||||
parameter_1,
|
||||
parameter_2,
|
||||
parameter_3,
|
||||
parameter_4,
|
||||
parameter_5,
|
||||
parameter_6,
|
||||
parameter_7,
|
||||
):
|
||||
pass
|
7
tests/data/cases/line_ranges_outside_source.py
Normal file
7
tests/data/cases/line_ranges_outside_source.py
Normal file
@ -0,0 +1,7 @@
|
||||
# flags: --line-ranges=5000-6000
|
||||
# NOTE: If you need to modify this file, pay special attention to the --line-ranges=
|
||||
# flag above as it's formatting specifically these lines, in this case none.
|
||||
def foo1(parameter_1, parameter_2, parameter_3, parameter_4, parameter_5, parameter_6, parameter_7): pass
|
||||
def foo2(parameter_1, parameter_2, parameter_3, parameter_4, parameter_5, parameter_6, parameter_7): pass
|
||||
def foo3(parameter_1, parameter_2, parameter_3, parameter_4, parameter_5, parameter_6, parameter_7): pass
|
||||
def foo4(parameter_1, parameter_2, parameter_3, parameter_4, parameter_5, parameter_6, parameter_7): pass
|
@ -4,7 +4,7 @@
|
||||
|
||||
import pytest
|
||||
|
||||
from black.ranges import adjusted_lines
|
||||
from black.ranges import adjusted_lines, sanitized_lines
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
@ -183,3 +183,67 @@ def test_diffs(lines: List[Tuple[int, int]], adjusted: List[Tuple[int, int]]) ->
|
||||
12. # last line changed
|
||||
"""
|
||||
assert adjusted == adjusted_lines(lines, original_source, modified_source)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"lines,sanitized",
|
||||
[
|
||||
(
|
||||
[(1, 4)],
|
||||
[(1, 4)],
|
||||
),
|
||||
(
|
||||
[(2, 3)],
|
||||
[(2, 3)],
|
||||
),
|
||||
(
|
||||
[(2, 10)],
|
||||
[(2, 4)],
|
||||
),
|
||||
(
|
||||
[(0, 3)],
|
||||
[(1, 3)],
|
||||
),
|
||||
(
|
||||
[(0, 10)],
|
||||
[(1, 4)],
|
||||
),
|
||||
(
|
||||
[(-2, 3)],
|
||||
[(1, 3)],
|
||||
),
|
||||
(
|
||||
[(0, 0)],
|
||||
[],
|
||||
),
|
||||
(
|
||||
[(-2, -1)],
|
||||
[],
|
||||
),
|
||||
(
|
||||
[(-1, 0)],
|
||||
[],
|
||||
),
|
||||
(
|
||||
[(3, 1), (1, 3), (5, 6)],
|
||||
[(1, 3)],
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_sanitize(
|
||||
lines: List[Tuple[int, int]], sanitized: List[Tuple[int, int]]
|
||||
) -> None:
|
||||
source = """\
|
||||
1. import re
|
||||
2. def func(arg1,
|
||||
3. arg2, arg3):
|
||||
4. pass
|
||||
"""
|
||||
assert sanitized == sanitized_lines(lines, source)
|
||||
|
||||
source_no_trailing_nl = """\
|
||||
1. import re
|
||||
2. def func(arg1,
|
||||
3. arg2, arg3):
|
||||
4. pass"""
|
||||
assert sanitized == sanitized_lines(lines, source_no_trailing_nl)
|
||||
|
Loading…
Reference in New Issue
Block a user