Use the new .ctx attribute for subscripts for detecting in which context the node was used. Closes issue #705.

authorClaudiu Popa <pcmanticore@gmail.com>
changeset82fc94502999
branchdefault
phasepublic
hiddenno
parent revision#6fbe83cee30d Merged in jakirkham/pylint/issue_538_pt2 (pull request #315)
child revision#bd9ee94a908d Give a nice error message when Graphviz is not installed. Closes issue #168.
files modified by this revision
pylint/checkers/typecheck.py
# HG changeset patch
# User Claudiu Popa <pcmanticore@gmail.com>
# Date 1449567923 -7200
# Tue Dec 08 11:45:23 2015 +0200
# Node ID 82fc94502999bbe411b3c9f5b7d4af9c4e7843e8
# Parent 6fbe83cee30d0f9f8f1d12a48e1718b781bfb7cf
Use the new .ctx attribute for subscripts for detecting in which context the node was used. Closes issue #705.

diff --git a/pylint/checkers/typecheck.py b/pylint/checkers/typecheck.py
@@ -49,11 +49,10 @@
1  _ZOPE_DEPRECATED = (
2      "This option is deprecated. Use generated-members instead."
3  )
4  BUILTINS = six.moves.builtins.__name__
5  STR_FORMAT = "%s.str.format" % BUILTINS
6 -STORE_CONTEXT, LOAD_CONTEXT, DELETE_CONTEXT = range(3)
7 
8 
9  def _unflatten(iterable):
10      for index, elem in enumerate(iterable):
11          if (isinstance(elem, collections.Sequence) and
@@ -649,13 +648,13 @@
12 
13          # Determine what method on the parent this index will use
14          # The parent of this node will be a Subscript, and the parent of that
15          # node determines if the Subscript is a get, set, or delete operation.
16          operation = node.parent.parent
17 -        if isinstance(operation, astroid.Assign):
18 +        if node.parent.ctx is astroid.Store:
19              methodname = '__setitem__'
20 -        elif isinstance(operation, astroid.Delete):
21 +        elif node.parent.ctx is astroid.Del:
22              methodname = '__delitem__'
23          else:
24              methodname = '__getitem__'
25 
26          # Check if this instance's __getitem__, __setitem__, or __delitem__, as
@@ -834,33 +833,25 @@
27              return
28          operator, right = node.ops[0]
29          if operator in ['in', 'not in']:
30              self._check_membership_test(right)
31 
32 -    @staticmethod
33 -    def _subscript_context(node):
34 -        statement = node.statement()
35 -        if isinstance(statement, astroid.Assign):
36 -            for target in statement.targets:
37 -                if target is node or target.parent_of(node):
38 -                    return STORE_CONTEXT
39 -        elif isinstance(statement, astroid.Delete):
40 -            return DELETE_CONTEXT
41 -        return LOAD_CONTEXT
42 -
43      @check_messages('unsubscriptable-object', 'unsupported-assignment-operation',
44                      'unsupported-delete-operation')
45      def visit_subscript(self, node):
46 +        supported_protocol = None
47          if isinstance(node.value, (astroid.ListComp, astroid.DictComp)):
48              return
49 
50 -        context = self._subscript_context(node)
51 -        if context == LOAD_CONTEXT:
52 +        if node.ctx == astroid.Load:
53 +            supported_protocol = supports_getitem
54              msg = 'unsubscriptable-object'
55 -        elif context == STORE_CONTEXT:
56 +        elif node.ctx == astroid.Store:
57 +            supported_protocol = supports_setitem
58              msg = 'unsupported-assignment-operation'
59 -        elif context == DELETE_CONTEXT:
60 +        elif node.ctx == astroid.Del:
61 +            supported_protocol = supports_delitem
62              msg = 'unsupported-delete-operation'
63 
64          if isinstance(node.value, astroid.SetComp):
65              self.add_message(msg, args=node.value.as_string(),
66                               node=node.value)
@@ -871,17 +862,10 @@
67 
68          inferred = safe_infer(node.value)
69          if inferred is None or inferred is astroid.YES:
70              return
71 
72 -        supported_protocol = None
73 -        if context == STORE_CONTEXT:
74 -            supported_protocol = supports_setitem
75 -        elif context == LOAD_CONTEXT:
76 -            supported_protocol = supports_getitem
77 -        elif context == DELETE_CONTEXT:
78 -            supported_protocol = supports_delitem
79          if not supported_protocol(inferred):
80              self.add_message(msg, args=node.value.as_string(), node=node.value)
81 
82 
83  class IterableChecker(BaseChecker):