summaryrefslogtreecommitdiff
path: root/tests/functional/c/consider/consider_using_dict_items.py
blob: 7fd74814fc3937544eec4b0659e8d60a2e90eea9 (plain)
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
103
104
105
"""Emit a message for iteration through dict keys and subscripting dict with key."""
# pylint: disable=line-too-long,missing-docstring,unsubscriptable-object,too-few-public-methods,redefined-outer-name,use-dict-literal,modified-iterating-dict

def bad():
    a_dict = {1: 1, 2: 2, 3: 3}
    for k in a_dict:  # [consider-using-dict-items]
        print(a_dict[k])
    another_dict = dict()
    for k in another_dict:  # [consider-using-dict-items]
        print(another_dict[k])


def good():
    a_dict = {1: 1, 2: 2, 3: 3}
    for k in a_dict:
        print(k)

out_of_scope_dict = dict()

def another_bad():
    for k in out_of_scope_dict:  # [consider-using-dict-items]
        print(out_of_scope_dict[k])

def another_good():
    for k in out_of_scope_dict:
        k = 1
        k = 2
        k = 3
        print(out_of_scope_dict[k])


b_dict = {}
for k2 in b_dict:  # Should not emit warning, key access necessary
    b_dict[k2] = 2

for k2 in b_dict:  # Should not emit warning, key access necessary (AugAssign)
    b_dict[k2] += 2

# Warning should be emitted in this case
for k6 in b_dict:  # [consider-using-dict-items]
    val = b_dict[k6]
    b_dict[k6] = 2

for k3 in b_dict:  # [consider-using-dict-items]
    val = b_dict[k3]

for k4 in b_dict.keys():  # [consider-iterating-dictionary,consider-using-dict-items]
    val = b_dict[k4]

class Foo:
    c_dict = {}

# Should emit warning when iterating over a dict attribute of a class
for k5 in Foo.c_dict:  # [consider-using-dict-items]
    val = Foo.c_dict[k5]

c_dict = {}

# Should NOT emit warning whey key used to access a different dict
for k5 in Foo.c_dict:  # This is fine
    val = b_dict[k5]

for k5 in Foo.c_dict:  # This is fine
    val = c_dict[k5]

# Should emit warning within a list/dict comprehension
val = {k9: b_dict[k9] for k9 in b_dict}  # [consider-using-dict-items]
val = [(k7, b_dict[k7]) for k7 in b_dict]  # [consider-using-dict-items]

# Should emit warning even when using dict attribute of a class within comprehension
val = [(k7, Foo.c_dict[k7]) for k7 in Foo.c_dict]  # [consider-using-dict-items]
val = any(True for k8 in Foo.c_dict if Foo.c_dict[k8])  # [consider-using-dict-items]

# Should emit warning when dict access done in ``if`` portion of comprehension
val = any(True for k8 in b_dict if b_dict[k8])  # [consider-using-dict-items]

# Should NOT emit warning whey key used to access a different dict
val = [(k7, b_dict[k7]) for k7 in Foo.c_dict]
val = any(True for k8 in Foo.c_dict if b_dict[k8])

# Should NOT emit warning, essentially same check as above
val = [(k7, c_dict[k7]) for k7 in Foo.c_dict]
val = any(True for k8 in Foo.c_dict if c_dict[k8])

# Should emit warning, using .keys() of Foo.c_dict
val = any(True for k8 in Foo.c_dict.keys() if Foo.c_dict[k8])  # [consider-iterating-dictionary,consider-using-dict-items]

# Test false positive described in #4630
# (https://github.com/pylint-dev/pylint/issues/4630)

d = {'key': 'value'}

for k in d:  # this is fine, with the reassignment of d[k], d[k] is necessary
    d[k] += '123'
    if '1' in d[k]:  # index lookup necessary here, do not emit error
        print('found 1')

for k in d:  # if this gets rewritten to d.items(), we are back to the above problem
    d[k] = d[k] + 1
    if '1' in d[k]:  # index lookup necessary here, do not emit error
        print('found 1')

for k in d:  # [consider-using-dict-items]
    if '1' in d[k]:  # index lookup necessary here, do not emit error
        print('found 1')