summaryrefslogtreecommitdiff
path: root/tests/functional/u/unsubscriptable_value.py
diff options
context:
space:
mode:
Diffstat (limited to 'tests/functional/u/unsubscriptable_value.py')
-rw-r--r--tests/functional/u/unsubscriptable_value.py114
1 files changed, 114 insertions, 0 deletions
diff --git a/tests/functional/u/unsubscriptable_value.py b/tests/functional/u/unsubscriptable_value.py
new file mode 100644
index 000000000..68280c867
--- /dev/null
+++ b/tests/functional/u/unsubscriptable_value.py
@@ -0,0 +1,114 @@
+"""
+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
+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]