Add FURB193: suggest dict.setdefault() over get-and-assign pattern#365
Add FURB193: suggest dict.setdefault() over get-and-assign pattern#365worksbyfriday wants to merge 3 commits into
Conversation
Detects `d[key] = d.get(key, default)` and suggests using `d.setdefault(key, default)` instead, which is more idiomatic and avoids the redundant dict lookup. Works with any MutableMapping subclass (dict, OrderedDict, defaultdict, etc.). Only triggers when both the target dict and key in the assignment match the dict and key in the .get() call. Closes dosisod#349 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
This is a nice improvement! I don't particularly use this idiom much, but I can see it be useful in other code. Any reason why |
Per dosisod's review: d[key] = d.get(key) has the same semantics as d.setdefault(key), which sets the key to None if not present. Changed match pattern from args=[get_key_expr, _] to args=[get_key_expr, *_] to accept 1 or 2 arguments. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
Good catch! I've updated the match pattern from |
get_mypy_type() expects Node, not object. Since expr comes from IndexExpr.base which is an Expression, type the parameter accordingly. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
@Fridayai700 it doesn't look like a test case was added |
|
The test case for d["x"] = d.get("x")And the corresponding expected output is in The mypy fix in the latest commit (8733596) changed the type annotation from |
Summary
Closes #349.
Adds a new check (FURB193) that detects the pattern
d[key] = d.get(key, default)and suggests usingd.setdefault(key, default)instead.The check works with any
MutableMappingsubclass (dict,OrderedDict,defaultdict, etc.) and only triggers when:.get()receiver dict.get()key argument.get()is called with exactly 2 arguments (a key and a default)It correctly ignores cases with different keys, different dicts, missing default argument, or non-
.get()calls.Test plan
test/data/err_193.pywith positive and negative test casestest/data/err_193.txtwith expected outputrefurb --explain FURB193produces correct documentationdict,OrderedDict, anddefaultdict— all correctly detected