[flake8-comprehensions] Skip when TypeError present from too many (kw)args for C410,C411, and C418 (#15838)

Both `list` and `dict` expect only a single positional argument. Giving
more positional arguments, or a keyword argument, is a `TypeError` and
neither the lint rule nor its fix make sense in that context.

Closes #15810
This commit is contained in:
Dylan 2025-01-30 17:10:43 -06:00 committed by GitHub
parent fe516e24f5
commit 071862af5a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 52 additions and 8 deletions

View file

@ -11,3 +11,7 @@ list( # comment
list([ # comment
1, 2
])
# Skip when too many positional arguments
# See https://github.com/astral-sh/ruff/issues/15810
list([1],[2])

View file

@ -1,2 +1,8 @@
x = [1, 2, 3]
list([i for i in x])
# Skip when too many positional arguments
# or keyword argument present.
# See https://github.com/astral-sh/ruff/issues/15810
list([x for x in "XYZ"],[])
list([x for x in "XYZ"],foo=[])

View file

@ -8,3 +8,6 @@ dict(
dict({}, a=1)
dict({x: 1 for x in range(1)}, a=1)
# Skip when too many positional arguments
# See https://github.com/astral-sh/ruff/issues/15810
dict({"A": 1}, {"B": 2})

View file

@ -826,7 +826,7 @@ pub(crate) fn expression(expr: &Expr, checker: &mut Checker) {
flake8_comprehensions::rules::unnecessary_literal_within_dict_call(checker, call);
}
if checker.enabled(Rule::UnnecessaryListCall) {
flake8_comprehensions::rules::unnecessary_list_call(checker, expr, func, args);
flake8_comprehensions::rules::unnecessary_list_call(checker, expr, call);
}
if checker.enabled(Rule::UnnecessaryCallAroundSorted) {
flake8_comprehensions::rules::unnecessary_call_around_sorted(

View file

@ -1,4 +1,4 @@
use ruff_python_ast::Expr;
use ruff_python_ast::{Arguments, Expr, ExprCall};
use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Fix};
use ruff_macros::{derive_message_formats, ViolationMetadata};
@ -44,12 +44,27 @@ impl AlwaysFixableViolation for UnnecessaryListCall {
}
/// C411
pub(crate) fn unnecessary_list_call(
checker: &mut Checker,
expr: &Expr,
func: &Expr,
args: &[Expr],
) {
pub(crate) fn unnecessary_list_call(checker: &mut Checker, expr: &Expr, call: &ExprCall) {
let ExprCall {
func,
arguments,
range: _,
} = call;
if !arguments.keywords.is_empty() {
return;
}
if arguments.args.len() > 1 {
return;
}
let Arguments {
range: _,
args,
keywords: _,
} = arguments;
let Some(argument) = helpers::first_argument_with_matching_function("list", func, args) else {
return;
};

View file

@ -56,6 +56,9 @@ pub(crate) fn unnecessary_literal_within_dict_call(checker: &mut Checker, call:
if !call.arguments.keywords.is_empty() {
return;
}
if call.arguments.args.len() > 1 {
return;
}
let Some(argument) =
helpers::first_argument_with_matching_function("dict", &call.func, &call.arguments.args)
else {

View file

@ -67,6 +67,9 @@ pub(crate) fn unnecessary_literal_within_list_call(checker: &mut Checker, call:
if !call.arguments.keywords.is_empty() {
return;
}
if call.arguments.args.len() > 1 {
return;
}
let Some(argument) =
helpers::first_argument_with_matching_function("list", &call.func, &call.arguments.args)
else {

View file

@ -104,6 +104,8 @@ C410.py:11:1: C410 [*] Unnecessary list literal passed to `list()` (remove the o
12 | | 1, 2
13 | | ])
| |__^ C410
14 |
15 | # Skip when too many positional arguments
|
= help: Remove outer `list()` call
@ -116,3 +118,6 @@ C410.py:11:1: C410 [*] Unnecessary list literal passed to `list()` (remove the o
12 12 | 1, 2
13 |-])
13 |+]
14 14 |
15 15 | # Skip when too many positional arguments
16 16 | # See https://github.com/astral-sh/ruff/issues/15810

View file

@ -6,6 +6,8 @@ C411.py:2:1: C411 [*] Unnecessary `list()` call (remove the outer call to `list(
1 | x = [1, 2, 3]
2 | list([i for i in x])
| ^^^^^^^^^^^^^^^^^^^^ C411
3 |
4 | # Skip when too many positional arguments
|
= help: Remove outer `list()` call
@ -13,3 +15,6 @@ C411.py:2:1: C411 [*] Unnecessary `list()` call (remove the outer call to `list(
1 1 | x = [1, 2, 3]
2 |-list([i for i in x])
2 |+[i for i in x]
3 3 |
4 4 | # Skip when too many positional arguments
5 5 | # or keyword argument present.