diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_comprehensions/C410.py b/crates/ruff_linter/resources/test/fixtures/flake8_comprehensions/C410.py index 6e6c977bb6472e..2f8ef83b4e7e01 100644 --- a/crates/ruff_linter/resources/test/fixtures/flake8_comprehensions/C410.py +++ b/crates/ruff_linter/resources/test/fixtures/flake8_comprehensions/C410.py @@ -11,3 +11,7 @@ list([ # comment 1, 2 ]) + +# Skip when too many positional arguments +# See https://github.com/astral-sh/ruff/issues/15810 +list([1],[2]) diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_comprehensions/C411.py b/crates/ruff_linter/resources/test/fixtures/flake8_comprehensions/C411.py index 8cb272217b8810..8d1ce8b1266cc2 100644 --- a/crates/ruff_linter/resources/test/fixtures/flake8_comprehensions/C411.py +++ b/crates/ruff_linter/resources/test/fixtures/flake8_comprehensions/C411.py @@ -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=[]) diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_comprehensions/C418.py b/crates/ruff_linter/resources/test/fixtures/flake8_comprehensions/C418.py index 01e9be2c0d5975..0663ed0f088eb3 100644 --- a/crates/ruff_linter/resources/test/fixtures/flake8_comprehensions/C418.py +++ b/crates/ruff_linter/resources/test/fixtures/flake8_comprehensions/C418.py @@ -8,3 +8,6 @@ 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}) diff --git a/crates/ruff_linter/src/checkers/ast/analyze/expression.rs b/crates/ruff_linter/src/checkers/ast/analyze/expression.rs index e2ea12bc5eb2bc..b2e67ae6eb6431 100644 --- a/crates/ruff_linter/src/checkers/ast/analyze/expression.rs +++ b/crates/ruff_linter/src/checkers/ast/analyze/expression.rs @@ -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( diff --git a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_list_call.rs b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_list_call.rs index 5696bfee75efb7..e4e67a5406d0ca 100644 --- a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_list_call.rs +++ b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_list_call.rs @@ -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; }; diff --git a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_literal_within_dict_call.rs b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_literal_within_dict_call.rs index b3c61b013563a9..fab2b7042a5e72 100644 --- a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_literal_within_dict_call.rs +++ b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_literal_within_dict_call.rs @@ -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 { diff --git a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_literal_within_list_call.rs b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_literal_within_list_call.rs index 7dbc47496bb2e7..056277a3054fa8 100644 --- a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_literal_within_list_call.rs +++ b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_literal_within_list_call.rs @@ -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 { diff --git a/crates/ruff_linter/src/rules/flake8_comprehensions/snapshots/ruff_linter__rules__flake8_comprehensions__tests__C410_C410.py.snap b/crates/ruff_linter/src/rules/flake8_comprehensions/snapshots/ruff_linter__rules__flake8_comprehensions__tests__C410_C410.py.snap index 9f9152383b8d17..35dd289c787399 100644 --- a/crates/ruff_linter/src/rules/flake8_comprehensions/snapshots/ruff_linter__rules__flake8_comprehensions__tests__C410_C410.py.snap +++ b/crates/ruff_linter/src/rules/flake8_comprehensions/snapshots/ruff_linter__rules__flake8_comprehensions__tests__C410_C410.py.snap @@ -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 diff --git a/crates/ruff_linter/src/rules/flake8_comprehensions/snapshots/ruff_linter__rules__flake8_comprehensions__tests__C411_C411.py.snap b/crates/ruff_linter/src/rules/flake8_comprehensions/snapshots/ruff_linter__rules__flake8_comprehensions__tests__C411_C411.py.snap index 16d2a3c61c6057..84882a467437de 100644 --- a/crates/ruff_linter/src/rules/flake8_comprehensions/snapshots/ruff_linter__rules__flake8_comprehensions__tests__C411_C411.py.snap +++ b/crates/ruff_linter/src/rules/flake8_comprehensions/snapshots/ruff_linter__rules__flake8_comprehensions__tests__C411_C411.py.snap @@ -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.