Remove remove_super_arguments (#6735)

Now that we have an `Arguments` node, we can use it directly to get the
range.
This commit is contained in:
Charlie Marsh
2023-08-21 13:04:07 -04:00
committed by GitHub
parent 575b77aa52
commit e032fbd2e7
4 changed files with 35 additions and 70 deletions

View File

@@ -432,7 +432,7 @@ pub(crate) fn expression(expr: &Expr, checker: &mut Checker) {
pyupgrade::rules::deprecated_unittest_alias(checker, func);
}
if checker.enabled(Rule::SuperCallWithParameters) {
pyupgrade::rules::super_call_with_parameters(checker, expr, func, args);
pyupgrade::rules::super_call_with_parameters(checker, call);
}
if checker.enabled(Rule::UnnecessaryEncodeUTF8) {
pyupgrade::rules::unnecessary_encode_utf8(checker, call);

View File

@@ -1,17 +1,12 @@
use anyhow::Result;
use libcst_native::ParenthesizableWhitespace;
use ruff_python_ast::{Expr, Ranged};
use ruff_python_codegen::Stylist;
use ruff_python_parser::{lexer, Mode, Tok};
use ruff_source_file::Locator;
use ruff_text_size::{TextRange, TextSize};
use crate::autofix::codemods::CodegenStylist;
use ruff_diagnostics::Edit;
use ruff_python_codegen::Stylist;
use ruff_source_file::Locator;
use crate::cst::matchers::{
match_call_mut, match_expression, match_function_def, match_indented_block, match_statement,
};
use crate::cst::matchers::{match_function_def, match_indented_block, match_statement};
/// Safely adjust the indentation of the indented block at [`TextRange`].
pub(crate) fn adjust_indentation(
@@ -39,29 +34,6 @@ pub(crate) fn adjust_indentation(
Ok(module_text)
}
/// Generate a fix to remove arguments from a `super` call.
pub(crate) fn remove_super_arguments(
locator: &Locator,
stylist: &Stylist,
expr: &Expr,
) -> Option<Edit> {
let range = expr.range();
let contents = locator.slice(range);
let mut tree = match_expression(contents).ok()?;
let body = match_call_mut(&mut tree).ok()?;
body.args = vec![];
body.whitespace_before_args = ParenthesizableWhitespace::default();
body.whitespace_after_func = ParenthesizableWhitespace::default();
Some(Edit::range_replacement(
tree.codegen_stylist(stylist),
range,
))
}
/// Remove any imports matching `members` from an import-from statement.
pub(crate) fn remove_import_members(contents: &str, members: &[&str]) -> String {
let mut names: Vec<TextRange> = vec![];

View File

@@ -1,11 +1,10 @@
use ruff_python_ast::{self as ast, Expr, Parameter, ParameterWithDefault, Ranged, Stmt};
use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Fix};
use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix};
use ruff_macros::{derive_message_formats, violation};
use ruff_python_ast::{self as ast, Expr, Parameter, ParameterWithDefault, Ranged, Stmt};
use ruff_text_size::TextSize;
use crate::checkers::ast::Checker;
use crate::registry::AsRule;
use crate::rules::pyupgrade::fixes;
/// ## What it does
/// Checks for `super` calls that pass redundant arguments.
@@ -59,25 +58,11 @@ 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 Expr::Name(ast::ExprName { id, .. }) = func {
id == "super" && !args.is_empty()
} else {
false
}
}
/// UP008
pub(crate) fn super_call_with_parameters(
checker: &mut Checker,
expr: &Expr,
func: &Expr,
args: &[Expr],
) {
pub(crate) fn super_call_with_parameters(checker: &mut Checker, call: &ast::ExprCall) {
// Only bother going through the super check at all if we're in a `super` call.
// (We check this in `super_args` too, so this is just an optimization.)
if !is_super_call_with_arguments(func, args) {
if !is_super_call_with_arguments(call) {
return;
}
let scope = checker.semantic().current_scope();
@@ -92,7 +77,7 @@ pub(crate) fn super_call_with_parameters(
// 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 {
let [first_arg, second_arg] = call.arguments.args.as_slice() else {
return;
};
@@ -142,13 +127,21 @@ pub(crate) fn super_call_with_parameters(
drop(parents);
let mut diagnostic = Diagnostic::new(SuperCallWithParameters, expr.range());
let mut diagnostic = Diagnostic::new(SuperCallWithParameters, call.arguments.range());
if checker.patch(diagnostic.kind.rule()) {
if let Some(edit) =
fixes::remove_super_arguments(checker.locator(), checker.stylist(), expr)
{
diagnostic.set_fix(Fix::suggested(edit));
}
diagnostic.set_fix(Fix::suggested(Edit::deletion(
call.arguments.start() + TextSize::new(1),
call.arguments.end() - TextSize::new(1),
)));
}
checker.diagnostics.push(diagnostic);
}
/// Returns `true` if a call is an argumented `super` invocation.
fn is_super_call_with_arguments(call: &ast::ExprCall) -> bool {
if let Expr::Name(ast::ExprName { id, .. }) = call.func.as_ref() {
id == "super" && !call.arguments.is_empty()
} else {
false
}
}

View File

@@ -1,11 +1,11 @@
---
source: crates/ruff/src/rules/pyupgrade/mod.rs
---
UP008.py:17:18: UP008 [*] Use `super()` instead of `super(__class__, self)`
UP008.py:17:23: UP008 [*] Use `super()` instead of `super(__class__, self)`
|
16 | def wrong(self):
17 | parent = super(Child, self) # wrong
| ^^^^^^^^^^^^^^^^^^ UP008
| ^^^^^^^^^^^^^ UP008
18 | super(Child, self).method # wrong
19 | super(
|
@@ -21,12 +21,12 @@ UP008.py:17:18: UP008 [*] Use `super()` instead of `super(__class__, self)`
19 19 | super(
20 20 | Child,
UP008.py:18:9: UP008 [*] Use `super()` instead of `super(__class__, self)`
UP008.py:18:14: UP008 [*] Use `super()` instead of `super(__class__, self)`
|
16 | def wrong(self):
17 | parent = super(Child, self) # wrong
18 | super(Child, self).method # wrong
| ^^^^^^^^^^^^^^^^^^ UP008
| ^^^^^^^^^^^^^ UP008
19 | super(
20 | Child,
|
@@ -42,12 +42,12 @@ UP008.py:18:9: UP008 [*] Use `super()` instead of `super(__class__, self)`
20 20 | Child,
21 21 | self,
UP008.py:19:9: UP008 [*] Use `super()` instead of `super(__class__, self)`
UP008.py:19:14: UP008 [*] Use `super()` instead of `super(__class__, self)`
|
17 | parent = super(Child, self) # wrong
18 | super(Child, self).method # wrong
19 | super(
| _________^
| ______________^
20 | | Child,
21 | | self,
22 | | ).method() # wrong
@@ -68,12 +68,12 @@ UP008.py:19:9: UP008 [*] Use `super()` instead of `super(__class__, self)`
24 21 |
25 22 | class BaseClass:
UP008.py:36:9: UP008 [*] Use `super()` instead of `super(__class__, self)`
UP008.py:36:14: UP008 [*] Use `super()` instead of `super(__class__, self)`
|
34 | class MyClass(BaseClass):
35 | def normal(self):
36 | super(MyClass, self).f() # can use super()
| ^^^^^^^^^^^^^^^^^^^^ UP008
| ^^^^^^^^^^^^^^^ UP008
37 | super().f()
|
= help: Remove `super` parameters
@@ -88,11 +88,11 @@ UP008.py:36:9: UP008 [*] Use `super()` instead of `super(__class__, self)`
38 38 |
39 39 | def different_argument(self, other):
UP008.py:50:13: UP008 [*] Use `super()` instead of `super(__class__, self)`
UP008.py:50:18: UP008 [*] Use `super()` instead of `super(__class__, self)`
|
49 | def inner_argument(self):
50 | super(MyClass, self).f() # can use super()
| ^^^^^^^^^^^^^^^^^^^^ UP008
| ^^^^^^^^^^^^^^^ UP008
51 | super().f()
|
= help: Remove `super` parameters