Skip to content

Commit ef250da

Browse files
fix(4716): fix false positive unnecessary_dict_index_lookup emitted when del is used (#5344)
* fix(4716): fix false positive `unnecessary_dict_index_lookup` emitted when `del` is used Co-authored-by: Pierre Sassoulas <[email protected]>
1 parent 5bb0095 commit ef250da

File tree

5 files changed

+36
-9
lines changed

5 files changed

+36
-9
lines changed

ChangeLog

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,14 @@ Release date: TBA
1414
* Some files in ``pylint.testutils`` were deprecated. In the future imports should be done from the
1515
``pylint.testutils.functional`` namespace directly.
1616

17-
..
18-
Insert your changelog randomly, it will reduce merge conflicts
19-
(Ie. not necessarily at the end)
17+
* Fix ``unnecessary_dict_index_lookup`` false positive when deleting a dictionary's entry.
2018

19+
Closes #4716
2120

22-
What's New in Pylint 2.12.3?
23-
============================
24-
Release date: TBA
25-
26-
..
27-
Put bug fixes that should not wait for a new minor version here
21+
* Fix false negative for ``consider-iterating-dictionary`` during membership checks encapsulated in iterables
22+
or ``not in`` checks
2823

24+
Closes #5323
2925

3026
..
3127
Insert your changelog randomly, it will reduce merge conflicts

doc/whatsnew/2.13.rst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,15 @@ Extensions
2222
Other Changes
2323
=============
2424

25+
* Fix ``unnecessary_dict_index_lookup`` false positive when deleting a dictionary's entry.
26+
27+
Closes #4716
28+
29+
* Fix false negative for ``consider-iterating-dictionary`` during membership checks encapsulated in iterables
30+
or ``not in`` checks
31+
32+
Closes #5323
33+
2534
* Require Python ``3.6.2`` to run pylint.
2635

2736
Closes #5065

pylint/checkers/refactoring/refactoring_checker.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1873,6 +1873,9 @@ def _check_unnecessary_dict_index_lookup(
18731873
# Ignore this subscript if it is the target of an assignment
18741874
# Early termination; after reassignment dict index lookup will be necessary
18751875
return
1876+
if isinstance(subscript.parent, nodes.Delete):
1877+
# Ignore this subscript if it's used with the delete keyword
1878+
return
18761879

18771880
# Case where .items is assigned to k,v (i.e., for k, v in d.items())
18781881
if isinstance(value, nodes.Name):

tests/functional/u/unnecessary/unnecessary_dict_index_lookup.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,3 +82,21 @@ class Foo:
8282
if 'V' in d[k]: # [unnecessary-dict-index-lookup]
8383
d[k] = "value"
8484
print(d[k]) # This is fine
85+
86+
# Test false positive described in #4716
87+
# Should not be emitted for del
88+
# (https://github.com/PyCQA/pylint/issues/4716)
89+
d = {}
90+
for key, val in d.items():
91+
del d[key]
92+
break
93+
94+
for item in d.items():
95+
del d[item[0]]
96+
break
97+
98+
outer_dict = {"inner_dict": {}}
99+
for key, val in outer_dict.items():
100+
for key_two, val_two in val.items():
101+
del outer_dict[key][key_two] # [unnecessary-dict-index-lookup]
102+
break

tests/functional/u/unnecessary/unnecessary_dict_index_lookup.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,4 @@ unnecessary-dict-index-lookup:57:10:57:20::Unnecessary dictionary index lookup,
2121
unnecessary-dict-index-lookup:60:1:60:11::Unnecessary dictionary index lookup, use 'item[1]' instead:UNDEFINED
2222
unnecessary-dict-index-lookup:65:10:65:20::Unnecessary dictionary index lookup, use 'item[1]' instead:UNDEFINED
2323
unnecessary-dict-index-lookup:82:14:82:18::Unnecessary dictionary index lookup, use '_' instead:UNDEFINED
24+
unnecessary-dict-index-lookup:101:12:101:27::Unnecessary dictionary index lookup, use 'val' instead:UNDEFINED

0 commit comments

Comments
 (0)