summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/data/messages/b/bad-super-call/bad.py7
-rw-r--r--doc/data/messages/b/bad-super-call/details.rst3
-rw-r--r--doc/data/messages/b/bad-super-call/good.py6
-rw-r--r--doc/whatsnew/2/2.14/full.rst4
-rw-r--r--pylint/checkers/newstyle.py4
-rw-r--r--tests/functional/s/super/super_checks.py35
-rw-r--r--tests/functional/s/super/super_checks.txt3
7 files changed, 55 insertions, 7 deletions
diff --git a/doc/data/messages/b/bad-super-call/bad.py b/doc/data/messages/b/bad-super-call/bad.py
index 1f13df5ed..625a70e6f 100644
--- a/doc/data/messages/b/bad-super-call/bad.py
+++ b/doc/data/messages/b/bad-super-call/bad.py
@@ -2,6 +2,11 @@ class Animal:
pass
+class Tree:
+ pass
+
+
class Cat(Animal):
def __init__(self):
- super(Animal, self).__init__() # [bad-super-call]
+ super(Tree, self).__init__() # [bad-super-call]
+ super(Animal, self).__init__()
diff --git a/doc/data/messages/b/bad-super-call/details.rst b/doc/data/messages/b/bad-super-call/details.rst
index 73f41942c..e5b0ab5c7 100644
--- a/doc/data/messages/b/bad-super-call/details.rst
+++ b/doc/data/messages/b/bad-super-call/details.rst
@@ -2,3 +2,6 @@ In Python 2.7, ``super()`` has to be called with its own class and ``self`` as a
lead to a mix up of parent and child class in the code.
In Python 3 the recommended way is to call ``super()`` without arguments (see also ``super-with-arguments``).
+
+One exception is calling ``super()`` on a non-direct parent class. This can be used to get a method other than the default
+method returned by the ``mro()``.
diff --git a/doc/data/messages/b/bad-super-call/good.py b/doc/data/messages/b/bad-super-call/good.py
index 720b2eda9..66152bc73 100644
--- a/doc/data/messages/b/bad-super-call/good.py
+++ b/doc/data/messages/b/bad-super-call/good.py
@@ -2,6 +2,10 @@ class Animal:
pass
+class Tree:
+ pass
+
+
class Cat(Animal):
def __init__(self):
- super().__init__()
+ super(Animal, self).__init__()
diff --git a/doc/whatsnew/2/2.14/full.rst b/doc/whatsnew/2/2.14/full.rst
index 3bc318793..3a751fef1 100644
--- a/doc/whatsnew/2/2.14/full.rst
+++ b/doc/whatsnew/2/2.14/full.rst
@@ -5,6 +5,10 @@ What's New in Pylint 2.14.3?
----------------------------
Release date: TBA
+* Fixed two false positives for ``bad-super-call`` for calls that refer to a non-direct parent.
+
+ Closes #4922, Closes #2903
+
* Fixed a false positive for ``useless-super-delegation`` for subclasses that specify the number of
of parameters against a parent that uses a variadic argument.
diff --git a/pylint/checkers/newstyle.py b/pylint/checkers/newstyle.py
index 6b0aa5095..0aed97183 100644
--- a/pylint/checkers/newstyle.py
+++ b/pylint/checkers/newstyle.py
@@ -108,7 +108,9 @@ class NewStyleConflictChecker(BaseChecker):
except astroid.InferenceError:
continue
- if klass is not supcls:
+ # If the supcls is in the ancestors of klass super can be used to skip
+ # a step in the mro() and get a method from a higher parent
+ if klass is not supcls and all(i != supcls for i in klass.ancestors()):
name = None
# if supcls is not Uninferable, then supcls was inferred
# and use its name. Otherwise, try to look
diff --git a/tests/functional/s/super/super_checks.py b/tests/functional/s/super/super_checks.py
index 277feae7e..ca35d52ae 100644
--- a/tests/functional/s/super/super_checks.py
+++ b/tests/functional/s/super/super_checks.py
@@ -29,7 +29,7 @@ class Py3kAaaa(NewAaaa):
class Py3kWrongSuper(Py3kAaaa):
"""new style"""
def __init__(self):
- super(NewAaaa, self).__init__() # [bad-super-call]
+ super(NewAaaa, self).__init__()
class WrongNameRegression(Py3kAaaa):
""" test a regression with the message """
@@ -59,7 +59,7 @@ class SuperDifferentScope(object):
"""The following super is in another scope than `test`."""
def __init__(self, arg):
super(FalsePositive, self).__init__(arg)
- super(object, 1).__init__() # [bad-super-call]
+ super(object, 1).__init__()
class UnknownBases(Missing):
@@ -123,3 +123,34 @@ class SuperWithSelfClass(object):
"""self.__class__ may lead to recursion loop in derived classes"""
def __init__(self):
super(self.__class__, self).__init__() # [bad-super-call]
+
+
+# Reported in https://github.com/PyCQA/pylint/issues/2903
+class Parent:
+ def method(self):
+ print()
+
+
+class Child(Parent):
+ def method(self):
+ print("Child")
+ super().method()
+
+class Niece(Parent):
+ def method(self):
+ print("Niece")
+ super().method()
+
+class GrandChild(Child):
+ def method(self):
+ print("Grandchild")
+ super(GrandChild, self).method()
+ super(Child, self).method()
+ super(Niece, self).method() # [bad-super-call]
+
+
+# Reported in https://github.com/PyCQA/pylint/issues/4922
+class AlabamaCousin(Child, Niece):
+ def method(self):
+ print("AlabamaCousin")
+ super(Child, self).method()
diff --git a/tests/functional/s/super/super_checks.txt b/tests/functional/s/super/super_checks.txt
index d18c28327..f33d9ec63 100644
--- a/tests/functional/s/super/super_checks.txt
+++ b/tests/functional/s/super/super_checks.txt
@@ -1,10 +1,8 @@
no-member:10:8:10:29:Aaaa.hop:Super of 'Aaaa' has no 'hop' member:INFERENCE
no-member:19:8:19:32:NewAaaa.hop:Super of 'NewAaaa' has no 'hop' member:INFERENCE
bad-super-call:22:8:22:25:NewAaaa.__init__:Bad first argument 'Aaaa' given to super():UNDEFINED
-bad-super-call:32:8:32:28:Py3kWrongSuper.__init__:Bad first argument 'NewAaaa' given to super():UNDEFINED
bad-super-call:37:8:37:28:WrongNameRegression.__init__:Bad first argument 'Missing' given to super():UNDEFINED
bad-super-call:46:8:46:33:CrashSuper.__init__:Bad first argument 'NewAaaa' given to super():UNDEFINED
-bad-super-call:62:8:62:24:SuperDifferentScope.test:Bad first argument 'object' given to super():UNDEFINED
bad-super-call:70:8:70:28:UnknownBases.__init__:Bad first argument 'Missing' given to super():UNDEFINED
not-callable:89:8:89:54:InvalidSuperChecks.__init__:super(InvalidSuperChecks, self).not_a_method is not callable:UNDEFINED
no-member:90:8:90:55:InvalidSuperChecks.__init__:Super of 'InvalidSuperChecks' has no 'attribute_error' member:INFERENCE
@@ -15,3 +13,4 @@ unexpected-keyword-arg:95:8:95:57:InvalidSuperChecks.__init__:Unexpected keyword
no-member:98:8:98:55:InvalidSuperChecks.__init__:Super of 'InvalidSuperChecks' has no 'attribute_error' member:INFERENCE
bad-super-call:120:8:120:31:SuperWithType.__init__:Bad first argument 'type' given to super():UNDEFINED
bad-super-call:125:8:125:35:SuperWithSelfClass.__init__:Bad first argument 'self.__class__' given to super():UNDEFINED
+bad-super-call:149:8:149:26:GrandChild.method:Bad first argument 'Niece' given to super():UNDEFINED