mirror of
https://github.com/astral-sh/ruff.git
synced 2025-10-01 06:11:21 +00:00
Remove unnecessary super_args.rs
(#2594)
This commit is contained in:
parent
87d0aa5561
commit
291ef9856a
4 changed files with 73 additions and 100 deletions
|
@ -592,15 +592,6 @@ pub fn has_comments_in(range: Range, locator: &Locator) -> bool {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `true` if a call is an argumented `super` invocation.
|
|
||||||
pub fn is_super_call_with_arguments(func: &Expr, args: &[Expr]) -> bool {
|
|
||||||
if let ExprKind::Name { id, .. } = &func.node {
|
|
||||||
id == "super" && !args.is_empty()
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Return `true` if the body uses `locals()`, `globals()`, `vars()`, `eval()`.
|
/// Return `true` if the body uses `locals()`, `globals()`, `vars()`, `eval()`.
|
||||||
pub fn uses_magic_variable_access(checker: &Checker, body: &[Stmt]) -> bool {
|
pub fn uses_magic_variable_access(checker: &Checker, body: &[Stmt]) -> bool {
|
||||||
any_over_body(body, &|expr| {
|
any_over_body(body, &|expr| {
|
||||||
|
|
|
@ -29,7 +29,6 @@ pub(crate) use rewrite_mock_import::{
|
||||||
};
|
};
|
||||||
pub(crate) use rewrite_unicode_literal::{rewrite_unicode_literal, RewriteUnicodeLiteral};
|
pub(crate) use rewrite_unicode_literal::{rewrite_unicode_literal, RewriteUnicodeLiteral};
|
||||||
pub(crate) use rewrite_yield_from::{rewrite_yield_from, RewriteYieldFrom};
|
pub(crate) use rewrite_yield_from::{rewrite_yield_from, RewriteYieldFrom};
|
||||||
pub(crate) use super_args::super_args;
|
|
||||||
pub(crate) use super_call_with_parameters::{super_call_with_parameters, SuperCallWithParameters};
|
pub(crate) use super_call_with_parameters::{super_call_with_parameters, SuperCallWithParameters};
|
||||||
pub(crate) use type_of_primitive::{type_of_primitive, TypeOfPrimitive};
|
pub(crate) use type_of_primitive::{type_of_primitive, TypeOfPrimitive};
|
||||||
pub(crate) use typing_text_str_alias::{typing_text_str_alias, TypingTextStrAlias};
|
pub(crate) use typing_text_str_alias::{typing_text_str_alias, TypingTextStrAlias};
|
||||||
|
@ -68,7 +67,6 @@ mod rewrite_c_element_tree;
|
||||||
mod rewrite_mock_import;
|
mod rewrite_mock_import;
|
||||||
mod rewrite_unicode_literal;
|
mod rewrite_unicode_literal;
|
||||||
mod rewrite_yield_from;
|
mod rewrite_yield_from;
|
||||||
mod super_args;
|
|
||||||
mod super_call_with_parameters;
|
mod super_call_with_parameters;
|
||||||
mod type_of_primitive;
|
mod type_of_primitive;
|
||||||
mod typing_text_str_alias;
|
mod typing_text_str_alias;
|
||||||
|
|
|
@ -1,80 +0,0 @@
|
||||||
use crate::ast::helpers;
|
|
||||||
use crate::ast::types::{Range, Scope, ScopeKind};
|
|
||||||
|
|
||||||
use crate::registry::Diagnostic;
|
|
||||||
|
|
||||||
use crate::rules::pyupgrade::rules::SuperCallWithParameters;
|
|
||||||
|
|
||||||
use rustpython_ast::{ArgData, Expr, ExprKind, Stmt, StmtKind};
|
|
||||||
|
|
||||||
/// UP008
|
|
||||||
pub fn super_args(
|
|
||||||
scope: &Scope,
|
|
||||||
parents: &[&Stmt],
|
|
||||||
expr: &Expr,
|
|
||||||
func: &Expr,
|
|
||||||
args: &[Expr],
|
|
||||||
) -> Option<Diagnostic> {
|
|
||||||
if !helpers::is_super_call_with_arguments(func, args) {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check: are we in a Function scope?
|
|
||||||
if !matches!(scope.kind, ScopeKind::Function { .. }) {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut parents = parents.iter().rev();
|
|
||||||
|
|
||||||
// For a `super` invocation to be unnecessary, the first argument needs to match
|
|
||||||
// the enclosing class, and the second argument needs to match the first
|
|
||||||
// argument to the enclosing function.
|
|
||||||
let [first_arg, second_arg] = args else {
|
|
||||||
return None;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Find the enclosing function definition (if any).
|
|
||||||
let Some(StmtKind::FunctionDef {
|
|
||||||
args: parent_args, ..
|
|
||||||
}) = parents
|
|
||||||
.find(|stmt| matches!(stmt.node, StmtKind::FunctionDef { .. }))
|
|
||||||
.map(|stmt| &stmt.node) else {
|
|
||||||
return None;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Extract the name of the first argument to the enclosing function.
|
|
||||||
let Some(ArgData {
|
|
||||||
arg: parent_arg, ..
|
|
||||||
}) = parent_args.args.first().map(|expr| &expr.node) else {
|
|
||||||
return None;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Find the enclosing class definition (if any).
|
|
||||||
let Some(StmtKind::ClassDef {
|
|
||||||
name: parent_name, ..
|
|
||||||
}) = parents
|
|
||||||
.find(|stmt| matches!(stmt.node, StmtKind::ClassDef { .. }))
|
|
||||||
.map(|stmt| &stmt.node) else {
|
|
||||||
return None;
|
|
||||||
};
|
|
||||||
|
|
||||||
let (
|
|
||||||
ExprKind::Name {
|
|
||||||
id: first_arg_id, ..
|
|
||||||
},
|
|
||||||
ExprKind::Name {
|
|
||||||
id: second_arg_id, ..
|
|
||||||
},
|
|
||||||
) = (&first_arg.node, &second_arg.node) else {
|
|
||||||
return None;
|
|
||||||
};
|
|
||||||
|
|
||||||
if first_arg_id == parent_name && second_arg_id == parent_arg {
|
|
||||||
return Some(Diagnostic::new(
|
|
||||||
SuperCallWithParameters,
|
|
||||||
Range::from_located(expr),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
None
|
|
||||||
}
|
|
|
@ -1,11 +1,13 @@
|
||||||
use crate::define_violation;
|
use rustpython_ast::{ArgData, Expr, ExprKind, Stmt, StmtKind};
|
||||||
use crate::violation::AlwaysAutofixableViolation;
|
|
||||||
use ruff_macros::derive_message_formats;
|
|
||||||
use rustpython_ast::{Expr, Stmt};
|
|
||||||
|
|
||||||
use super::super::fixes;
|
use ruff_macros::derive_message_formats;
|
||||||
use crate::ast::helpers;
|
|
||||||
|
use crate::ast::types::{Range, ScopeKind};
|
||||||
use crate::checkers::ast::Checker;
|
use crate::checkers::ast::Checker;
|
||||||
|
use crate::define_violation;
|
||||||
|
use crate::registry::Diagnostic;
|
||||||
|
use crate::rules::pyupgrade::fixes;
|
||||||
|
use crate::violation::AlwaysAutofixableViolation;
|
||||||
|
|
||||||
define_violation!(
|
define_violation!(
|
||||||
pub struct SuperCallWithParameters;
|
pub struct SuperCallWithParameters;
|
||||||
|
@ -21,11 +23,20 @@ impl AlwaysAutofixableViolation for SuperCallWithParameters {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns `true` if a call is an argumented `super` invocation.
|
||||||
|
fn is_super_call_with_arguments(func: &Expr, args: &[Expr]) -> bool {
|
||||||
|
if let ExprKind::Name { id, .. } = &func.node {
|
||||||
|
id == "super" && !args.is_empty()
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// UP008
|
/// UP008
|
||||||
pub fn super_call_with_parameters(checker: &mut Checker, expr: &Expr, func: &Expr, args: &[Expr]) {
|
pub fn super_call_with_parameters(checker: &mut Checker, expr: &Expr, func: &Expr, args: &[Expr]) {
|
||||||
// Only bother going through the super check at all if we're in a `super` call.
|
// Only bother going through the super check at all if we're in a `super` call.
|
||||||
// (We check this in `check_super_args` too, so this is just an optimization.)
|
// (We check this in `super_args` too, so this is just an optimization.)
|
||||||
if !helpers::is_super_call_with_arguments(func, args) {
|
if !is_super_call_with_arguments(func, args) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let scope = checker.current_scope();
|
let scope = checker.current_scope();
|
||||||
|
@ -34,9 +45,62 @@ pub fn super_call_with_parameters(checker: &mut Checker, expr: &Expr, func: &Exp
|
||||||
.iter()
|
.iter()
|
||||||
.map(std::convert::Into::into)
|
.map(std::convert::Into::into)
|
||||||
.collect();
|
.collect();
|
||||||
let Some(mut diagnostic) = super::super_args(scope, &parents, expr, func, args) else {
|
|
||||||
|
// Check: are we in a Function scope?
|
||||||
|
if !matches!(scope.kind, ScopeKind::Function { .. }) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut parents = parents.iter().rev();
|
||||||
|
|
||||||
|
// For a `super` invocation to be unnecessary, the first argument needs to match
|
||||||
|
// the enclosing class, and the second argument needs to match the first
|
||||||
|
// argument to the enclosing function.
|
||||||
|
let [first_arg, second_arg] = args else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Find the enclosing function definition (if any).
|
||||||
|
let Some(StmtKind::FunctionDef {
|
||||||
|
args: parent_args, ..
|
||||||
|
}) = parents
|
||||||
|
.find(|stmt| matches!(stmt.node, StmtKind::FunctionDef { .. }))
|
||||||
|
.map(|stmt| &stmt.node) else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Extract the name of the first argument to the enclosing function.
|
||||||
|
let Some(ArgData {
|
||||||
|
arg: parent_arg, ..
|
||||||
|
}) = parent_args.args.first().map(|expr| &expr.node) else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Find the enclosing class definition (if any).
|
||||||
|
let Some(StmtKind::ClassDef {
|
||||||
|
name: parent_name, ..
|
||||||
|
}) = parents
|
||||||
|
.find(|stmt| matches!(stmt.node, StmtKind::ClassDef { .. }))
|
||||||
|
.map(|stmt| &stmt.node) else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
let (
|
||||||
|
ExprKind::Name {
|
||||||
|
id: first_arg_id, ..
|
||||||
|
},
|
||||||
|
ExprKind::Name {
|
||||||
|
id: second_arg_id, ..
|
||||||
|
},
|
||||||
|
) = (&first_arg.node, &second_arg.node) else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
if !(first_arg_id == parent_name && second_arg_id == parent_arg) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut diagnostic = Diagnostic::new(SuperCallWithParameters, Range::from_located(expr));
|
||||||
if checker.patch(diagnostic.kind.rule()) {
|
if checker.patch(diagnostic.kind.rule()) {
|
||||||
if let Some(fix) = fixes::remove_super_arguments(checker.locator, checker.stylist, expr) {
|
if let Some(fix) = fixes::remove_super_arguments(checker.locator, checker.stylist, expr) {
|
||||||
diagnostic.amend(fix);
|
diagnostic.amend(fix);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue