summaryrefslogtreecommitdiff
path: root/tests/functional/u/unsubscriptable_value.py
blob: 6a97cc4c846cfccb31b2b61bf169b0de2fe357d6 (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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
"""
Checks that value used in a subscript supports subscription
(i.e. defines __getitem__ method).
"""
# pylint: disable=missing-docstring,pointless-statement,expression-not-assigned,wrong-import-position, unnecessary-comprehension
# pylint: disable=too-few-public-methods,import-error,invalid-name,wrong-import-order, useless-object-inheritance, redundant-u-string-prefix
import six

# primitives
numbers = [1, 2, 3]
numbers[0]
"123"[0]
u"123"[0]
b"123"[0]
bytearray(b"123")[0]
dict(a=1, b=2)['a']
(1, 2, 3)[0]

# list/dict comprehensions are fine
[x for x in range(10)][0]
{x: 10 - x for x in range(10)}[0]


# instances
class NonSubscriptable(object):
    pass

class Subscriptable(object):
    def __getitem__(self, key):
        return key + key

NonSubscriptable()[0]  # [unsubscriptable-object]
NonSubscriptable[0]  # [unsubscriptable-object]
Subscriptable()[0]
Subscriptable[0]  # [unsubscriptable-object]

# generators are not subscriptable
def powers_of_two():
    k = 0
    while k < 10:
        yield 2 ** k
        k += 1

powers_of_two()[0]  # [unsubscriptable-object]
powers_of_two[0]  # [unsubscriptable-object]


# check that primitive non subscriptable types are caught
True[0]  # [unsubscriptable-object]
None[0]  # [unsubscriptable-object]
8.5[0]  # [unsubscriptable-object]
10[0]  # [unsubscriptable-object]

# sets are not subscriptable
{x ** 2 for x in range(10)}[0]  # [unsubscriptable-object]
set(numbers)[0]  # [unsubscriptable-object]
frozenset(numbers)[0]  # [unsubscriptable-object]

# skip instances with unknown base classes
from some_missing_module import LibSubscriptable

class MaybeSubscriptable(LibSubscriptable):
    pass

MaybeSubscriptable()[0]

# subscriptable classes (through metaclasses)

class MetaSubscriptable(type):
    def __getitem__(cls, key):
        return key + key

class SubscriptableClass(six.with_metaclass(MetaSubscriptable, object)):
    pass

SubscriptableClass[0]
SubscriptableClass()[0]  # [unsubscriptable-object]

# functions are not subscriptable
def test(*args, **kwargs):
    return args, kwargs

test()[0]
test[0]  # [unsubscriptable-object]

# deque
from collections import deque
deq = deque(maxlen=10)
deq.append(42)
deq[0]


class AbstractClass(object):

    def __init__(self):
        self.ala = {i for i in range(10)}
        self.bala = [i for i in range(10)]
        self.portocala = None

    def test_unsubscriptable(self):
        self.bala[0]
        self.portocala[0]


class ClassMixin(object):

    def __init__(self):
        self.ala = {i for i in range(10)}
        self.bala = [i for i in range(10)]
        self.portocala = None

    def test_unsubscriptable(self):
        self.bala[0]
        self.portocala[0]


def return_an_int(param):
    """Returns an int"""
    if param == 0:
        return 1
    return 0


def test_one(param):
    """Should complain about var_one[0], but doesn't"""
    var_one = return_an_int(param)
    return var_one[0]  # [unsubscriptable-object]