Handle parenthesized calls in PD002 (#7111)

This commit is contained in:
Charlie Marsh 2023-09-03 22:03:55 +01:00 committed by GitHub
parent d9cf31f355
commit 911d4f2918
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 32 additions and 6 deletions

View File

@ -29,3 +29,5 @@ x.apply(lambda x: x.sort_values("a", inplace=True))
import torch
torch.m.ReLU(inplace=True) # safe because this isn't a pandas call
(x.drop(["a"], axis=1, inplace=True))

View File

@ -1,7 +1,8 @@
use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation};
use ruff_macros::{derive_message_formats, violation};
use ruff_python_ast::helpers::is_const_true;
use ruff_python_ast::{self as ast, Keyword};
use ruff_python_ast::parenthesize::parenthesized_range;
use ruff_python_ast::{self as ast, Keyword, Stmt};
use ruff_source_file::Locator;
use ruff_text_size::Ranged;
@ -75,13 +76,17 @@ pub(crate) fn inplace_argument(checker: &mut Checker, call: &ast::ExprCall) {
// the star argument _doesn't_ contain an override).
// 2. The call is part of a larger expression (we're converting an expression to a
// statement, and expressions can't contain statements).
let statement = checker.semantic().current_statement();
if !seen_star
&& checker.semantic().current_statement().is_expr_stmt()
&& checker.semantic().current_expression_parent().is_none()
&& statement.is_expr_stmt()
{
if let Some(fix) =
convert_inplace_argument_to_assignment(call, keyword, checker.locator())
{
if let Some(fix) = convert_inplace_argument_to_assignment(
call,
keyword,
statement,
checker.locator(),
) {
diagnostic.set_fix(fix);
}
}
@ -101,13 +106,16 @@ pub(crate) fn inplace_argument(checker: &mut Checker, call: &ast::ExprCall) {
fn convert_inplace_argument_to_assignment(
call: &ast::ExprCall,
keyword: &Keyword,
statement: &Stmt,
locator: &Locator,
) -> Option<Fix> {
// Add the assignment.
let attr = call.func.as_attribute_expr()?;
let insert_assignment = Edit::insertion(
format!("{name} = ", name = locator.slice(attr.value.range())),
call.start(),
parenthesized_range(call.into(), statement.into(), locator.contents())
.unwrap_or(call.range())
.start(),
);
// Remove the `inplace` argument.

View File

@ -158,4 +158,20 @@ PD002.py:28:38: PD002 `inplace=True` should be avoided; it has inconsistent beha
|
= help: Assign to variable; remove `inplace` arg
PD002.py:33:24: PD002 [*] `inplace=True` should be avoided; it has inconsistent behavior
|
31 | torch.m.ReLU(inplace=True) # safe because this isn't a pandas call
32 |
33 | (x.drop(["a"], axis=1, inplace=True))
| ^^^^^^^^^^^^ PD002
|
= help: Assign to variable; remove `inplace` arg
Suggested fix
30 30 |
31 31 | torch.m.ReLU(inplace=True) # safe because this isn't a pandas call
32 32 |
33 |-(x.drop(["a"], axis=1, inplace=True))
33 |+x = (x.drop(["a"], axis=1))