Skip to content

Commit

Permalink
Do not report consider_iterating_dictionary if bitwise operations a…
Browse files Browse the repository at this point in the history
…re used (#7743)


Co-authored-by: Pierre Sassoulas <pierre.sassoulas@gmail.com>
  • Loading branch information
clavedeluna and Pierre-Sassoulas committed Nov 10, 2022
1 parent 18950d8 commit c289271
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 29 deletions.
3 changes: 3 additions & 0 deletions doc/whatsnew/fragments/5478.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
``consider-iterating-dictionary`` will no longer be raised if bitwise operations are used.

Closes #5478
9 changes: 8 additions & 1 deletion pylint/checkers/refactoring/recommendation_checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

from pylint import checkers
from pylint.checkers import utils
from pylint.interfaces import INFERENCE


class RecommendationChecker(checkers.BaseChecker):
Expand Down Expand Up @@ -85,6 +86,10 @@ def _check_consider_iterating_dictionary(self, node: nodes.Call) -> None:
return
if node.func.attrname != "keys":
return

if isinstance(node.parent, nodes.BinOp) and node.parent.op in {"&", "|", "^"}:
return

comp_ancestor = utils.get_node_first_ancestor_of_type(node, nodes.Compare)
if (
isinstance(node.parent, (nodes.For, nodes.Comprehension))
Expand All @@ -101,7 +106,9 @@ def _check_consider_iterating_dictionary(self, node: nodes.Call) -> None:
inferred.bound, nodes.Dict
):
return
self.add_message("consider-iterating-dictionary", node=node)
self.add_message(
"consider-iterating-dictionary", node=node, confidence=INFERENCE
)

def _check_use_maxsplit_arg(self, node: nodes.Call) -> None:
"""Add message when accessing first or last elements of a str.split() or
Expand Down
22 changes: 22 additions & 0 deletions tests/functional/c/consider/consider_iterating_dictionary.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,3 +92,25 @@ def inner_function():
print("a" in another_metadata.keys()) # [consider-iterating-dictionary]
return inner_function()
return InnerClass().another_function()

a_dict = {"a": 1, "b": 2, "c": 3}
a_set = {"c", "d"}

# Test bitwise operations. These should not raise msg because removing `.keys()`
# either gives error or ends in a different result
print(a_dict.keys() | a_set)

if "a" in a_dict.keys() | a_set:
pass

if "a" in a_dict.keys() & a_set:
pass

if 1 in a_dict.keys() ^ [1, 2]:
pass

if "a" in a_dict.keys() or a_set: # [consider-iterating-dictionary]
pass

if "a" in a_dict.keys() and a_set: # [consider-iterating-dictionary]
pass
54 changes: 28 additions & 26 deletions tests/functional/c/consider/consider_iterating_dictionary.txt
Original file line number Diff line number Diff line change
@@ -1,26 +1,28 @@
consider-iterating-dictionary:25:16:25:25::Consider iterating the dictionary directly instead of calling .keys():UNDEFINED
consider-iterating-dictionary:26:16:26:25::Consider iterating the dictionary directly instead of calling .keys():UNDEFINED
consider-iterating-dictionary:27:16:27:25::Consider iterating the dictionary directly instead of calling .keys():UNDEFINED
consider-iterating-dictionary:28:21:28:30::Consider iterating the dictionary directly instead of calling .keys():UNDEFINED
consider-iterating-dictionary:29:24:29:33::Consider iterating the dictionary directly instead of calling .keys():UNDEFINED
consider-iterating-dictionary:30:24:30:33::Consider iterating the dictionary directly instead of calling .keys():UNDEFINED
consider-iterating-dictionary:31:24:31:33::Consider iterating the dictionary directly instead of calling .keys():UNDEFINED
consider-iterating-dictionary:32:29:32:38::Consider iterating the dictionary directly instead of calling .keys():UNDEFINED
consider-iterating-dictionary:33:11:33:20::Consider iterating the dictionary directly instead of calling .keys():UNDEFINED
consider-iterating-dictionary:38:24:38:35::Consider iterating the dictionary directly instead of calling .keys():UNDEFINED
consider-iterating-dictionary:38:55:38:66::Consider iterating the dictionary directly instead of calling .keys():UNDEFINED
consider-iterating-dictionary:39:31:39:42::Consider iterating the dictionary directly instead of calling .keys():UNDEFINED
consider-iterating-dictionary:39:61:39:72::Consider iterating the dictionary directly instead of calling .keys():UNDEFINED
consider-iterating-dictionary:40:30:40:41::Consider iterating the dictionary directly instead of calling .keys():UNDEFINED
consider-iterating-dictionary:40:60:40:71::Consider iterating the dictionary directly instead of calling .keys():UNDEFINED
consider-iterating-dictionary:43:8:43:21::Consider iterating the dictionary directly instead of calling .keys():UNDEFINED
consider-iterating-dictionary:45:8:45:17::Consider iterating the dictionary directly instead of calling .keys():UNDEFINED
consider-iterating-dictionary:65:11:65:20::Consider iterating the dictionary directly instead of calling .keys():UNDEFINED
consider-iterating-dictionary:73:19:73:34::Consider iterating the dictionary directly instead of calling .keys():UNDEFINED
consider-iterating-dictionary:75:14:75:29::Consider iterating the dictionary directly instead of calling .keys():UNDEFINED
consider-iterating-dictionary:77:15:77:30::Consider iterating the dictionary directly instead of calling .keys():UNDEFINED
consider-iterating-dictionary:79:10:79:25::Consider iterating the dictionary directly instead of calling .keys():UNDEFINED
consider-iterating-dictionary:89:42:89:65:AClass.a_function.InnerClass.another_function.inner_function:Consider iterating the dictionary directly instead of calling .keys():UNDEFINED
consider-iterating-dictionary:90:37:90:60:AClass.a_function.InnerClass.another_function.inner_function:Consider iterating the dictionary directly instead of calling .keys():UNDEFINED
consider-iterating-dictionary:91:38:91:61:AClass.a_function.InnerClass.another_function.inner_function:Consider iterating the dictionary directly instead of calling .keys():UNDEFINED
consider-iterating-dictionary:92:33:92:56:AClass.a_function.InnerClass.another_function.inner_function:Consider iterating the dictionary directly instead of calling .keys():UNDEFINED
consider-iterating-dictionary:25:16:25:25::Consider iterating the dictionary directly instead of calling .keys():INFERENCE
consider-iterating-dictionary:26:16:26:25::Consider iterating the dictionary directly instead of calling .keys():INFERENCE
consider-iterating-dictionary:27:16:27:25::Consider iterating the dictionary directly instead of calling .keys():INFERENCE
consider-iterating-dictionary:28:21:28:30::Consider iterating the dictionary directly instead of calling .keys():INFERENCE
consider-iterating-dictionary:29:24:29:33::Consider iterating the dictionary directly instead of calling .keys():INFERENCE
consider-iterating-dictionary:30:24:30:33::Consider iterating the dictionary directly instead of calling .keys():INFERENCE
consider-iterating-dictionary:31:24:31:33::Consider iterating the dictionary directly instead of calling .keys():INFERENCE
consider-iterating-dictionary:32:29:32:38::Consider iterating the dictionary directly instead of calling .keys():INFERENCE
consider-iterating-dictionary:33:11:33:20::Consider iterating the dictionary directly instead of calling .keys():INFERENCE
consider-iterating-dictionary:38:24:38:35::Consider iterating the dictionary directly instead of calling .keys():INFERENCE
consider-iterating-dictionary:38:55:38:66::Consider iterating the dictionary directly instead of calling .keys():INFERENCE
consider-iterating-dictionary:39:31:39:42::Consider iterating the dictionary directly instead of calling .keys():INFERENCE
consider-iterating-dictionary:39:61:39:72::Consider iterating the dictionary directly instead of calling .keys():INFERENCE
consider-iterating-dictionary:40:30:40:41::Consider iterating the dictionary directly instead of calling .keys():INFERENCE
consider-iterating-dictionary:40:60:40:71::Consider iterating the dictionary directly instead of calling .keys():INFERENCE
consider-iterating-dictionary:43:8:43:21::Consider iterating the dictionary directly instead of calling .keys():INFERENCE
consider-iterating-dictionary:45:8:45:17::Consider iterating the dictionary directly instead of calling .keys():INFERENCE
consider-iterating-dictionary:65:11:65:20::Consider iterating the dictionary directly instead of calling .keys():INFERENCE
consider-iterating-dictionary:73:19:73:34::Consider iterating the dictionary directly instead of calling .keys():INFERENCE
consider-iterating-dictionary:75:14:75:29::Consider iterating the dictionary directly instead of calling .keys():INFERENCE
consider-iterating-dictionary:77:15:77:30::Consider iterating the dictionary directly instead of calling .keys():INFERENCE
consider-iterating-dictionary:79:10:79:25::Consider iterating the dictionary directly instead of calling .keys():INFERENCE
consider-iterating-dictionary:89:42:89:65:AClass.a_function.InnerClass.another_function.inner_function:Consider iterating the dictionary directly instead of calling .keys():INFERENCE
consider-iterating-dictionary:90:37:90:60:AClass.a_function.InnerClass.another_function.inner_function:Consider iterating the dictionary directly instead of calling .keys():INFERENCE
consider-iterating-dictionary:91:38:91:61:AClass.a_function.InnerClass.another_function.inner_function:Consider iterating the dictionary directly instead of calling .keys():INFERENCE
consider-iterating-dictionary:92:33:92:56:AClass.a_function.InnerClass.another_function.inner_function:Consider iterating the dictionary directly instead of calling .keys():INFERENCE
consider-iterating-dictionary:112:10:112:23::Consider iterating the dictionary directly instead of calling .keys():INFERENCE
consider-iterating-dictionary:115:10:115:23::Consider iterating the dictionary directly instead of calling .keys():INFERENCE
4 changes: 2 additions & 2 deletions tests/functional/c/consider/consider_using_dict_items.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ consider-using-dict-items:9:4:10:30:bad:Consider iterating with .items():UNDEFIN
consider-using-dict-items:21:4:22:35:another_bad:Consider iterating with .items():UNDEFINED
consider-using-dict-items:40:0:42:18::Consider iterating with .items():UNDEFINED
consider-using-dict-items:44:0:45:20::Consider iterating with .items():UNDEFINED
consider-iterating-dictionary:47:10:47:23::Consider iterating the dictionary directly instead of calling .keys():UNDEFINED
consider-iterating-dictionary:47:10:47:23::Consider iterating the dictionary directly instead of calling .keys():INFERENCE
consider-using-dict-items:47:0:48:20::Consider iterating with .items():UNDEFINED
consider-using-dict-items:54:0:55:24::Consider iterating with .items():UNDEFINED
consider-using-dict-items:67:0:None:None::Consider iterating with .items():UNDEFINED
consider-using-dict-items:68:0:None:None::Consider iterating with .items():UNDEFINED
consider-using-dict-items:71:0:None:None::Consider iterating with .items():UNDEFINED
consider-using-dict-items:72:0:None:None::Consider iterating with .items():UNDEFINED
consider-using-dict-items:75:0:None:None::Consider iterating with .items():UNDEFINED
consider-iterating-dictionary:86:25:86:42::Consider iterating the dictionary directly instead of calling .keys():UNDEFINED
consider-iterating-dictionary:86:25:86:42::Consider iterating the dictionary directly instead of calling .keys():INFERENCE
consider-using-dict-items:86:0:None:None::Consider iterating with .items():UNDEFINED
consider-using-dict-items:103:0:105:24::Consider iterating with .items():UNDEFINED

0 comments on commit c289271

Please sign in to comment.