summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFederico Bond <federicobond@gmail.com>2020-05-03 21:50:36 -0300
committerPierre Sassoulas <pierre.sassoulas@gmail.com>2020-05-05 07:08:55 +0200
commitd4c8bcd74e37d84d0c3a7e1624e49ca6dc50ae8b (patch)
tree44f6d5aded972240fd3141d93d27b7167a2c8f09
parent3fffdf03d5a32e4a0d1b5216ea9d16dacacdaa6f (diff)
downloadpylint-git-d4c8bcd74e37d84d0c3a7e1624e49ca6dc50ae8b.tar.gz
Add new old-style-super check to flag instances of super with default arguments
-rw-r--r--ChangeLog2
-rw-r--r--doc/whatsnew/2.6.rst2
-rw-r--r--pylint/checkers/python3.py22
-rw-r--r--tests/checkers/unittest_python3.py34
-rw-r--r--tests/functional/s/super_style.py17
-rw-r--r--tests/functional/s/super_style.rc3
-rw-r--r--tests/functional/s/super_style.txt1
7 files changed, 80 insertions, 1 deletions
diff --git a/ChangeLog b/ChangeLog
index 2e47d45fe..4fa958010 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -16,6 +16,8 @@ Release date: TBA
* mixed-indentation has been removed, it is no longer useful since TabError is included directly in python3
+* Add `old-style-super` check for flagging instances of Python 2 style super calls.
+
Close #2984 #3573
What's New in Pylint 2.5.1?
diff --git a/doc/whatsnew/2.6.rst b/doc/whatsnew/2.6.rst
index 92a72e3c0..c00053acd 100644
--- a/doc/whatsnew/2.6.rst
+++ b/doc/whatsnew/2.6.rst
@@ -13,6 +13,8 @@ Summary -- Release highlights
New checkers
============
+* Add `old-style-super` check for flagging instances of Python 2 style super calls.
+
Other Changes
=============
diff --git a/pylint/checkers/python3.py b/pylint/checkers/python3.py
index 11fc0eec0..0f5690020 100644
--- a/pylint/checkers/python3.py
+++ b/pylint/checkers/python3.py
@@ -598,6 +598,12 @@ class Python3Checker(checkers.BaseChecker):
"variables will be deleted outside of the "
"comprehension.",
),
+ "C1601": (
+ "Consider using Python 3 style super() without arguments",
+ "old-style-super",
+ "Emitted when calling the super builtin with the current class "
+ "and instance. On Python 3 these arguments are the default.",
+ ),
}
_bad_builtins = frozenset(
@@ -1233,12 +1239,26 @@ class Python3Checker(checkers.BaseChecker):
if not _in_iterating_context(node):
checker = "{}-builtin-not-iterating".format(node.func.name)
self.add_message(checker, node=node)
- if node.func.name == "open" and node.keywords:
+ elif node.func.name == "open" and node.keywords:
kwargs = node.keywords
for kwarg in kwargs or []:
if kwarg.arg == "encoding":
self._validate_encoding(kwarg.value, node)
break
+ elif node.func.name == "super":
+ if len(node.args) != 2:
+ return
+ if (
+ not isinstance(node.args[1], astroid.Name)
+ or node.args[1].name != "self"
+ ):
+ return
+ if (
+ not isinstance(node.args[1], astroid.Name)
+ or node.args[0].name != node.scope().parent.name
+ ):
+ return
+ self.add_message("old-style-super", node=node)
def _validate_encoding(self, encoding, node):
if isinstance(encoding, astroid.Const):
diff --git a/tests/checkers/unittest_python3.py b/tests/checkers/unittest_python3.py
index fdb5b26fd..e6c5b5fe1 100644
--- a/tests/checkers/unittest_python3.py
+++ b/tests/checkers/unittest_python3.py
@@ -1153,3 +1153,37 @@ class TestPython3Checker(testutils.CheckerTestCase):
message = testutils.Message("next-method-defined", node=node)
with self.assertAddsMessages(message):
self.checker.visit_functiondef(node)
+
+ def test_old_style_super(self):
+ node = astroid.extract_node(
+ """
+ class Foo(object):
+ def __init__():
+ super(Foo, self).__init__() #@
+ """
+ ).func.expr
+ message = testutils.Message("old-style-super", node=node)
+ with self.assertAddsMessages(message):
+ self.checker.visit_call(node)
+
+ def test_super_non_default_args(self):
+ node = astroid.extract_node(
+ """
+ class Foo(object):
+ def __init__():
+ super(Bar, self).__init__() #@
+ """
+ ).func.expr
+ with self.assertNoMessages():
+ self.checker.visit_call(node)
+
+ def test_new_style_super(self):
+ node = astroid.extract_node(
+ """
+ class Foo(object):
+ def __init__():
+ super().__init__() #@
+ """
+ ).func.expr
+ with self.assertNoMessages():
+ self.checker.visit_call(node)
diff --git a/tests/functional/s/super_style.py b/tests/functional/s/super_style.py
new file mode 100644
index 000000000..342e67c4b
--- /dev/null
+++ b/tests/functional/s/super_style.py
@@ -0,0 +1,17 @@
+class Foo:
+ pass
+
+
+class Bar(Foo):
+ def __init__(self):
+ super(Bar, self).__init__() # [old-style-super]
+
+
+class Baz(Foo):
+ def __init__(self):
+ super().__init__()
+
+
+class Qux(Foo):
+ def __init__(self):
+ super(Bar, self).__init__()
diff --git a/tests/functional/s/super_style.rc b/tests/functional/s/super_style.rc
new file mode 100644
index 000000000..cfff8dab7
--- /dev/null
+++ b/tests/functional/s/super_style.rc
@@ -0,0 +1,3 @@
+[Messages Control]
+disable=all
+enable=old-style-super
diff --git a/tests/functional/s/super_style.txt b/tests/functional/s/super_style.txt
new file mode 100644
index 000000000..50235699e
--- /dev/null
+++ b/tests/functional/s/super_style.txt
@@ -0,0 +1 @@
+old-style-super:7:Bar.__init__:Consider using Python 3 style super() without arguments