From e3aa096710619f7b4647b9656649f90b29fe6eba Mon Sep 17 00:00:00 2001 From: Claudiu Popa Date: Thu, 26 Nov 2015 15:35:03 +0200 Subject: Added a new warning, 'unsupported-assignment-operation' This is emitted when item assignment is tried on an object which doesn't have this ability. Closes issue #591. --- pylint/checkers/typecheck.py | 41 +++++++++++++++++++++++++++++++++++------ 1 file changed, 35 insertions(+), 6 deletions(-) (limited to 'pylint/checkers/typecheck.py') diff --git a/pylint/checkers/typecheck.py b/pylint/checkers/typecheck.py index 43b0bde..75cb193 100644 --- a/pylint/checkers/typecheck.py +++ b/pylint/checkers/typecheck.py @@ -38,7 +38,8 @@ from pylint.checkers.utils import ( decorated_with, node_ignores_exception, is_iterable, is_mapping, supports_membership_test, is_comprehension, is_inside_abstract_class, - supports_subscript, + supports_getitem, + supports_setitem, safe_infer, has_known_bases) from pylint import utils @@ -161,6 +162,10 @@ MSGS = { 'unsubscriptable-object', "Emitted when a subscripted value doesn't support subscription" "(i.e. doesn't define __getitem__ method)"), + 'E1137': ("%r does not support item assignment", + 'unsupported-assignment-operation', + "Emitted when an object does not support item assignment " + "(i.e. doesn't define __setitem__ method)"), } # builtin sequence types in Python 2 and 3. @@ -825,18 +830,42 @@ accessed. Python regular expressions are accepted.'} if operator in ['in', 'not in']: self._check_membership_test(right) + @staticmethod + def _is_subscript_store_context(node): + statement = node.statement() + if isinstance(statement, astroid.Assign): + for target in statement.targets: + if target is node or target.parent_of(node): + return False + return True + @check_messages('unsubscriptable-object') def visit_subscript(self, node): if isinstance(node.value, (astroid.ListComp, astroid.DictComp)): return + + store_context = self._is_subscript_store_context(node) if isinstance(node.value, astroid.SetComp): - self.add_message('unsubscriptable-object', - args=node.value.as_string(), + if store_context: + msg = 'unsubscriptable-object' + else: + msg = 'unsupported-assignment-operation' + self.add_message(msg, args=node.value.as_string(), node=node.value) - infered = safe_infer(node.value) - if infered is None or infered is astroid.YES: return - if not supports_subscript(infered): + + inferred = safe_infer(node.value) + if inferred is None or inferred is astroid.YES: + return + + if not store_context: + if not supports_setitem(inferred): + self.add_message('unsupported-assignment-operation', + args=node.value.as_string(), + node=node.value) + return + + if not supports_getitem(inferred): self.add_message('unsubscriptable-object', args=node.value.as_string(), node=node.value) -- cgit v1.2.1