Skip to content

Commit 417e8c3

Browse files
Fix bad-super-call for non-direct parents (#6956)
Co-authored-by: Pierre Sassoulas <[email protected]>
1 parent fb6be59 commit 417e8c3

File tree

7 files changed

+55
-7
lines changed

7 files changed

+55
-7
lines changed

doc/data/messages/b/bad-super-call/bad.py

+6-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@ class Animal:
22
pass
33

44

5+
class Tree:
6+
pass
7+
8+
59
class Cat(Animal):
610
def __init__(self):
7-
super(Animal, self).__init__() # [bad-super-call]
11+
super(Tree, self).__init__() # [bad-super-call]
12+
super(Animal, self).__init__()

doc/data/messages/b/bad-super-call/details.rst

+3
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,6 @@ In Python 2.7, ``super()`` has to be called with its own class and ``self`` as a
22
lead to a mix up of parent and child class in the code.
33

44
In Python 3 the recommended way is to call ``super()`` without arguments (see also ``super-with-arguments``).
5+
6+
One exception is calling ``super()`` on a non-direct parent class. This can be used to get a method other than the default
7+
method returned by the ``mro()``.

doc/data/messages/b/bad-super-call/good.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ class Animal:
22
pass
33

44

5+
class Tree:
6+
pass
7+
8+
59
class Cat(Animal):
610
def __init__(self):
7-
super().__init__()
11+
super(Animal, self).__init__()

doc/whatsnew/2/2.14/full.rst

+4
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ What's New in Pylint 2.14.3?
55
----------------------------
66
Release date: TBA
77

8+
* Fixed two false positives for ``bad-super-call`` for calls that refer to a non-direct parent.
9+
10+
Closes #4922, Closes #2903
11+
812
* Fixed a false positive for ``useless-super-delegation`` for subclasses that specify the number of
913
of parameters against a parent that uses a variadic argument.
1014

pylint/checkers/newstyle.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,9 @@ def visit_functiondef(self, node: nodes.FunctionDef) -> None:
108108
except astroid.InferenceError:
109109
continue
110110

111-
if klass is not supcls:
111+
# If the supcls is in the ancestors of klass super can be used to skip
112+
# a step in the mro() and get a method from a higher parent
113+
if klass is not supcls and all(i != supcls for i in klass.ancestors()):
112114
name = None
113115
# if supcls is not Uninferable, then supcls was inferred
114116
# and use its name. Otherwise, try to look

tests/functional/s/super/super_checks.py

+33-2
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ def __init__(self):
2929
class Py3kWrongSuper(Py3kAaaa):
3030
"""new style"""
3131
def __init__(self):
32-
super(NewAaaa, self).__init__() # [bad-super-call]
32+
super(NewAaaa, self).__init__()
3333

3434
class WrongNameRegression(Py3kAaaa):
3535
""" test a regression with the message """
@@ -59,7 +59,7 @@ class FalsePositive(Empty):
5959
"""The following super is in another scope than `test`."""
6060
def __init__(self, arg):
6161
super(FalsePositive, self).__init__(arg)
62-
super(object, 1).__init__() # [bad-super-call]
62+
super(object, 1).__init__()
6363

6464

6565
class UnknownBases(Missing):
@@ -123,3 +123,34 @@ class SuperWithSelfClass(object):
123123
"""self.__class__ may lead to recursion loop in derived classes"""
124124
def __init__(self):
125125
super(self.__class__, self).__init__() # [bad-super-call]
126+
127+
128+
# Reported in https://github.com/PyCQA/pylint/issues/2903
129+
class Parent:
130+
def method(self):
131+
print()
132+
133+
134+
class Child(Parent):
135+
def method(self):
136+
print("Child")
137+
super().method()
138+
139+
class Niece(Parent):
140+
def method(self):
141+
print("Niece")
142+
super().method()
143+
144+
class GrandChild(Child):
145+
def method(self):
146+
print("Grandchild")
147+
super(GrandChild, self).method()
148+
super(Child, self).method()
149+
super(Niece, self).method() # [bad-super-call]
150+
151+
152+
# Reported in https://github.com/PyCQA/pylint/issues/4922
153+
class AlabamaCousin(Child, Niece):
154+
def method(self):
155+
print("AlabamaCousin")
156+
super(Child, self).method()

tests/functional/s/super/super_checks.txt

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
no-member:10:8:10:29:Aaaa.hop:Super of 'Aaaa' has no 'hop' member:INFERENCE
22
no-member:19:8:19:32:NewAaaa.hop:Super of 'NewAaaa' has no 'hop' member:INFERENCE
33
bad-super-call:22:8:22:25:NewAaaa.__init__:Bad first argument 'Aaaa' given to super():UNDEFINED
4-
bad-super-call:32:8:32:28:Py3kWrongSuper.__init__:Bad first argument 'NewAaaa' given to super():UNDEFINED
54
bad-super-call:37:8:37:28:WrongNameRegression.__init__:Bad first argument 'Missing' given to super():UNDEFINED
65
bad-super-call:46:8:46:33:CrashSuper.__init__:Bad first argument 'NewAaaa' given to super():UNDEFINED
7-
bad-super-call:62:8:62:24:SuperDifferentScope.test:Bad first argument 'object' given to super():UNDEFINED
86
bad-super-call:70:8:70:28:UnknownBases.__init__:Bad first argument 'Missing' given to super():UNDEFINED
97
not-callable:89:8:89:54:InvalidSuperChecks.__init__:super(InvalidSuperChecks, self).not_a_method is not callable:UNDEFINED
108
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
1513
no-member:98:8:98:55:InvalidSuperChecks.__init__:Super of 'InvalidSuperChecks' has no 'attribute_error' member:INFERENCE
1614
bad-super-call:120:8:120:31:SuperWithType.__init__:Bad first argument 'type' given to super():UNDEFINED
1715
bad-super-call:125:8:125:35:SuperWithSelfClass.__init__:Bad first argument 'self.__class__' given to super():UNDEFINED
16+
bad-super-call:149:8:149:26:GrandChild.method:Bad first argument 'Niece' given to super():UNDEFINED

0 commit comments

Comments
 (0)