Remove some usages of default format for expressions (#2100)

This commit is contained in:
Charlie Marsh 2023-01-22 23:15:43 -05:00 committed by GitHub
parent 9d2eced941
commit 09b65a6449
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 65 additions and 16 deletions

40
src/ast/hashable.rs Normal file
View File

@ -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
}
}

View File

@ -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;

View File

@ -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()) {

View File

@ -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),
));
}

View File

@ -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);
}
}