From f56bc1983b16c34a2fcb4a467a5220f54e8aa72f Mon Sep 17 00:00:00 2001 From: Deepyaman Datta Date: Fri, 3 Nov 2023 08:56:21 -0600 Subject: [PATCH] Place 'r' prefix before 'f' for raw format strings (#8464) ## Summary Currently, `UP032` applied to raw strings results in format strings with the prefix 'fr'. This gets changed to 'rf' by Ruff format (or Black). In order to avoid that, this PR uses the prefix 'rf' to begin with. ## Test Plan Updated the expectation on an existing test. --- .../src/rules/pyupgrade/rules/f_strings.rs | 13 +++++++++++-- ...linter__rules__pyupgrade__tests__UP032_0.py.snap | 2 +- 2 files changed, 12 insertions(+), 3 deletions(-) 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 |