Prevent f-string merge quote changes with nested quotes (#4498)
This commit is contained in:
parent
e54f86bae4
commit
3fab5ade71
@ -17,6 +17,8 @@
|
|||||||
|
|
||||||
<!-- Changes that affect Black's preview style -->
|
<!-- Changes that affect Black's preview style -->
|
||||||
|
|
||||||
|
- Fix/remove string merging changing f-string quotes on f-strings with internal quotes
|
||||||
|
(#4498)
|
||||||
- Remove parentheses around sole list items (#4312)
|
- Remove parentheses around sole list items (#4312)
|
||||||
- Collapse multiple empty lines after an import into one (#4489)
|
- Collapse multiple empty lines after an import into one (#4489)
|
||||||
|
|
||||||
|
@ -137,10 +137,11 @@ foo(
|
|||||||
|
|
||||||
_Black_ will split long string literals and merge short ones. Parentheses are used where
|
_Black_ will split long string literals and merge short ones. Parentheses are used where
|
||||||
appropriate. When split, parts of f-strings that don't need formatting are converted to
|
appropriate. When split, parts of f-strings that don't need formatting are converted to
|
||||||
plain strings. User-made splits are respected when they do not exceed the line length
|
plain strings. f-strings will not be merged if they contain internal quotes and it would
|
||||||
limit. Line continuation backslashes are converted into parenthesized strings.
|
change their quotation mark style. User-made splits are respected when they do not
|
||||||
Unnecessary parentheses are stripped. The stability and status of this feature is
|
exceed the line length limit. Line continuation backslashes are converted into
|
||||||
tracked in [this issue](https://github.com/psf/black/issues/2188).
|
parenthesized strings. Unnecessary parentheses are stripped. The stability and status of
|
||||||
|
this feature istracked in [this issue](https://github.com/psf/black/issues/2188).
|
||||||
|
|
||||||
(labels/wrap-long-dict-values)=
|
(labels/wrap-long-dict-values)=
|
||||||
|
|
||||||
|
@ -794,6 +794,8 @@ def _validate_msg(line: Line, string_idx: int) -> TResult[None]:
|
|||||||
- The set of all string prefixes in the string group is of
|
- The set of all string prefixes in the string group is of
|
||||||
length greater than one and is not equal to {"", "f"}.
|
length greater than one and is not equal to {"", "f"}.
|
||||||
- The string group consists of raw strings.
|
- The string group consists of raw strings.
|
||||||
|
- The string group would merge f-strings with different quote types
|
||||||
|
and internal quotes.
|
||||||
- The string group is stringified type annotations. We don't want to
|
- The string group is stringified type annotations. We don't want to
|
||||||
process stringified type annotations since pyright doesn't support
|
process stringified type annotations since pyright doesn't support
|
||||||
them spanning multiple string values. (NOTE: mypy, pytype, pyre do
|
them spanning multiple string values. (NOTE: mypy, pytype, pyre do
|
||||||
@ -820,6 +822,8 @@ def _validate_msg(line: Line, string_idx: int) -> TResult[None]:
|
|||||||
|
|
||||||
i += inc
|
i += inc
|
||||||
|
|
||||||
|
QUOTE = line.leaves[string_idx].value[-1]
|
||||||
|
|
||||||
num_of_inline_string_comments = 0
|
num_of_inline_string_comments = 0
|
||||||
set_of_prefixes = set()
|
set_of_prefixes = set()
|
||||||
num_of_strings = 0
|
num_of_strings = 0
|
||||||
@ -842,6 +846,19 @@ def _validate_msg(line: Line, string_idx: int) -> TResult[None]:
|
|||||||
|
|
||||||
set_of_prefixes.add(prefix)
|
set_of_prefixes.add(prefix)
|
||||||
|
|
||||||
|
if (
|
||||||
|
"f" in prefix
|
||||||
|
and leaf.value[-1] != QUOTE
|
||||||
|
and (
|
||||||
|
"'" in leaf.value[len(prefix) + 1 : -1]
|
||||||
|
or '"' in leaf.value[len(prefix) + 1 : -1]
|
||||||
|
)
|
||||||
|
):
|
||||||
|
return TErr(
|
||||||
|
"StringMerger does NOT merge f-strings with different quote types"
|
||||||
|
"and internal quotes."
|
||||||
|
)
|
||||||
|
|
||||||
if id(leaf) in line.comments:
|
if id(leaf) in line.comments:
|
||||||
num_of_inline_string_comments += 1
|
num_of_inline_string_comments += 1
|
||||||
if contains_pragma_comment(line.comments[id(leaf)]):
|
if contains_pragma_comment(line.comments[id(leaf)]):
|
||||||
|
2
tests/data/cases/preview_fstring.py
Normal file
2
tests/data/cases/preview_fstring.py
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
# flags: --unstable
|
||||||
|
f"{''=}" f'{""=}'
|
@ -882,7 +882,7 @@ def foo():
|
|||||||
|
|
||||||
log.info(
|
log.info(
|
||||||
"Skipping:"
|
"Skipping:"
|
||||||
f" {desc['db_id']} {foo('bar',x=123)} {'foo' != 'bar'} {(x := 'abc=')} {pos_share=} {desc['status']} {desc['exposure_max']}"
|
f' {desc["db_id"]} {foo("bar",x=123)} {"foo" != "bar"} {(x := "abc=")} {pos_share=} {desc["status"]} {desc["exposure_max"]}'
|
||||||
)
|
)
|
||||||
|
|
||||||
log.info(
|
log.info(
|
||||||
@ -902,7 +902,7 @@ def foo():
|
|||||||
|
|
||||||
log.info(
|
log.info(
|
||||||
"Skipping:"
|
"Skipping:"
|
||||||
f" {'a' == 'b' == 'c' == 'd'} {desc['ms_name']} {money=} {dte=} {pos_share=} {desc['status']} {desc['exposure_max']}"
|
f' {"a" == "b" == "c" == "d"} {desc["ms_name"]} {money=} {dte=} {pos_share=} {desc["status"]} {desc["exposure_max"]}'
|
||||||
)
|
)
|
||||||
|
|
||||||
log.info(
|
log.info(
|
||||||
|
@ -552,6 +552,7 @@ async def foo(self):
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Regression test for https://github.com/psf/black/issues/3506.
|
# Regression test for https://github.com/psf/black/issues/3506.
|
||||||
|
# Regressed again by https://github.com/psf/black/pull/4498
|
||||||
s = (
|
s = (
|
||||||
"With single quote: ' "
|
"With single quote: ' "
|
||||||
f" {my_dict['foo']}"
|
f" {my_dict['foo']}"
|
||||||
@ -1239,9 +1240,15 @@ async def foo(self):
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Regression test for https://github.com/psf/black/issues/3506.
|
# Regression test for https://github.com/psf/black/issues/3506.
|
||||||
s = f"With single quote: ' {my_dict['foo']} With double quote: \" {my_dict['bar']}"
|
# Regressed again by https://github.com/psf/black/pull/4498
|
||||||
|
s = (
|
||||||
|
"With single quote: ' "
|
||||||
|
f" {my_dict['foo']}"
|
||||||
|
' With double quote: " '
|
||||||
|
f' {my_dict["bar"]}'
|
||||||
|
)
|
||||||
|
|
||||||
s = (
|
s = (
|
||||||
"Lorem Ipsum is simply dummy text of the printing and typesetting"
|
"Lorem Ipsum is simply dummy text of the printing and typesetting"
|
||||||
f" industry:'{my_dict['foo']}'"
|
f' industry:\'{my_dict["foo"]}\''
|
||||||
)
|
)
|
Loading…
Reference in New Issue
Block a user