(&self, context: &PyFormatContext)
| 85 | |
| 86 | impl StringLikeExtensions for ast::StringLike<'_> { |
| 87 | fn is_multiline(&self, context: &PyFormatContext) -> bool { |
| 88 | // Helper for f-string and t-string parts |
| 89 | fn contains_line_break_or_comments( |
| 90 | elements: &ast::InterpolatedStringElements, |
| 91 | context: &PyFormatContext, |
| 92 | triple_quotes: TripleQuotes, |
| 93 | ) -> bool { |
| 94 | elements.iter().any(|element| match element { |
| 95 | ast::InterpolatedStringElement::Literal(literal) => { |
| 96 | triple_quotes.is_yes() && context.source().contains_line_break(literal.range()) |
| 97 | } |
| 98 | ast::InterpolatedStringElement::Interpolation(expression) => { |
| 99 | // Expressions containing comments can't be joined. |
| 100 | // |
| 101 | // Format specifiers needs to be checked as well. For example, the |
| 102 | // following should be considered multiline because the literal |
| 103 | // part of the format specifier contains a newline at the end |
| 104 | // (`.3f\n`): |
| 105 | // |
| 106 | // ```py |
| 107 | // x = f"hello {a + b + c + d:.3f |
| 108 | // } world" |
| 109 | // ``` |
| 110 | context.comments().contains_comments(expression.into()) |
| 111 | || expression.format_spec.as_deref().is_some_and(|spec| { |
| 112 | contains_line_break_or_comments(&spec.elements, context, triple_quotes) |
| 113 | }) |
| 114 | || expression.debug_text.as_ref().is_some_and(|debug_text| { |
| 115 | memchr2(b'\n', b'\r', debug_text.leading().as_bytes()).is_some() |
| 116 | || memchr2(b'\n', b'\r', debug_text.trailing().as_bytes()).is_some() |
| 117 | }) |
| 118 | } |
| 119 | }) |
| 120 | } |
| 121 | |
| 122 | self.parts().any(|part| match part { |
| 123 | StringLikePart::String(_) | StringLikePart::Bytes(_) => { |
| 124 | part.flags().is_triple_quoted() |
| 125 | && context.source().contains_line_break(part.range()) |
| 126 | } |
| 127 | StringLikePart::FString(f_string) => contains_line_break_or_comments( |
| 128 | &f_string.elements, |
| 129 | context, |
| 130 | f_string.flags.triple_quotes(), |
| 131 | ), |
| 132 | StringLikePart::TString(t_string) => contains_line_break_or_comments( |
| 133 | &t_string.elements, |
| 134 | context, |
| 135 | t_string.flags.triple_quotes(), |
| 136 | ), |
| 137 | }) |
| 138 | } |
| 139 | } |
no test coverage detected