Fix f-string formatting in assignment statement (#14454)

## Summary

fixes: #13813

This PR fixes a bug in the formatting assignment statement when the
value is an f-string.

This is resolved by using custom best fit layouts if the f-string is (a)
not already a flat f-string (thus, cannot be multiline) and (b) is not a
multiline string (thus, cannot be flattened). So, it is used in cases
like the following:
```py
aaaaaaaaaaaaaaaaaa = f"testeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee{
    expression}moreeeeeeeeeeeeeeeee"
```
Which is (a) `FStringLayout::Multiline` and (b) not a multiline.

There are various other examples in the PR diff along with additional
explanation and context as code comments.

## Test Plan

Add multiple test cases for various scenarios.
This commit is contained in:
Dhruv Manilawala
2024-11-26 15:07:18 +05:30
committed by GitHub
parent e4cefd9bf9
commit f3dac27e9a
15 changed files with 2184 additions and 74 deletions

View File

@@ -154,7 +154,7 @@ impl<'a> FormatImplicitConcatenatedStringFlat<'a> {
}
// Multiline strings can never fit on a single line.
if !string.is_fstring() && string.is_multiline(context.source()) {
if string.is_multiline(context) {
return None;
}
@@ -187,25 +187,6 @@ impl<'a> FormatImplicitConcatenatedStringFlat<'a> {
}
if let StringLikePart::FString(fstring) = part {
if fstring.elements.iter().any(|element| match element {
// Same as for other literals. Multiline literals can't fit on a single line.
FStringElement::Literal(literal) => {
context.source().contains_line_break(literal.range())
}
FStringElement::Expression(expression) => {
if is_f_string_formatting_enabled(context) {
// Expressions containing comments can't be joined.
context.comments().contains_comments(expression.into())
} else {
// Multiline f-string expressions can't be joined if the f-string formatting is disabled because
// the string gets inserted in verbatim preserving the newlines.
context.source().contains_line_break(expression.range())
}
}
}) {
return None;
}
if context.options().target_version().supports_pep_701() {
if is_fstring_with_quoted_format_spec_and_debug(fstring, context) {
if preserve_quotes_requirement