mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-28 12:55:05 +00:00
Use Cow in printf rewrite rule (#7986)
Small thing that bothered me when looking into the regex update.
This commit is contained in:
parent
7da4e28a98
commit
84f7391cc5
2 changed files with 31 additions and 31 deletions
|
@ -1,13 +1,13 @@
|
|||
use once_cell::sync::Lazy;
|
||||
use regex::{Captures, Regex};
|
||||
use std::borrow::Cow;
|
||||
|
||||
static CURLY_BRACES: Lazy<Regex> = Lazy::new(|| Regex::new(r"(\\N\{[^}]+})|([{}])").unwrap());
|
||||
|
||||
pub(super) fn curly_escape(text: &str) -> String {
|
||||
pub(super) fn curly_escape(text: &str) -> Cow<'_, str> {
|
||||
// Match all curly braces. This will include named unicode escapes (like
|
||||
// \N{SNOWMAN}), which we _don't_ want to escape, so take care to preserve them.
|
||||
CURLY_BRACES
|
||||
.replace_all(text, |caps: &Captures| {
|
||||
CURLY_BRACES.replace_all(text, |caps: &Captures| {
|
||||
if let Some(match_) = caps.get(1) {
|
||||
match_.as_str().to_string()
|
||||
} else {
|
||||
|
@ -18,5 +18,4 @@ pub(super) fn curly_escape(text: &str) -> String {
|
|||
}
|
||||
}
|
||||
})
|
||||
.to_string()
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
use std::borrow::Cow;
|
||||
use std::str::FromStr;
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation};
|
||||
|
@ -105,7 +106,7 @@ fn simplify_conversion_flag(flags: CConversionFlags) -> String {
|
|||
}
|
||||
|
||||
/// Convert a [`PercentFormat`] struct into a `String`.
|
||||
fn handle_part(part: &CFormatPart<String>) -> String {
|
||||
fn handle_part(part: &CFormatPart<String>) -> Cow<'_, str> {
|
||||
match part {
|
||||
CFormatPart::Literal(item) => curly_escape(item),
|
||||
CFormatPart::Spec(spec) => {
|
||||
|
@ -114,7 +115,7 @@ fn handle_part(part: &CFormatPart<String>) -> String {
|
|||
// TODO(charlie): What case is this?
|
||||
if spec.format_char == '%' {
|
||||
format_string.push('%');
|
||||
return format_string;
|
||||
return Cow::Owned(format_string);
|
||||
}
|
||||
|
||||
format_string.push('{');
|
||||
|
@ -171,26 +172,25 @@ fn handle_part(part: &CFormatPart<String>) -> String {
|
|||
format_string.push(spec.format_char);
|
||||
}
|
||||
format_string.push('}');
|
||||
format_string
|
||||
Cow::Owned(format_string)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert a [`CFormatString`] into a `String`.
|
||||
fn percent_to_format(format_string: &CFormatString) -> String {
|
||||
let mut contents = String::new();
|
||||
for (.., format_part) in format_string.iter() {
|
||||
contents.push_str(&handle_part(format_part));
|
||||
}
|
||||
contents
|
||||
format_string
|
||||
.iter()
|
||||
.map(|(_, part)| handle_part(part))
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// If a tuple has one argument, remove the comma; otherwise, return it as-is.
|
||||
fn clean_params_tuple(right: &Expr, locator: &Locator) -> String {
|
||||
let mut contents = locator.slice(right).to_string();
|
||||
fn clean_params_tuple<'a>(right: &Expr, locator: &Locator<'a>) -> Cow<'a, str> {
|
||||
if let Expr::Tuple(ast::ExprTuple { elts, .. }) = &right {
|
||||
if elts.len() == 1 {
|
||||
if !locator.contains_line_break(right.range()) {
|
||||
let mut contents = locator.slice(right).to_string();
|
||||
for (i, character) in contents.chars().rev().enumerate() {
|
||||
if character == ',' {
|
||||
let correct_index = contents.len() - i - 1;
|
||||
|
@ -198,10 +198,12 @@ fn clean_params_tuple(right: &Expr, locator: &Locator) -> String {
|
|||
break;
|
||||
}
|
||||
}
|
||||
return Cow::Owned(contents);
|
||||
}
|
||||
}
|
||||
}
|
||||
contents
|
||||
|
||||
Cow::Borrowed(locator.slice(right))
|
||||
}
|
||||
|
||||
/// Converts a dictionary to a function call while preserving as much styling as
|
||||
|
@ -419,16 +421,16 @@ pub(crate) fn printf_string_formatting(checker: &mut Checker, expr: &Expr, right
|
|||
// Parse the parameters.
|
||||
let params_string = match right {
|
||||
Expr::Constant(_) | Expr::FString(_) => {
|
||||
format!("({})", checker.locator().slice(right))
|
||||
Cow::Owned(format!("({})", checker.locator().slice(right)))
|
||||
}
|
||||
Expr::Name(_) | Expr::Attribute(_) | Expr::Subscript(_) | Expr::Call(_) => {
|
||||
if num_keyword_arguments > 0 {
|
||||
// If we have _any_ named fields, assume the right-hand side is a mapping.
|
||||
format!("(**{})", checker.locator().slice(right))
|
||||
Cow::Owned(format!("(**{})", checker.locator().slice(right)))
|
||||
} else if num_positional_arguments > 1 {
|
||||
// If we have multiple fields, but no named fields, assume the right-hand side is a
|
||||
// tuple.
|
||||
format!("(*{})", checker.locator().slice(right))
|
||||
Cow::Owned(format!("(*{})", checker.locator().slice(right)))
|
||||
} else {
|
||||
// Otherwise, if we have a single field, we can't make any assumptions about the
|
||||
// right-hand side. It _could_ be a tuple, but it could also be a single value,
|
||||
|
@ -444,13 +446,12 @@ pub(crate) fn printf_string_formatting(checker: &mut Checker, expr: &Expr, right
|
|||
}
|
||||
Expr::Tuple(_) => clean_params_tuple(right, checker.locator()),
|
||||
Expr::Dict(_) => {
|
||||
if let Some(params_string) =
|
||||
let Some(params_string) =
|
||||
clean_params_dictionary(right, checker.locator(), checker.stylist())
|
||||
{
|
||||
params_string
|
||||
} else {
|
||||
else {
|
||||
return;
|
||||
}
|
||||
};
|
||||
Cow::Owned(params_string)
|
||||
}
|
||||
_ => return,
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue