astral-sh/ruff · warning

Expected Expression::ListComp | Expression:SetComp | Express

Error message

Expected Expression::ListComp | Expression:SetComp | Expression:DictComp

What it means

Raised by the C416/unnecessary-comprehension fix, which rewrites `list(...)`, `set(...)`, and `dict(...)` calls built from redundant comprehensions. If the expression is not a list/set/dict comprehension, the fixer has no rewrite and bails with this message.

Source

Thrown at crates/ruff_linter/src/rules/flake8_comprehensions/fixes.rs:654

                    rpar: vec![],
                }))),
                args: vec![Arg {
                    value: inner.for_in.iter.clone(),
                    keyword: None,
                    equal: None,
                    comma: None,
                    star: "",
                    whitespace_after_star: ParenthesizableWhitespace::default(),
                    whitespace_after_arg: ParenthesizableWhitespace::default(),
                }],
                lpar: vec![],
                rpar: vec![],
                whitespace_after_func: ParenthesizableWhitespace::default(),
                whitespace_before_args: ParenthesizableWhitespace::default(),
            }));
        }
        _ => {
            bail!("Expected Expression::ListComp | Expression:SetComp | Expression:DictComp");
        }
    }

    Ok(Edit::range_replacement(
        pad(tree.codegen_stylist(stylist), expr.range(), locator),
        expr.range(),
    ))
}

/// (C417) Convert `map(lambda x: x * 2, bar)` to `(x * 2 for x in bar)`.
pub(crate) fn fix_unnecessary_map(
    call_ast_node: &ExprCall,
    parent: Option<&Expr>,
    object_type: ObjectType,
    locator: &Locator,
    stylist: &Stylist,
) -> Result<Edit> {
    let module_text = locator.slice(call_ast_node);

View on GitHub (pinned to 26f38c119c)

Solutions

  1. Re-run `ruff check --fix` on the current file to refresh diagnostics.
  2. Replace the redundant comprehension manually: `[x for x in items]` -> `list(items)`.
  3. Ignore the fix and keep the diagnostic (`--fix-only` without this rule's fixes or a noqa).

Example fix

// before
values = [x for x in items]
// after
values = list(items)
Defensive patterns

Strategy: type-guard

Validate before calling

ok = isinstance(node, (ast.ListComp, ast.SetComp, ast.DictComp))

Type guard

def is_comprehension(expr):
    return isinstance(expr, (ast.ListComp, ast.SetComp, ast.DictComp))

Try / catch

try:
    apply_autofix(diagnostic)
except Exception:
    rewrite_comprehension_manually()

Prevention

When it happens

Trigger: `ruff check --fix` where the flagged expression is a comprehension-like node of an unexpected kind (e.g. a generator expression or parenthesized variant not covered by the match arms).

Common situations: Stale diagnostics after code edits; new AST node kinds introduced by parser changes not yet handled by the fixer; hand-crafted inputs to the fix API.

Related errors


AI-assisted analysis of astral-sh/ruff@26f38c119c (2026-09-05). Data as JSON: /api/errors/fdc839d8adf7a0bb. Report an issue: GitHub.