summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog3
-rw-r--r--checkers/classes.py41
-rw-r--r--test/unittest_checker_classes.py16
3 files changed, 40 insertions, 20 deletions
diff --git a/ChangeLog b/ChangeLog
index fd8f174..d7e6a9f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -16,6 +16,9 @@ ChangeLog for Pylint
* Catch enchant errors and emit 'invalid-characters-in-docstring'
when checking for spelling errors. Closes issue #469.
+ * Use all the inferred statements for the super-init-not-called
+ check. Closes issue #389.
+
2015-01-16 -- 1.4.1
diff --git a/checkers/classes.py b/checkers/classes.py
index 1a10c35..8e51a47 100644
--- a/checkers/classes.py
+++ b/checkers/classes.py
@@ -893,26 +893,27 @@ a metaclass class method.'}
expr.expr.func.name == 'super':
return
try:
- klass = next(expr.expr.infer())
- if klass is YES:
- continue
- # The infered klass can be super(), which was
- # assigned to a variable and the `__init__` was called later.
- #
- # base = super()
- # base.__init__(...)
-
- if (isinstance(klass, astroid.Instance) and
- isinstance(klass._proxied, astroid.Class) and
- is_builtin_object(klass._proxied) and
- klass._proxied.name == 'super'):
- return
- try:
- del not_called_yet[klass]
- except KeyError:
- if klass not in to_call:
- self.add_message('non-parent-init-called',
- node=expr, args=klass.name)
+ for klass in expr.expr.infer():
+ if klass is YES:
+ continue
+ # The infered klass can be super(), which was
+ # assigned to a variable and the `__init__`
+ # was called later.
+ #
+ # base = super()
+ # base.__init__(...)
+
+ if (isinstance(klass, astroid.Instance) and
+ isinstance(klass._proxied, astroid.Class) and
+ is_builtin_object(klass._proxied) and
+ klass._proxied.name == 'super'):
+ return
+ try:
+ del not_called_yet[klass]
+ except KeyError:
+ if klass not in to_call:
+ self.add_message('non-parent-init-called',
+ node=expr, args=klass.name)
except astroid.InferenceError:
continue
for klass, method in six.iteritems(not_called_yet):
diff --git a/test/unittest_checker_classes.py b/test/unittest_checker_classes.py
index f35e5e3..f21cfc1 100644
--- a/test/unittest_checker_classes.py
+++ b/test/unittest_checker_classes.py
@@ -61,6 +61,22 @@ class VariablesCheckerTC(CheckerTestCase):
with self.assertNoMessages():
self.checker.visit_function(node)
+ def test_super_init_not_called_regression(self):
+ # This should not emit a super-init-not-called
+ # warning. It previously did this, because
+ # ``next(node.infer())`` was used in that checker's
+ # logic and the first inferred node was an YES object,
+ # leading to this false positive.
+ node = test_utils.extract_node("""
+ import ctypes
+
+ class Foo(ctypes.BigEndianStructure):
+ def __init__(self): #@
+ ctypes.BigEndianStructure.__init__(self)
+ """)
+ with self.assertNoMessages():
+ self.checker.visit_function(node)
+
if __name__ == '__main__':
unittest.main()