From e75d8ac59c53f3e22eee5c84f4ae3e0dd9df8a96 Mon Sep 17 00:00:00 2001 From: Samuel Cormier-Iijima Date: Wed, 22 Nov 2023 15:23:51 -0500 Subject: [PATCH] [formatter] Add "preserve" quote-style to mimic Black's skip-string-normalization Fixes #7525 --- .../src/expression/string/docstring.rs | 4 +++- .../ruff_python_formatter/src/expression/string/mod.rs | 10 ++++++---- crates/ruff_python_formatter/src/options.rs | 4 ++++ ruff.schema.json | 3 ++- 4 files changed, 15 insertions(+), 6 deletions(-) diff --git a/crates/ruff_python_formatter/src/expression/string/docstring.rs b/crates/ruff_python_formatter/src/expression/string/docstring.rs index 41f350bd4deb2..977e5f443b2cb 100644 --- a/crates/ruff_python_formatter/src/expression/string/docstring.rs +++ b/crates/ruff_python_formatter/src/expression/string/docstring.rs @@ -490,7 +490,9 @@ impl<'ast, 'buf, 'fmt, 'src> DocstringLinePrinter<'ast, 'buf, 'fmt, 'src> { // `docstring_code_examples.py` for when this check is relevant. let wrapped = match self.quote_style { QuoteStyle::Single => std::format!("'''{}'''", printed.as_code()), - QuoteStyle::Double => std::format!(r#""""{}""""#, printed.as_code()), + QuoteStyle::Double | QuoteStyle::Preserve => { + std::format!(r#""""{}""""#, printed.as_code()) + } }; let result = ruff_python_parser::parse( &wrapped, diff --git a/crates/ruff_python_formatter/src/expression/string/mod.rs b/crates/ruff_python_formatter/src/expression/string/mod.rs index c7e896daf2c90..639239792a509 100644 --- a/crates/ruff_python_formatter/src/expression/string/mod.rs +++ b/crates/ruff_python_formatter/src/expression/string/mod.rs @@ -385,7 +385,9 @@ impl StringPart { let quotes = match quoting { Quoting::Preserve => self.quotes, Quoting::CanChange => { - if self.prefix.is_raw_string() { + if preferred_style == QuoteStyle::Preserve { + self.quotes + } else if self.prefix.is_raw_string() { choose_quotes_raw(raw_content, self.quotes, preferred_style) } else { choose_quotes(raw_content, self.quotes, preferred_style) @@ -664,7 +666,7 @@ fn choose_quotes(input: &str, quotes: StringQuotes, preferred_style: QuoteStyle) QuoteStyle::Single } } - QuoteStyle::Double => { + QuoteStyle::Double | QuoteStyle::Preserve => { if double_quotes > single_quotes { QuoteStyle::Single } else { @@ -716,8 +718,8 @@ impl Format> for StringQuotes { let quotes = match (self.style, self.triple) { (QuoteStyle::Single, false) => "'", (QuoteStyle::Single, true) => "'''", - (QuoteStyle::Double, false) => "\"", - (QuoteStyle::Double, true) => "\"\"\"", + (QuoteStyle::Double | QuoteStyle::Preserve, false) => "\"", + (QuoteStyle::Double | QuoteStyle::Preserve, true) => "\"\"\"", }; token(quotes).fmt(f) diff --git a/crates/ruff_python_formatter/src/options.rs b/crates/ruff_python_formatter/src/options.rs index a07fabbb9a795..576c66c3aabf7 100644 --- a/crates/ruff_python_formatter/src/options.rs +++ b/crates/ruff_python_formatter/src/options.rs @@ -207,6 +207,7 @@ pub enum QuoteStyle { Single, #[default] Double, + Preserve, } impl QuoteStyle { @@ -214,6 +215,7 @@ impl QuoteStyle { match self { QuoteStyle::Single => '\'', QuoteStyle::Double => '"', + QuoteStyle::Preserve => '"', // not used } } @@ -222,6 +224,7 @@ impl QuoteStyle { match self { QuoteStyle::Single => QuoteStyle::Double, QuoteStyle::Double => QuoteStyle::Single, + QuoteStyle::Preserve => QuoteStyle::Preserve, } } } @@ -245,6 +248,7 @@ impl FromStr for QuoteStyle { match s { "\"" | "double" | "Double" => Ok(Self::Double), "'" | "single" | "Single" => Ok(Self::Single), + "preserve" | "Preserve" => Ok(Self::Preserve), // TODO: replace this error with a diagnostic _ => Err("Value not supported for QuoteStyle"), } diff --git a/ruff.schema.json b/ruff.schema.json index 3bd21232a2551..92381de1a6522 100644 --- a/ruff.schema.json +++ b/ruff.schema.json @@ -2441,7 +2441,8 @@ "type": "string", "enum": [ "single", - "double" + "double", + "preserve" ] }, "RelativeImportsOrder": {