summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pylint/checkers/classes.py11
-rw-r--r--pylint/test/functional/non_iterator_returned.py21
-rw-r--r--pylint/test/functional/non_iterator_returned.txt9
-rw-r--r--tox.ini5
4 files changed, 27 insertions, 19 deletions
diff --git a/pylint/checkers/classes.py b/pylint/checkers/classes.py
index 3d9144d..24b862f 100644
--- a/pylint/checkers/classes.py
+++ b/pylint/checkers/classes.py
@@ -1067,12 +1067,15 @@ class SpecialMethodsChecker(BaseChecker):
def _check_iter(self, node):
try:
- infered = node.infer_call_result(node)
+ infered_values = list(node.infer_call_result(node))
except astroid.InferenceError:
return
-
- if not all(map(self._is_iterator, infered)):
- self.add_message('non-iterator-returned', node=node)
+ # cases when there're multiple values infered
+ # are skipped to reduce the number of false positives
+ if len(infered_values) == 1:
+ infered = infered_values[0]
+ if not self._is_iterator(infered):
+ self.add_message('non-iterator-returned', node=node)
def _ancestors_to_call(klass_node, method='__init__'):
diff --git a/pylint/test/functional/non_iterator_returned.py b/pylint/test/functional/non_iterator_returned.py
index 804ceee..d2fa758 100644
--- a/pylint/test/functional/non_iterator_returned.py
+++ b/pylint/test/functional/non_iterator_returned.py
@@ -56,6 +56,19 @@ class FifthGoodIterator(object):
def __iter__(self):
return IteratorClass
+class FileBasedIterator(object):
+ def __init__(self, path):
+ self.path = path
+ self.file = None
+
+ def __iter__(self):
+ if self.file is not None:
+ self.file.close()
+ self.file = open(self.path)
+ # self file has two infered values: None and <instance of 'file'>
+ # we don't want to emit error in this case
+ return self.file
+
class FirstBadIterator(object):
""" __iter__ returns a list """
@@ -80,11 +93,3 @@ class FourthBadIterator(object):
def __iter__(self): # [non-iterator-returned]
return ThirdBadIterator
-
-class FifthBadIterator(object):
- """All branches should return an iterator."""
-
- def __iter__(self): # [non-iterator-returned]
- if self:
- return 1
- return SecondGoodIterator()
diff --git a/pylint/test/functional/non_iterator_returned.txt b/pylint/test/functional/non_iterator_returned.txt
index fe3db10..fa1d5be 100644
--- a/pylint/test/functional/non_iterator_returned.txt
+++ b/pylint/test/functional/non_iterator_returned.txt
@@ -1,5 +1,4 @@
-non-iterator-returned:63:FirstBadIterator.__iter__:__iter__ returns non-iterator
-non-iterator-returned:69:SecondBadIterator.__iter__:__iter__ returns non-iterator
-non-iterator-returned:75:ThirdBadIterator.__iter__:__iter__ returns non-iterator
-non-iterator-returned:81:FourthBadIterator.__iter__:__iter__ returns non-iterator
-non-iterator-returned:87:FifthBadIterator.__iter__:__iter__ returns non-iterator \ No newline at end of file
+non-iterator-returned:76:FirstBadIterator.__iter__:__iter__ returns non-iterator
+non-iterator-returned:82:SecondBadIterator.__iter__:__iter__ returns non-iterator
+non-iterator-returned:88:ThirdBadIterator.__iter__:__iter__ returns non-iterator
+non-iterator-returned:94:FourthBadIterator.__iter__:__iter__ returns non-iterator
diff --git a/tox.ini b/tox.ini
index d9fcff1..7c911da 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,7 +1,7 @@
[tox]
# official list is
#envlist = py27, py32, py33, py34
-envlist = py27, py33, pylint
+envlist = py27, py34, pylint
[testenv:pylint]
deps =
@@ -14,5 +14,6 @@ commands = pylint -rn --rcfile={toxinidir}/pylintrc {envsitepackagesdir}/pylint
deps =
hg+https://bitbucket.org/logilab/astroid@master
six
+ pudb
commands = python -Wi -m unittest discover -s {envsitepackagesdir}/pylint/test/ -p {posargs:*test_*}.py
-changedir = {toxworkdir} \ No newline at end of file
+changedir = {toxworkdir}