diff options
author | David Shea <dshea@redhat.com> | 2014-07-07 14:20:47 -0400 |
---|---|---|
committer | David Shea <dshea@redhat.com> | 2014-07-07 14:20:47 -0400 |
commit | 2465aa80aa877497bc723caa253e0243188a035a (patch) | |
tree | 98433c98552d9b793eedeb5b7f01d56bec92819f /checkers | |
parent | eef3e13af5c0e6fcfea055e7162e4e11b0ba3365 (diff) | |
download | pylint-2465aa80aa877497bc723caa253e0243188a035a.tar.gz |
Correct the sequence index check for set and delete operations.
Usage of an index does not always imply __getitem__.
Diffstat (limited to 'checkers')
-rw-r--r-- | checkers/typecheck.py | 33 |
1 files changed, 22 insertions, 11 deletions
diff --git a/checkers/typecheck.py b/checkers/typecheck.py index d3a1aae..169abda 100644 --- a/checkers/typecheck.py +++ b/checkers/typecheck.py @@ -540,28 +540,39 @@ accessed. Python regular expressions are accepted.'} if not parent_type: return - # Check if this instance has a __getitem__ method implemented - # in a bulitin sequence type. This way we catch subclasses of - # sequence types but skip classes that override __getitem__ and - # which may allow non-integer indices. + # Determine what method on the parent this index will use + # The parent of this node will be a Subscript, and the parent of that + # node determines if the Subscript is a get, set, or delete operation. + operation = node.parent.parent + if isinstance(operation, astroid.Assign): + methodname = '__setitem__' + elif isinstance(operation, astroid.Delete): + methodname = '__delitem__' + else: + methodname = '__getitem__' + + # Check if this instance's __getitem__, __setitem__, or __delitem__, as + # appropriate to the statement, is implemented in a bulitin sequence + # type. This way we catch subclasses of sequence types but skip classes + # that override __getitem__ and which may allow non-integer indices. try: - getitems = parent_type.getattr('__getitem__') - if getitems is astroid.YES: + methods = parent_type.getattr(methodname) + if methods is astroid.YES: return - getitem = getitems[0] + itemmethod = methods[0] except (astroid.NotFoundError, IndexError): return - if not isinstance(getitem, astroid.Function): + if not isinstance(itemmethod, astroid.Function): return - if not getitem.parent: + if itemmethod.root().name != BUILTINS: return - if getitem.root().name != BUILTINS: + if not itemmethod.parent: return - if getitem.parent.name not in sequence_types: + if itemmethod.parent.name not in sequence_types: return index_type = safe_infer(node) |