mirror of
https://github.com/astral-sh/ruff.git
synced 2025-07-22 20:45:11 +00:00
Prefer the configured quote style
<!-- Thank you for contributing to Ruff! To help us out with reviewing, please consider the following: - Does this pull request include a summary of the change? (See below.) - Does this pull request include a descriptive title? - Does this pull request include references to any relevant issues? --> ## Summary This PR extends the string formatting to respect the configured quote style. <!-- What's the purpose of the change? What does it do, and why? --> ## Test Plan Extended the string test with new cases and set it up to run twice: Once with the `quote_style: Doube`, and once with `quote_style: Single` single and double quotes. <!-- How was it tested? -->
This commit is contained in:
parent
f18a1f70de
commit
313711aaf9
5 changed files with 165 additions and 24 deletions
|
@ -58,7 +58,8 @@ impl Format<PyFormatContext<'_>> for FormatStringPart {
|
|||
let raw_content_range = relative_raw_content_range + self.part_range.start();
|
||||
|
||||
let raw_content = &string_content[relative_raw_content_range];
|
||||
let (preferred_quotes, contains_newlines) = preferred_quotes(raw_content, quotes);
|
||||
let (preferred_quotes, contains_newlines) =
|
||||
preferred_quotes(raw_content, quotes, f.options().quote_style());
|
||||
|
||||
write!(f, [prefix, preferred_quotes])?;
|
||||
|
||||
|
@ -148,14 +149,20 @@ impl Format<PyFormatContext<'_>> for StringPrefix {
|
|||
/// Detects the preferred quotes for `input`.
|
||||
/// * single quoted strings: The preferred quote style is the one that requires less escape sequences.
|
||||
/// * triple quoted strings: Use double quotes except the string contains a sequence of `"""`.
|
||||
fn preferred_quotes(input: &str, quotes: StringQuotes) -> (StringQuotes, ContainsNewlines) {
|
||||
fn preferred_quotes(
|
||||
input: &str,
|
||||
quotes: StringQuotes,
|
||||
configured_style: QuoteStyle,
|
||||
) -> (StringQuotes, ContainsNewlines) {
|
||||
let mut contains_newlines = ContainsNewlines::No;
|
||||
|
||||
let preferred_style = if quotes.triple {
|
||||
let mut use_single_quotes = false;
|
||||
// True if the string contains a triple quote sequence of the configured quote style.
|
||||
let mut uses_triple_quotes = false;
|
||||
let mut chars = input.chars().peekable();
|
||||
|
||||
while let Some(c) = chars.next() {
|
||||
let configured_quote_char = configured_style.as_char();
|
||||
match c {
|
||||
'\n' | '\r' => contains_newlines = ContainsNewlines::Yes,
|
||||
'\\' => {
|
||||
|
@ -163,24 +170,25 @@ fn preferred_quotes(input: &str, quotes: StringQuotes) -> (StringQuotes, Contain
|
|||
chars.next();
|
||||
}
|
||||
}
|
||||
'"' => {
|
||||
// `"` or `'`
|
||||
c if c == configured_quote_char => {
|
||||
match chars.peek().copied() {
|
||||
Some('"') => {
|
||||
// `""`
|
||||
Some(c) if c == configured_quote_char => {
|
||||
// `""` or `''`
|
||||
chars.next();
|
||||
|
||||
if chars.peek().copied() == Some('"') {
|
||||
// `"""`
|
||||
if chars.peek().copied() == Some(configured_quote_char) {
|
||||
// `"""` or `'''`
|
||||
chars.next();
|
||||
use_single_quotes = true;
|
||||
uses_triple_quotes = true;
|
||||
}
|
||||
}
|
||||
Some(_) => {
|
||||
// Single quote, this is ok
|
||||
// A single quote char, this is ok
|
||||
}
|
||||
None => {
|
||||
// Trailing quote at the end of the comment
|
||||
use_single_quotes = true;
|
||||
uses_triple_quotes = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -188,10 +196,12 @@ fn preferred_quotes(input: &str, quotes: StringQuotes) -> (StringQuotes, Contain
|
|||
}
|
||||
}
|
||||
|
||||
if use_single_quotes {
|
||||
QuoteStyle::Single
|
||||
if uses_triple_quotes {
|
||||
// String contains a triple quote sequence of the configured quote style.
|
||||
// Keep the existing quote style.
|
||||
quotes.style
|
||||
} else {
|
||||
QuoteStyle::Double
|
||||
configured_style
|
||||
}
|
||||
} else {
|
||||
let mut single_quotes = 0u32;
|
||||
|
@ -215,10 +225,21 @@ fn preferred_quotes(input: &str, quotes: StringQuotes) -> (StringQuotes, Contain
|
|||
}
|
||||
}
|
||||
|
||||
if double_quotes > single_quotes {
|
||||
QuoteStyle::Single
|
||||
} else {
|
||||
QuoteStyle::Double
|
||||
match configured_style {
|
||||
QuoteStyle::Single => {
|
||||
if single_quotes > double_quotes {
|
||||
QuoteStyle::Double
|
||||
} else {
|
||||
QuoteStyle::Single
|
||||
}
|
||||
}
|
||||
QuoteStyle::Double => {
|
||||
if double_quotes > single_quotes {
|
||||
QuoteStyle::Single
|
||||
} else {
|
||||
QuoteStyle::Double
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -286,7 +307,7 @@ fn normalize_quotes(input: &str, quotes: StringQuotes) -> Cow<str> {
|
|||
|
||||
let style = quotes.style;
|
||||
let preferred_quote = style.as_char();
|
||||
let opposite_quote = style.opposite().as_char();
|
||||
let opposite_quote = style.invert().as_char();
|
||||
|
||||
let mut chars = input.char_indices();
|
||||
|
||||
|
|
|
@ -109,7 +109,7 @@ impl QuoteStyle {
|
|||
}
|
||||
|
||||
#[must_use]
|
||||
pub const fn opposite(self) -> QuoteStyle {
|
||||
pub const fn invert(self) -> QuoteStyle {
|
||||
match self {
|
||||
QuoteStyle::Single => QuoteStyle::Double,
|
||||
QuoteStyle::Double => QuoteStyle::Single,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue