Skip to content

Commit

Permalink
Use the preferred quotes for literals in triple quoted f-strings
Browse files Browse the repository at this point in the history
  • Loading branch information
MichaReiser committed Oct 22, 2024
1 parent 469e3f7 commit 73f1d80
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 64 deletions.
27 changes: 18 additions & 9 deletions crates/ruff_python_formatter/src/string/normalize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,6 @@ impl<'a, 'src> StringNormalizer<'a, 'src> {
return QuoteStyle::Preserve;
}

if let FStringState::InsideExpressionElement(parent_context) =
self.context.f_string_state()
{
return QuoteStyle::from(
parent_context.f_string().flags().quote_style().opposite(),
);
}

// Per PEP 8, always prefer double quotes for triple-quoted strings.
// Except when using quote-style-preserve.
if string.flags().is_triple_quoted() {
Expand Down Expand Up @@ -115,6 +107,20 @@ impl<'a, 'src> StringNormalizer<'a, 'src> {
QuoteStyle::Double
}
} else {
// For f-strings prefer alternating the quotes unless it's a triple quoted string,
// then prefer using the preferred quotes.
if let FStringState::InsideExpressionElement(parent_context) =
self.context.f_string_state()
{
let parent_flags = parent_context.f_string().flags();

if !parent_flags.is_triple_quoted() {
return QuoteStyle::from(
parent_context.f_string().flags().quote_style().opposite(),
);
}
}

preferred_quote_style
}
}
Expand Down Expand Up @@ -275,7 +281,10 @@ impl QuoteMetadata {
StringLikePart::FString(fstring) => {
// TODO: Should we limit this behavior to Post 312?
if is_f_string_formatting_enabled(context) {
let mut literals = fstring.elements.iter().filter_map(FStringElement::as_literal);
let mut literals = fstring
.elements
.iter()
.filter_map(FStringElement::as_literal);

let Some(first) = literals.next() else {
return QuoteMetadata::from_str("", part.flags(), preferred_quote);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -902,7 +902,7 @@ log.info(f"""Skipping: {'a' == 'b'} {desc['ms_name']} {money=} {dte=} {pos_share
)

dict_with_lambda_values = {
@@ -524,69 +383,62 @@
@@ -524,65 +383,58 @@

# Complex string concatenations with a method call in the middle.
code = (
Expand Down Expand Up @@ -982,15 +982,17 @@ log.info(f"""Skipping: {'a' == 'b'} {desc['ms_name']} {money=} {dte=} {pos_share

log.info(
- f"""Skipping: {"a" == 'b'} {desc["ms_name"]} {money=} {dte=} {pos_share=} {desc["status"]} {desc["exposure_max"]}"""
+ f"""Skipping: {'a' == 'b'} {desc['ms_name']} {money=} {dte=} {pos_share=} {desc['status']} {desc['exposure_max']}"""
+ f"""Skipping: {"a" == "b"} {desc["ms_name"]} {money=} {dte=} {pos_share=} {desc["status"]} {desc["exposure_max"]}"""
)

log.info(
- f"""Skipping: {'a' == "b"=} {desc["ms_name"]} {money=} {dte=} {pos_share=} {desc["status"]} {desc["exposure_max"]}"""
+ f"""Skipping: {'a' == "b"=} {desc['ms_name']} {money=} {dte=} {pos_share=} {desc['status']} {desc['exposure_max']}"""
@@ -590,5 +442,5 @@
)

log.info(
- f"""Skipping: {'a' == 'b'} {desc['ms_name']} {money=} {dte=} {pos_share=} {desc['status']} {desc['exposure_max']}"""
+ f"""Skipping: {"a" == "b"} {desc["ms_name"]} {money=} {dte=} {pos_share=} {desc["status"]} {desc["exposure_max"]}"""
)
```

## Ruff Output
Expand Down Expand Up @@ -1432,15 +1434,15 @@ log.info(
)

log.info(
f"""Skipping: {'a' == 'b'} {desc['ms_name']} {money=} {dte=} {pos_share=} {desc['status']} {desc['exposure_max']}"""
f"""Skipping: {"a" == "b"} {desc["ms_name"]} {money=} {dte=} {pos_share=} {desc["status"]} {desc["exposure_max"]}"""
)

log.info(
f"""Skipping: {'a' == "b"=} {desc['ms_name']} {money=} {dte=} {pos_share=} {desc['status']} {desc['exposure_max']}"""
f"""Skipping: {'a' == "b"=} {desc["ms_name"]} {money=} {dte=} {pos_share=} {desc["status"]} {desc["exposure_max"]}"""
)

log.info(
f"""Skipping: {'a' == 'b'} {desc['ms_name']} {money=} {dte=} {pos_share=} {desc['status']} {desc['exposure_max']}"""
f"""Skipping: {"a" == "b"} {desc["ms_name"]} {money=} {dte=} {pos_share=} {desc["status"]} {desc["exposure_max"]}"""
)
```
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -399,9 +399,9 @@ result_f = (
)
# https://github.com/astral-sh/ruff/issues/6841
x = f"""a{''}b"""
x = f"""a{""}b"""
y = f'''c{1}d"""e'''
z = f"""a{''}b""" f'''c{1}d"""e'''
z = f"""a{""}b""" f'''c{1}d"""e'''
# F-String formatting test cases (Preview)
Expand Down Expand Up @@ -511,10 +511,10 @@ f"foo {'"bar"'}"
# Triple-quoted strings
# It's ok to use the same quote char for the inner string if it's single-quoted.
f"""test {'inner'}"""
f"""test {'inner'}"""
f"""test {"inner"}"""
f"""test {"inner"}"""
# But if the inner string is also triple-quoted then we should preserve the existing quotes.
f"""test {'''inner'''}"""
f"""test {"""inner"""}"""
# Magic trailing comma
#
Expand Down Expand Up @@ -616,10 +616,10 @@ x = f"""
# Here, the debug expression is in a nested f-string so we should start preserving
# whitespaces from that point onwards. This means we should format the outer f-string.
x = f"""{
'foo ' # comment 24
+ f'{ x =
"foo " # comment 24
+ f"{ x =
}' # comment 25
}" # comment 25
}
"""
Expand All @@ -641,19 +641,19 @@ if indent0:
if indent2:
foo = f"""hello world
hello {
f'aaaaaaa {
f"aaaaaaa {
[
"aaaaaaaaaaaaaaaaaaaaa",
"bbbbbbbbbbbbbbbbbbbbb",
"ccccccccccccccccccccc",
"ddddddddddddddddddddd",
'aaaaaaaaaaaaaaaaaaaaa',
'bbbbbbbbbbbbbbbbbbbbb',
'ccccccccccccccccccccc',
'ddddddddddddddddddddd',
]
} bbbbbbbb'
} bbbbbbbb"
+ [
'aaaaaaaaaaaaaaaaaaaaa',
'bbbbbbbbbbbbbbbbbbbbb',
'ccccccccccccccccccccc',
'ddddddddddddddddddddd',
"aaaaaaaaaaaaaaaaaaaaa",
"bbbbbbbbbbbbbbbbbbbbb",
"ccccccccccccccccccccc",
"ddddddddddddddddddddd",
]
} --------
"""
Expand Down Expand Up @@ -1022,18 +1022,6 @@ _ = (
" f()\n"
# XXX: The following line changes depending on whether the tests
# are run through the interactive interpreter or with -m
@@ -57,9 +57,9 @@
)
# https://github.com/astral-sh/ruff/issues/6841
-x = f"""a{""}b"""
+x = f"""a{''}b"""
y = f'''c{1}d"""e'''
-z = f"""a{""}b""" f'''c{1}d"""e'''
+z = f"""a{''}b""" f'''c{1}d"""e'''
# F-String formatting test cases (Preview)
@@ -67,64 +67,72 @@
x = f"{a}"
x = f"{
Expand Down Expand Up @@ -1144,7 +1132,7 @@ _ = (
}"
# Quotes
@@ -147,18 +159,18 @@
@@ -147,20 +159,20 @@
f'foo "bar" {x}'
f'foo "bar" {x}'
f"foo 'bar' {x}"
Expand All @@ -1161,12 +1149,15 @@ _ = (
# Triple-quoted strings
# It's ok to use the same quote char for the inner string if it's single-quoted.
f"""test {'inner'}"""
-f"""test {"inner"}"""
+f"""test {'inner'}"""
-f"""test {'inner'}"""
f"""test {"inner"}"""
+f"""test {"inner"}"""
# But if the inner string is also triple-quoted then we should preserve the existing quotes.
f"""test {'''inner'''}"""
-f"""test {'''inner'''}"""
+f"""test {"""inner"""}"""
# Magic trailing comma
#
@@ -171,63 +183,66 @@
f"aaaaaaa {['aaaaaaaaaaaaaaa', 'bbbbbbbbbbbbb', 'ccccccccccccccccc', 'ddddddddddddddd', 'eeeeeeeeeeeeee']} aaaaaaa"
Expand Down Expand Up @@ -1301,12 +1292,12 @@ _ = (
-x = f"""{"foo " + # comment 24
- f"{ x =
+x = f"""{
+ 'foo ' # comment 24
+ + f'{ x =
+ "foo " # comment 24
+ + f"{ x =
- }" # comment 25
- }
+ }' # comment 25
+ }" # comment 25
+}
"""
Expand Down Expand Up @@ -1341,19 +1332,19 @@ _ = (
- 'ddddddddddddddddddddd'
- ]
- } --------
+ f'aaaaaaa {
+ f"aaaaaaa {
+ [
+ "aaaaaaaaaaaaaaaaaaaaa",
+ "bbbbbbbbbbbbbbbbbbbbb",
+ "ccccccccccccccccccccc",
+ "ddddddddddddddddddddd",
+ 'aaaaaaaaaaaaaaaaaaaaa',
+ 'bbbbbbbbbbbbbbbbbbbbb',
+ 'ccccccccccccccccccccc',
+ 'ddddddddddddddddddddd',
+ ]
+ } bbbbbbbb'
+ } bbbbbbbb"
+ + [
+ 'aaaaaaaaaaaaaaaaaaaaa',
+ 'bbbbbbbbbbbbbbbbbbbbb',
+ 'ccccccccccccccccccccc',
+ 'ddddddddddddddddddddd',
+ "aaaaaaaaaaaaaaaaaaaaa",
+ "bbbbbbbbbbbbbbbbbbbbb",
+ "ccccccccccccccccccccc",
+ "ddddddddddddddddddddd",
+ ]
+ } --------
"""
Expand Down

0 comments on commit 73f1d80

Please sign in to comment.