1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
|
# pylint: disable=missing-docstring, too-few-public-methods, expression-not-assigned, line-too-long
a_dict = {}
b_dict = {}
for k, v in a_dict.items():
print(a_dict[k]) # [unnecessary-dict-index-lookup]
print(b_dict[k]) # Should not emit warning, accessing other dictionary
a_dict[k] = 123 # Should not emit warning, key access necessary
a_dict[k] += 123 # Should not emit warning, key access necessary
print(a_dict[k]) # Should not emit warning, v != a_dict[k]
for k, v in b_dict.items():
k = "another key"
print(b_dict[k]) # This is fine, key reassigned
# Tests on comprehensions
{v: 1 for k, v in a_dict.items() if a_dict[k]} # [unnecessary-dict-index-lookup]
{v: 1 for k, v in a_dict.items() if k} # This is fine, no indexing
{a_dict[k]: 1 for k, v in a_dict.items() if k} # [unnecessary-dict-index-lookup]
{a_dict[k]: 1 for k, v in a_dict.items() if a_dict[k]} # [unnecessary-dict-index-lookup, unnecessary-dict-index-lookup]
[v for k, v in a_dict.items() if a_dict[k]] # [unnecessary-dict-index-lookup]
[v for k, v in a_dict.items() if k] # This is fine, no indexing
[a_dict[k] for k, v in a_dict.items() if k] # [unnecessary-dict-index-lookup]
[a_dict[k] for k, v in a_dict.items() if a_dict[k]] # [unnecessary-dict-index-lookup, unnecessary-dict-index-lookup]
# Tests on dict attribute of a class
class Foo:
c_dict = {}
for k, v in Foo.c_dict.items():
print(b_dict[k]) # Should not emit warning, accessing other dictionary
print(Foo.c_dict[k]) # [unnecessary-dict-index-lookup]
unnecessary = 0 # pylint: disable=invalid-name
unnecessary += Foo.c_dict[k] # [unnecessary-dict-index-lookup]
Foo.c_dict[k] += v # key access necessary
# Tests on comprehensions
{v: 1 for k, v in Foo.c_dict.items() if Foo.c_dict[k]} # [unnecessary-dict-index-lookup]
{v: 1 for k, v in Foo.c_dict.items() if k} # This is fine, no indexing
{Foo.c_dict[k]: 1 for k, v in Foo.c_dict.items() if k} # [unnecessary-dict-index-lookup]
{Foo.c_dict[k]: 1 for k, v in Foo.c_dict.items() if Foo.c_dict[k]} # [unnecessary-dict-index-lookup, unnecessary-dict-index-lookup]
[v for k, v in Foo.c_dict.items() if Foo.c_dict[k]] # [unnecessary-dict-index-lookup]
[v for k, v in Foo.c_dict.items() if k] # This is fine, no indexing
[Foo.c_dict[k] for k, v in Foo.c_dict.items() if k] # [unnecessary-dict-index-lookup]
[Foo.c_dict[k] for k, v in Foo.c_dict.items() if Foo.c_dict[k]] # [unnecessary-dict-index-lookup, unnecessary-dict-index-lookup]
# Test assigning d.items() to a single variable
d = {1: "a", 2: "b"}
for item in d.items():
print(item[0])
print(d[item[0]]) # [unnecessary-dict-index-lookup]
[item[0] for item in d.items()]
[d[item[0]] for item in d.items()] # [unnecessary-dict-index-lookup]
# Reassigning single var
for item in d.items():
print(item[0])
print(d[item[0]]) # [unnecessary-dict-index-lookup]
item = (2, "b")
print(d[item[0]]) # This is fine, no warning thrown as key has been reassigned
# Test false positive described in #4630
# (https://github.com/PyCQA/pylint/issues/4630)
d = {'key': 'value'}
for k, _ in d.items():
d[k] += 'VALUE'
if 'V' in d[k]: # This is fine, if d[k] is replaced with _, the semantics change
print('found V')
for k, _ in d.items():
if 'V' in d[k]: # [unnecessary-dict-index-lookup]
d[k] = "value"
print(d[k]) # This is fine
# Test false positive described in #4716
# Should not be emitted for del
# (https://github.com/PyCQA/pylint/issues/4716)
d = {}
for key, val in d.items():
del d[key]
break
for item in d.items():
del d[item[0]]
break
outer_dict = {"inner_dict": {}}
for key, val in outer_dict.items():
for key_two, val_two in val.items():
del outer_dict[key][key_two] # [unnecessary-dict-index-lookup]
break
|