MCPcopy Create free account
hub / github.com/astral-sh/ruff / preferred_quote_style

Method preferred_quote_style

crates/ruff_python_formatter/src/string/normalize.rs:44–190  ·  view source on GitHub ↗

Determines the preferred quote style for `string`. The formatter should use the preferred quote style unless it can't because the string contains the preferred quotes OR it leads to more escaping. Note: If you add more cases here where we return `QuoteStyle::Preserve`, make sure to also add them to [`FormatImplicitConcatenatedStringFlat::new`](crate::string::implicit::FormatImplicitConcatenatedSt

(&self, string: StringLikePart)

Source from the content-addressed store, hash-verified

42 /// add them to
43 /// [`FormatImplicitConcatenatedStringFlat::new`](crate::string::implicit::FormatImplicitConcatenatedStringFlat::new).
44 pub(super) fn preferred_quote_style(&self, string: StringLikePart) -> QuoteStyle {
45 let preferred_quote_style = self
46 .preferred_quote_style
47 .unwrap_or(self.context.options().quote_style());
48 let supports_pep_701 = self.context.options().target_version().supports_pep_701();
49
50 // Preserve the existing quote style for nested interpolations more than one layer deep, if
51 // PEP 701 isn't supported.
52 if !supports_pep_701 && self.context.interpolated_string_state().is_nested() {
53 return QuoteStyle::Preserve;
54 }
55
56 // For f-strings and t-strings prefer alternating the quotes unless the outer string is
57 // triple quoted and the inner isn't. In Python 3.12+, `nested-string-quote-style =
58 // "preferred"` uses the configured quote style instead.
59 if let InterpolatedStringState::InsideInterpolatedElement(parent_context)
60 | InterpolatedStringState::NestedInterpolatedElement(parent_context) =
61 self.context.interpolated_string_state()
62 {
63 let parent_flags = parent_context.flags();
64 let nested_string_quote_style = self.context.options().nested_string_quote_style();
65
66 if !parent_flags.is_triple_quoted() || string.flags().is_triple_quoted() {
67 // When `nested-string-quote-style = "preferred"` and we're targeting Python
68 // 3.12+, use the preferred quote style consistently.
69 if supports_pep_701
70 && nested_string_quote_style.is_preferred()
71 && !preferred_quote_style.is_preserve()
72 {
73 return preferred_quote_style;
74 }
75 // Otherwise, use alternating quotes for compatibility.
76 // This logic is even necessary when using preserve and the target python version doesn't support PEP701 because
77 // we might end up joining two f-strings that have different quote styles, in which case we need to alternate the quotes
78 // for inner strings to avoid a syntax error: `string = "this is my string with " f'"{params.get("mine")}"'`
79 else if !preferred_quote_style.is_preserve() || !supports_pep_701 {
80 return QuoteStyle::from(parent_flags.quote_style().opposite());
81 }
82 }
83 }
84
85 // Leave the quotes unchanged for all other strings.
86 if preferred_quote_style.is_preserve() {
87 return QuoteStyle::Preserve;
88 }
89
90 // There are cases where it is necessary to preserve the quotes to prevent an invalid f-string or t-string.
91 match string {
92 StringLikePart::FString(fstring) => {
93 // There are two cases where it's necessary to preserve the quotes if the
94 // target version is pre 3.12 and the part is an f-string.
95 if !supports_pep_701 {
96 // An f-string expression contains a debug text with a quote character
97 // because the formatter will emit the debug expression **exactly** the
98 // same as in the source text.
99 if is_fstring_with_quoted_debug_expression(fstring, self.context) {
100 return QuoteStyle::Preserve;
101 }

Callers 2

choose_quotesMethod · 0.80
merge_flagsMethod · 0.80

Tested by

no test coverage detected