{"record":{"id":"becffe90e4777a3a","repo":"astral-sh/ruff","slug":"expected-tuple-or-list-for-dictionary-comprehensio","errorCode":null,"errorMessage":"Expected tuple or list for dictionary comprehension","messagePattern":"Expected tuple or list for dictionary comprehension","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"crates/ruff_linter/src/rules/flake8_comprehensions/fixes.rs","lineNumber":778,"sourceCode":"                rpar: vec![],\n            }));\n        }\n        ObjectType::Set => {\n            tree = Expression::SetComp(Box::new(SetComp {\n                elt: lambda.body.clone(),\n                for_in: compfor,\n                lpar: vec![],\n                rpar: vec![],\n                lbrace: LeftCurlyBrace::default(),\n                rbrace: RightCurlyBrace::default(),\n            }));\n        }\n        ObjectType::Dict => {\n            let elements = match lambda.body.as_ref() {\n                Expression::Tuple(tuple) => &tuple.elements,\n                Expression::List(list) => &list.elements,\n                _ => {\n                    bail!(\"Expected tuple or list for dictionary comprehension\")\n                }\n            };\n            let [key, value] = elements.as_slice() else {\n                bail!(\"Expected container to include two elements\");\n            };\n            let Element::Simple { value: key, .. } = key else {\n                bail!(\"Expected container to use a key as the first element\");\n            };\n            let Element::Simple { value, .. } = value else {\n                bail!(\"Expected container to use a value as the second element\");\n            };\n\n            tree = Expression::DictComp(Box::new(DictComp {\n                for_in: compfor,\n                lpar: vec![],\n                rpar: vec![],\n                key: Box::new(key.clone()),\n                value: Box::new(value.clone()),","sourceCodeStart":760,"sourceCodeEnd":796,"githubUrl":"https://github.com/astral-sh/ruff/blob/26f38c119cac42e4d320ba08f09224fdec74af2c/crates/ruff_linter/src/rules/flake8_comprehensions/fixes.rs#L760-L796","documentation":"Part of the C417 fix that converts `dict(map(lambda x: (k, v), it))` into a dict comprehension. For the dict target type the lambda body must be a tuple or list literal of key/value elements; any other body expression cannot be transformed, so the fixer bails.","triggerScenarios":"`ruff check --fix` on `dict(map(lambda x: f(x), items))` or `dict(map(lambda x: (x[0], x[1], x[2]), items))` where the lambda body is a call, name, or a longer tuple.","commonSituations":"Lambdas returning computed pairs via function calls; star-unpacking bodies like `lambda x: (*a, *b)`; stale diagnostics after edits.","solutions":["Re-run ruff so the fix sees current code.","Rewrite manually: `dict(map(lambda x: (k(x), v(x)), it))` -> `{k(x): v(x) for x in it}`.","Add `# noqa: C417` if the lambda body is intentionally not a literal pair."],"exampleFix":"// before\nconfig = dict(map(lambda kv: (kv[0], kv[1]), pairs))\n// after\nconfig = {kv[0]: kv[1] for kv in pairs}","handlingStrategy":"type-guard","validationCode":"ok = isinstance(l.body, (ast.Tuple, ast.List))","typeGuard":"def is_pair_literal(lam):\n    return isinstance(lam, ast.Lambda) and isinstance(lam.body, (ast.Tuple, ast.List))","tryCatchPattern":"try:\n    apply_autofix(diagnostic)\nexcept Exception:\n    write_dict_comp_manually()","preventionTips":["Make dict-conversion lambda bodies literal pairs","Avoid function-call bodies in C417-targeted lambdas","Re-run ruff after edits"],"tags":["rust","ruff","lint-autofix","flake8-comprehensions"],"backgroundTag":"autofix-unsupported-ast-shape","analyzedSha":"26f38c119cac42e4d320ba08f09224fdec74af2c","analyzedAt":"2026-09-05T10:32:37.492Z","contentChangedAt":"2026-09-05T10:32:37.492Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}