mirror of
https://github.com/astral-sh/ruff
synced 2026-01-24 06:50:59 -05:00
@@ -11,13 +11,9 @@ use std::borrow::Cow;
|
||||
|
||||
use crate::comments::{leading_comments, trailing_comments};
|
||||
use crate::expression::parentheses::in_parentheses_only_soft_line_break_or_space;
|
||||
use crate::other::f_string::{FStringContext, FStringLayout, FormatFString};
|
||||
use crate::other::f_string::{FStringContext, FStringLayout};
|
||||
use crate::other::f_string_element::FormatFStringExpressionElement;
|
||||
use crate::other::string_literal::StringLiteralKind;
|
||||
use crate::prelude::*;
|
||||
use crate::preview::{
|
||||
is_f_string_formatting_enabled, is_join_implicit_concatenated_string_enabled,
|
||||
};
|
||||
use crate::string::docstring::needs_chaperone_space;
|
||||
use crate::string::normalize::{
|
||||
is_fstring_with_quoted_debug_expression, is_fstring_with_quoted_format_spec_and_debug,
|
||||
@@ -82,14 +78,9 @@ impl<'a> FormatImplicitConcatenatedStringExpanded<'a> {
|
||||
impl Format<PyFormatContext<'_>> for FormatImplicitConcatenatedStringExpanded<'_> {
|
||||
fn fmt(&self, f: &mut Formatter<PyFormatContext<'_>>) -> FormatResult<()> {
|
||||
let comments = f.context().comments().clone();
|
||||
let quoting = self.string.quoting(f.context().source());
|
||||
|
||||
let join_implicit_concatenated_string_enabled =
|
||||
is_join_implicit_concatenated_string_enabled(f.context());
|
||||
|
||||
// Keep implicit concatenated strings expanded unless they're already written on a single line.
|
||||
if matches!(self.layout, ImplicitConcatenatedLayout::Multipart)
|
||||
&& join_implicit_concatenated_string_enabled
|
||||
&& self.string.parts().tuple_windows().any(|(a, b)| {
|
||||
f.context()
|
||||
.source()
|
||||
@@ -103,23 +94,13 @@ impl Format<PyFormatContext<'_>> for FormatImplicitConcatenatedStringExpanded<'_
|
||||
|
||||
for part in self.string.parts() {
|
||||
let format_part = format_with(|f: &mut PyFormatter| match part {
|
||||
StringLikePart::String(part) => {
|
||||
let kind = if self.string.is_fstring() {
|
||||
#[allow(deprecated)]
|
||||
StringLiteralKind::InImplicitlyConcatenatedFString(quoting)
|
||||
} else {
|
||||
StringLiteralKind::String
|
||||
};
|
||||
|
||||
part.format().with_options(kind).fmt(f)
|
||||
}
|
||||
StringLikePart::String(part) => part.format().fmt(f),
|
||||
StringLikePart::Bytes(bytes_literal) => bytes_literal.format().fmt(f),
|
||||
StringLikePart::FString(part) => FormatFString::new(part, quoting).fmt(f),
|
||||
StringLikePart::FString(part) => part.format().fmt(f),
|
||||
});
|
||||
|
||||
let part_comments = comments.leading_dangling_trailing(&part);
|
||||
joiner.entry(&format_args![
|
||||
(!join_implicit_concatenated_string_enabled).then_some(line_suffix_boundary()),
|
||||
leading_comments(part_comments.leading),
|
||||
format_part,
|
||||
trailing_comments(part_comments.trailing)
|
||||
@@ -149,10 +130,6 @@ impl<'a> FormatImplicitConcatenatedStringFlat<'a> {
|
||||
/// Creates a new formatter. Returns `None` if the string can't be merged into a single string.
|
||||
pub(crate) fn new(string: StringLike<'a>, context: &PyFormatContext) -> Option<Self> {
|
||||
fn merge_flags(string: StringLike, context: &PyFormatContext) -> Option<AnyStringFlags> {
|
||||
if !is_join_implicit_concatenated_string_enabled(context) {
|
||||
return None;
|
||||
}
|
||||
|
||||
// Multiline strings can never fit on a single line.
|
||||
if string.is_multiline(context) {
|
||||
return None;
|
||||
@@ -323,44 +300,29 @@ impl Format<PyFormatContext<'_>> for FormatImplicitConcatenatedStringFlat<'_> {
|
||||
}
|
||||
|
||||
StringLikePart::FString(f_string) => {
|
||||
if is_f_string_formatting_enabled(f.context()) {
|
||||
for element in &f_string.elements {
|
||||
match element {
|
||||
FStringElement::Literal(literal) => {
|
||||
FormatLiteralContent {
|
||||
range: literal.range(),
|
||||
flags: self.flags,
|
||||
is_fstring: true,
|
||||
trim_end: false,
|
||||
trim_start: false,
|
||||
}
|
||||
.fmt(f)?;
|
||||
for element in &f_string.elements {
|
||||
match element {
|
||||
FStringElement::Literal(literal) => {
|
||||
FormatLiteralContent {
|
||||
range: literal.range(),
|
||||
flags: self.flags,
|
||||
is_fstring: true,
|
||||
trim_end: false,
|
||||
trim_start: false,
|
||||
}
|
||||
// Formatting the expression here and in the expanded version is safe **only**
|
||||
// because we assert that the f-string never contains any comments.
|
||||
FStringElement::Expression(expression) => {
|
||||
let context = FStringContext::new(
|
||||
self.flags,
|
||||
FStringLayout::from_f_string(
|
||||
f_string,
|
||||
f.context().source(),
|
||||
),
|
||||
);
|
||||
.fmt(f)?;
|
||||
}
|
||||
// Formatting the expression here and in the expanded version is safe **only**
|
||||
// because we assert that the f-string never contains any comments.
|
||||
FStringElement::Expression(expression) => {
|
||||
let context = FStringContext::new(
|
||||
self.flags,
|
||||
FStringLayout::from_f_string(f_string, f.context().source()),
|
||||
);
|
||||
|
||||
FormatFStringExpressionElement::new(expression, context)
|
||||
.fmt(f)?;
|
||||
}
|
||||
FormatFStringExpressionElement::new(expression, context).fmt(f)?;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
FormatLiteralContent {
|
||||
range: part.content_range(),
|
||||
flags: self.flags,
|
||||
is_fstring: true,
|
||||
trim_end: false,
|
||||
trim_start: false,
|
||||
}
|
||||
.fmt(f)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -386,9 +348,6 @@ impl Format<PyFormatContext<'_>> for FormatLiteralContent {
|
||||
0,
|
||||
self.flags,
|
||||
self.flags.is_f_string() && !self.is_fstring,
|
||||
// TODO: Remove the argument from `normalize_string` when promoting the `is_f_string_formatting_enabled` preview style.
|
||||
self.flags.is_f_string() && !is_f_string_formatting_enabled(f.context()),
|
||||
is_f_string_formatting_enabled(f.context()),
|
||||
);
|
||||
|
||||
// Trim the start and end of the string if it's the first or last part of a docstring.
|
||||
@@ -413,7 +372,7 @@ impl Format<PyFormatContext<'_>> for FormatLiteralContent {
|
||||
Cow::Owned(normalized) => text(normalized).fmt(f)?,
|
||||
}
|
||||
|
||||
if self.trim_end && needs_chaperone_space(self.flags, &normalized, f.context()) {
|
||||
if self.trim_end && needs_chaperone_space(self.flags, &normalized) {
|
||||
space().fmt(f)?;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user