mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-17 17:10:34 +00:00
Preserve quotes in generated f-strings (#15794)
## Summary This is another follow-up to #15726 and #15778, extending the quote-preserving behavior to f-strings and deleting the now-unused `Generator::quote` field. ## Details I also made one unrelated change to `rules/flynt/helpers.rs` to remove a `to_string` call for making a `Box<str>` and tweaked some arguments to some of the `Generator::unparse_f_string` methods to make the code easier to follow, in my opinion. Happy to revert especially the latter of these if needed. Unfortunately this still does not fix the issue in #9660, which appears to be more of an escaping issue than a quote-preservation issue. After #15726, the result is now `a = f'# {"".join([])}' if 1 else ""` instead of `a = f"# {''.join([])}" if 1 else ""` (single quotes on the outside now), but we still don't have the desired behavior of double quotes everywhere on Python 3.12+. I added a test for this but split it off into another branch since it ended up being unaddressed here, but my `dbg!` statements showed the correct preferred quotes going into [`UnicodeEscape::with_preferred_quote`](https://github.com/astral-sh/ruff/blob/main/crates/ruff_python_literal/src/escape.rs#L54). ## Test Plan Existing rule and `Generator` tests. --------- Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
This commit is contained in:
parent
d151ca85d3
commit
23c98849fc
11 changed files with 197 additions and 116 deletions
|
@ -1063,10 +1063,32 @@ bitflags! {
|
|||
|
||||
/// Flags that can be queried to obtain information
|
||||
/// regarding the prefixes and quotes used for an f-string.
|
||||
#[derive(Default, Copy, Clone, Eq, PartialEq, Hash)]
|
||||
///
|
||||
/// ## Notes on usage
|
||||
///
|
||||
/// If you're using a `Generator` from the `ruff_python_codegen` crate to generate a lint-rule fix
|
||||
/// from an existing f-string literal, consider passing along the [`FString::flags`] field. If you
|
||||
/// don't have an existing literal but have a `Checker` from the `ruff_linter` crate available,
|
||||
/// consider using `Checker::default_fstring_flags` to create instances of this struct; this method
|
||||
/// will properly handle nested f-strings. For usage that doesn't fit into one of these categories,
|
||||
/// the public constructor [`FStringFlags::empty`] can be used.
|
||||
#[derive(Copy, Clone, Eq, PartialEq, Hash)]
|
||||
pub struct FStringFlags(FStringFlagsInner);
|
||||
|
||||
impl FStringFlags {
|
||||
/// Construct a new [`FStringFlags`] with **no flags set**.
|
||||
///
|
||||
/// See [`FStringFlags::with_quote_style`], [`FStringFlags::with_triple_quotes`], and
|
||||
/// [`FStringFlags::with_prefix`] for ways of setting the quote style (single or double),
|
||||
/// enabling triple quotes, and adding prefixes (such as `r`), respectively.
|
||||
///
|
||||
/// See the documentation for [`FStringFlags`] for additional caveats on this constructor, and
|
||||
/// situations in which alternative ways to construct this struct should be used, especially
|
||||
/// when writing lint rules.
|
||||
pub fn empty() -> Self {
|
||||
Self(FStringFlagsInner::empty())
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn with_quote_style(mut self, quote_style: Quote) -> Self {
|
||||
self.0
|
||||
|
@ -2229,7 +2251,7 @@ impl From<AnyStringFlags> for FStringFlags {
|
|||
value.prefix()
|
||||
)
|
||||
};
|
||||
let new = FStringFlags::default()
|
||||
let new = FStringFlags::empty()
|
||||
.with_quote_style(value.quote_style())
|
||||
.with_prefix(fstring_prefix);
|
||||
if value.is_triple_quoted() {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue