Skip to content

Commit

Permalink
Fix false positives in PD002 (#4337)
Browse files Browse the repository at this point in the history
  • Loading branch information
evanrittenhouse authored May 10, 2023
1 parent a2b8487 commit 04097d1
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 1 deletion.
2 changes: 2 additions & 0 deletions crates/ruff/resources/test/fixtures/pandas_vet/PD002.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,5 @@
f(x.drop(["a"], axis=1, inplace=True))

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
3 changes: 2 additions & 1 deletion crates/ruff/src/checkers/ast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2902,7 +2902,8 @@ where
.enabled(Rule::PandasUseOfInplaceArgument)
{
self.diagnostics.extend(
pandas_vet::rules::inplace_argument(self, expr, args, keywords).into_iter(),
pandas_vet::rules::inplace_argument(self, expr, func, args, keywords)
.into_iter(),
);
}
pandas_vet::rules::check_call(self, func);
Expand Down
27 changes: 27 additions & 0 deletions crates/ruff/src/rules/pandas_vet/rules/inplace_argument.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use ruff_python_semantic::binding::{BindingKind, Importation};
use rustpython_parser::ast::{Constant, Expr, ExprKind, Keyword, StmtKind};

use ruff_diagnostics::{AutofixKind, Diagnostic, Violation};
Expand Down Expand Up @@ -51,10 +52,29 @@ impl Violation for PandasUseOfInplaceArgument {
pub fn inplace_argument(
checker: &Checker,
expr: &Expr,
func: &Expr,
args: &[Expr],
keywords: &[Keyword],
) -> Option<Diagnostic> {
let mut seen_star = false;
let mut is_checkable = false;
let mut is_pandas = false;

if let Some(call_path) = checker.ctx.resolve_call_path(func) {
is_checkable = true;

let module = call_path[0];
is_pandas = checker.ctx.find_binding(module).map_or(false, |binding| {
matches!(
binding.kind,
BindingKind::Importation(Importation {
full_name: "pandas",
..
})
)
});
}

for keyword in keywords.iter().rev() {
let Some(arg) = &keyword.node.arg else {
seen_star = true;
Expand Down Expand Up @@ -94,6 +114,13 @@ pub fn inplace_argument(
diagnostic.set_fix(fix);
}
}

// Without a static type system, only module-level functions could potentially be
// non-pandas calls. If they're not, `inplace` should be considered safe.
if is_checkable && !is_pandas {
return None;
}

return Some(diagnostic);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,8 @@ PD002.py:26:38: PD002 `inplace=True` should be avoided; it has inconsistent beha
27 |
28 | x.apply(lambda x: x.sort_values('a', inplace=True))
| ^^^^^^^^^^^^ PD002
29 | import torch
30 | torch.m.ReLU(inplace=True) # safe because this isn't a pandas call
|
= help: Assign to variable; remove `inplace` arg

Expand Down

0 comments on commit 04097d1

Please sign in to comment.