mirror of https://github.com/astral-sh/ruff
Remove some usages of default format for expressions (#2100)
This commit is contained in:
parent
9d2eced941
commit
09b65a6449
|
|
@ -0,0 +1,40 @@
|
|||
use std::hash::Hash;
|
||||
|
||||
use rustpython_ast::Expr;
|
||||
|
||||
use crate::ast::comparable::ComparableExpr;
|
||||
|
||||
/// Wrapper around `Expr` that implements `Hash` and `PartialEq`.
|
||||
pub struct HashableExpr<'a>(&'a Expr);
|
||||
|
||||
impl Hash for HashableExpr<'_> {
|
||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||
let comparable = ComparableExpr::from(self.0);
|
||||
comparable.hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq<Self> for HashableExpr<'_> {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
let comparable = ComparableExpr::from(self.0);
|
||||
comparable == ComparableExpr::from(other.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for HashableExpr<'_> {}
|
||||
|
||||
impl<'a> From<&'a Expr> for HashableExpr<'a> {
|
||||
fn from(expr: &'a Expr) -> Self {
|
||||
Self(expr)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> HashableExpr<'a> {
|
||||
pub(crate) fn from_expr(expr: &'a Expr) -> Self {
|
||||
Self(expr)
|
||||
}
|
||||
|
||||
pub(crate) fn as_expr(&self) -> &'a Expr {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,7 @@ pub mod branch_detection;
|
|||
pub mod cast;
|
||||
pub mod comparable;
|
||||
pub mod function_type;
|
||||
pub mod hashable;
|
||||
pub mod helpers;
|
||||
pub mod operations;
|
||||
pub mod relocate;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
use rustpython_ast::{Excepthandler, ExcepthandlerKind, ExprKind};
|
||||
|
||||
use crate::ast::helpers::unparse_expr;
|
||||
use crate::ast::types::Range;
|
||||
use crate::checkers::ast::Checker;
|
||||
use crate::fix::Fix;
|
||||
|
|
@ -20,7 +21,7 @@ pub fn redundant_tuple_in_exception_handler(checker: &mut Checker, handlers: &[E
|
|||
continue;
|
||||
};
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
violations::RedundantTupleInExceptionHandler(elt.to_string()),
|
||||
violations::RedundantTupleInExceptionHandler(unparse_expr(elt, checker.stylist)),
|
||||
Range::from_located(type_),
|
||||
);
|
||||
if checker.patch(diagnostic.kind.rule()) {
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@ use itertools::Itertools;
|
|||
use rustc_hash::{FxHashMap, FxHashSet};
|
||||
use rustpython_ast::{Boolop, Expr, ExprKind};
|
||||
|
||||
use crate::ast::hashable::HashableExpr;
|
||||
use crate::ast::helpers::unparse_expr;
|
||||
use crate::ast::types::Range;
|
||||
use crate::checkers::ast::Checker;
|
||||
use crate::registry::Diagnostic;
|
||||
|
|
@ -13,7 +15,8 @@ pub fn merge_isinstance(checker: &mut Checker, expr: &Expr, op: &Boolop, values:
|
|||
return;
|
||||
}
|
||||
|
||||
let mut obj_to_types: FxHashMap<String, (usize, FxHashSet<String>)> = FxHashMap::default();
|
||||
let mut obj_to_types: FxHashMap<HashableExpr, (usize, FxHashSet<HashableExpr>)> =
|
||||
FxHashMap::default();
|
||||
for value in values {
|
||||
let ExprKind::Call { func, args, .. } = &value.node else {
|
||||
continue;
|
||||
|
|
@ -25,16 +28,14 @@ pub fn merge_isinstance(checker: &mut Checker, expr: &Expr, op: &Boolop, values:
|
|||
continue;
|
||||
};
|
||||
let (num_calls, matches) = obj_to_types
|
||||
.entry(obj.to_string())
|
||||
.entry(obj.into())
|
||||
.or_insert_with(|| (0, FxHashSet::default()));
|
||||
|
||||
*num_calls += 1;
|
||||
matches.extend(match &types.node {
|
||||
ExprKind::Tuple { elts, .. } => {
|
||||
elts.iter().map(std::string::ToString::to_string).collect()
|
||||
}
|
||||
ExprKind::Tuple { elts, .. } => elts.iter().map(HashableExpr::from_expr).collect(),
|
||||
_ => {
|
||||
vec![types.to_string()]
|
||||
vec![types.into()]
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -42,7 +43,15 @@ pub fn merge_isinstance(checker: &mut Checker, expr: &Expr, op: &Boolop, values:
|
|||
for (obj, (num_calls, types)) in obj_to_types {
|
||||
if num_calls > 1 && types.len() > 1 {
|
||||
checker.diagnostics.push(Diagnostic::new(
|
||||
violations::ConsiderMergingIsinstance(obj, types.into_iter().sorted().collect()),
|
||||
violations::ConsiderMergingIsinstance(
|
||||
unparse_expr(obj.as_expr(), checker.stylist),
|
||||
types
|
||||
.iter()
|
||||
.map(HashableExpr::as_expr)
|
||||
.map(|expr| unparse_expr(expr, checker.stylist))
|
||||
.sorted()
|
||||
.collect(),
|
||||
),
|
||||
Range::from_located(expr),
|
||||
));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
//! Generate Python source code from an abstract syntax tree (AST).
|
||||
|
||||
use std::fmt::{self, Write};
|
||||
use std::ops::Deref;
|
||||
|
||||
use rustpython_ast::{Excepthandler, ExcepthandlerKind, Suite, Withitem};
|
||||
|
|
@ -116,10 +115,6 @@ impl<'a> Generator<'a> {
|
|||
self.p_if(!std::mem::take(first), s);
|
||||
}
|
||||
|
||||
fn write_fmt(&mut self, f: fmt::Arguments<'_>) {
|
||||
self.buffer.write_fmt(f).unwrap();
|
||||
}
|
||||
|
||||
pub fn unparse_suite<U>(&mut self, suite: &Suite<U>) {
|
||||
for stmt in suite {
|
||||
self.unparse_stmt(stmt);
|
||||
|
|
@ -928,7 +923,8 @@ impl<'a> Generator<'a> {
|
|||
self.p_delim(&mut first, ", ");
|
||||
self.unparse_arg(arg);
|
||||
if let Some(i) = i.checked_sub(defaults_start) {
|
||||
write!(self, "={}", &args.defaults[i]);
|
||||
self.p("=");
|
||||
self.unparse_expr(&args.defaults[i], precedence::TEST);
|
||||
}
|
||||
self.p_if(i + 1 == args.posonlyargs.len(), ", /");
|
||||
}
|
||||
|
|
@ -947,7 +943,8 @@ impl<'a> Generator<'a> {
|
|||
.checked_sub(defaults_start)
|
||||
.and_then(|i| args.kw_defaults.get(i))
|
||||
{
|
||||
write!(self, "={default}");
|
||||
self.p("=");
|
||||
self.unparse_expr(default, precedence::TEST);
|
||||
}
|
||||
}
|
||||
if let Some(kwarg) = &args.kwarg {
|
||||
|
|
@ -960,7 +957,8 @@ impl<'a> Generator<'a> {
|
|||
fn unparse_arg<U>(&mut self, arg: &Arg<U>) {
|
||||
self.p(&arg.node.arg);
|
||||
if let Some(ann) = &arg.node.annotation {
|
||||
write!(self, ": {}", **ann);
|
||||
self.p(": ");
|
||||
self.unparse_expr(ann, precedence::TEST);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue