mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-27 12:29:28 +00:00
Respect trailing comma in unnecessary-dict-kwargs (#9015)
Closes https://github.com/astral-sh/ruff/issues/9014.
This commit is contained in:
parent
268d95e911
commit
958702ded0
4 changed files with 38 additions and 10 deletions
|
@ -10,7 +10,6 @@ Foo.objects.create(**{**bar}) # PIE804
|
||||||
|
|
||||||
foo(**{})
|
foo(**{})
|
||||||
|
|
||||||
|
|
||||||
foo(**{**data, "foo": "buzz"})
|
foo(**{**data, "foo": "buzz"})
|
||||||
foo(**buzz)
|
foo(**buzz)
|
||||||
foo(**{"bar-foo": True})
|
foo(**{"bar-foo": True})
|
||||||
|
@ -20,3 +19,5 @@ foo(**{buzz: True})
|
||||||
foo(**{"": True})
|
foo(**{"": True})
|
||||||
foo(**{f"buzz__{bar}": True})
|
foo(**{f"buzz__{bar}": True})
|
||||||
abc(**{"for": 3})
|
abc(**{"for": 3})
|
||||||
|
|
||||||
|
foo(**{},)
|
||||||
|
|
|
@ -543,7 +543,7 @@ pub(crate) fn expression(expr: &Expr, checker: &mut Checker) {
|
||||||
flake8_bugbear::rules::no_explicit_stacklevel(checker, call);
|
flake8_bugbear::rules::no_explicit_stacklevel(checker, call);
|
||||||
}
|
}
|
||||||
if checker.enabled(Rule::UnnecessaryDictKwargs) {
|
if checker.enabled(Rule::UnnecessaryDictKwargs) {
|
||||||
flake8_pie::rules::unnecessary_dict_kwargs(checker, expr, keywords);
|
flake8_pie::rules::unnecessary_dict_kwargs(checker, call);
|
||||||
}
|
}
|
||||||
if checker.enabled(Rule::UnnecessaryRangeStart) {
|
if checker.enabled(Rule::UnnecessaryRangeStart) {
|
||||||
flake8_pie::rules::unnecessary_range_start(checker, call);
|
flake8_pie::rules::unnecessary_range_start(checker, call);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix};
|
use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix};
|
||||||
use ruff_python_ast::{self as ast, Expr, Keyword};
|
use ruff_python_ast::{self as ast, Expr};
|
||||||
|
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
use ruff_text_size::Ranged;
|
use ruff_text_size::Ranged;
|
||||||
|
@ -8,6 +8,7 @@ use ruff_text_size::Ranged;
|
||||||
use ruff_python_stdlib::identifiers::is_identifier;
|
use ruff_python_stdlib::identifiers::is_identifier;
|
||||||
|
|
||||||
use crate::checkers::ast::Checker;
|
use crate::checkers::ast::Checker;
|
||||||
|
use crate::fix::edits::{remove_argument, Parentheses};
|
||||||
|
|
||||||
/// ## What it does
|
/// ## What it does
|
||||||
/// Checks for unnecessary `dict` kwargs.
|
/// Checks for unnecessary `dict` kwargs.
|
||||||
|
@ -52,8 +53,8 @@ impl AlwaysFixableViolation for UnnecessaryDictKwargs {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// PIE804
|
/// PIE804
|
||||||
pub(crate) fn unnecessary_dict_kwargs(checker: &mut Checker, expr: &Expr, kwargs: &[Keyword]) {
|
pub(crate) fn unnecessary_dict_kwargs(checker: &mut Checker, call: &ast::ExprCall) {
|
||||||
for kw in kwargs {
|
for kw in &call.arguments.keywords {
|
||||||
// keyword is a spread operator (indicated by None)
|
// keyword is a spread operator (indicated by None)
|
||||||
if kw.arg.is_some() {
|
if kw.arg.is_some() {
|
||||||
continue;
|
continue;
|
||||||
|
@ -65,7 +66,7 @@ pub(crate) fn unnecessary_dict_kwargs(checker: &mut Checker, expr: &Expr, kwargs
|
||||||
|
|
||||||
// Ex) `foo(**{**bar})`
|
// Ex) `foo(**{**bar})`
|
||||||
if matches!(keys.as_slice(), [None]) {
|
if matches!(keys.as_slice(), [None]) {
|
||||||
let mut diagnostic = Diagnostic::new(UnnecessaryDictKwargs, expr.range());
|
let mut diagnostic = Diagnostic::new(UnnecessaryDictKwargs, call.range());
|
||||||
|
|
||||||
diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement(
|
diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement(
|
||||||
format!("**{}", checker.locator().slice(values[0].range())),
|
format!("**{}", checker.locator().slice(values[0].range())),
|
||||||
|
@ -86,10 +87,18 @@ pub(crate) fn unnecessary_dict_kwargs(checker: &mut Checker, expr: &Expr, kwargs
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut diagnostic = Diagnostic::new(UnnecessaryDictKwargs, expr.range());
|
let mut diagnostic = Diagnostic::new(UnnecessaryDictKwargs, call.range());
|
||||||
|
|
||||||
if values.is_empty() {
|
if values.is_empty() {
|
||||||
diagnostic.set_fix(Fix::safe_edit(Edit::deletion(kw.start(), kw.end())));
|
diagnostic.try_set_fix(|| {
|
||||||
|
remove_argument(
|
||||||
|
kw,
|
||||||
|
&call.arguments,
|
||||||
|
Parentheses::Preserve,
|
||||||
|
checker.locator().contents(),
|
||||||
|
)
|
||||||
|
.map(Fix::safe_edit)
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement(
|
diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement(
|
||||||
kwargs
|
kwargs
|
||||||
|
|
|
@ -106,6 +106,8 @@ PIE804.py:11:1: PIE804 [*] Unnecessary `dict` kwargs
|
||||||
10 |
|
10 |
|
||||||
11 | foo(**{})
|
11 | foo(**{})
|
||||||
| ^^^^^^^^^ PIE804
|
| ^^^^^^^^^ PIE804
|
||||||
|
12 |
|
||||||
|
13 | foo(**{**data, "foo": "buzz"})
|
||||||
|
|
|
|
||||||
= help: Remove unnecessary kwargs
|
= help: Remove unnecessary kwargs
|
||||||
|
|
||||||
|
@ -116,7 +118,23 @@ PIE804.py:11:1: PIE804 [*] Unnecessary `dict` kwargs
|
||||||
11 |-foo(**{})
|
11 |-foo(**{})
|
||||||
11 |+foo()
|
11 |+foo()
|
||||||
12 12 |
|
12 12 |
|
||||||
13 13 |
|
13 13 | foo(**{**data, "foo": "buzz"})
|
||||||
14 14 | foo(**{**data, "foo": "buzz"})
|
14 14 | foo(**buzz)
|
||||||
|
|
||||||
|
PIE804.py:23:1: PIE804 [*] Unnecessary `dict` kwargs
|
||||||
|
|
|
||||||
|
21 | abc(**{"for": 3})
|
||||||
|
22 |
|
||||||
|
23 | foo(**{},)
|
||||||
|
| ^^^^^^^^^^ PIE804
|
||||||
|
|
|
||||||
|
= help: Remove unnecessary kwargs
|
||||||
|
|
||||||
|
ℹ Safe fix
|
||||||
|
20 20 | foo(**{f"buzz__{bar}": True})
|
||||||
|
21 21 | abc(**{"for": 3})
|
||||||
|
22 22 |
|
||||||
|
23 |-foo(**{},)
|
||||||
|
23 |+foo()
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue