diff --git a/crates/ruff_linter/src/rules/pyupgrade/rules/f_strings.rs b/crates/ruff_linter/src/rules/pyupgrade/rules/f_strings.rs index bd040aa0ecaa7..ff2028b005b27 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/rules/f_strings.rs +++ b/crates/ruff_linter/src/rules/pyupgrade/rules/f_strings.rs @@ -191,15 +191,21 @@ fn try_convert_to_f_string( summary: &mut FormatSummaryValues, locator: &Locator, ) -> Result> { + let contents = locator.slice(range); + // Strip the unicode prefix. It's redundant in Python 3, and invalid when used // with f-strings. - let contents = locator.slice(range); let contents = if contents.starts_with('U') || contents.starts_with('u') { &contents[1..] } else { contents }; + // Temporarily strip the raw prefix, if present. It will be prepended to the result, before the + // 'f', to match the prefix order both the Ruff formatter (and Black) use when formatting code. + let raw = contents.starts_with('R') || contents.starts_with('r'); + let contents = if raw { &contents[1..] } else { contents }; + // Remove the leading and trailing quotes. let leading_quote = leading_quote(contents).context("Unable to identify leading quote")?; let trailing_quote = trailing_quote(contents).context("Unable to identify trailing quote")?; @@ -291,7 +297,10 @@ fn try_convert_to_f_string( } // Construct the format string. - let mut contents = String::with_capacity(1 + converted.len()); + let mut contents = String::with_capacity(usize::from(raw) + 1 + converted.len()); + if raw { + contents.push('r'); + } contents.push('f'); contents.push_str(leading_quote); contents.push_str(&converted); diff --git a/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP032_0.py.snap b/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP032_0.py.snap index b056d14717377..de1fccc802d9d 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP032_0.py.snap +++ b/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP032_0.py.snap @@ -353,7 +353,7 @@ UP032_0.py:37:1: UP032 [*] Use f-string instead of `format` call 35 35 | "foo{}".format(1) 36 36 | 37 |-r"foo{}".format(1) - 37 |+fr"foo{1}" + 37 |+rf"foo{1}" 38 38 | 39 39 | x = "{a}".format(a=1) 40 40 |