From 87b0a1ca7c16bef2ee083ad4440f02f60052cde4 Mon Sep 17 00:00:00 2001 From: Mark Byrne Date: Sat, 13 Aug 2022 12:01:59 +0200 Subject: [PATCH 1/4] Fix false positive for `no-self-argument` when a staticmethod is applied to a function but uses a different name. Closes #7300 --- doc/whatsnew/fragments/7300.false_positive | 3 +++ pylint/checkers/classes/class_checker.py | 3 +++ tests/functional/n/no/no_self_argument.py | 28 +++++++++++++++++++--- tests/functional/n/no/no_self_argument.txt | 4 ++-- 4 files changed, 33 insertions(+), 5 deletions(-) create mode 100644 doc/whatsnew/fragments/7300.false_positive diff --git a/doc/whatsnew/fragments/7300.false_positive b/doc/whatsnew/fragments/7300.false_positive new file mode 100644 index 0000000000..e926b20688 --- /dev/null +++ b/doc/whatsnew/fragments/7300.false_positive @@ -0,0 +1,3 @@ +Fix false positive for `no-self-argument` when a staticmethod is applied to a function but uses a different name. + +Closes #7300 diff --git a/pylint/checkers/classes/class_checker.py b/pylint/checkers/classes/class_checker.py index b488360892..a6ca132c7a 100644 --- a/pylint/checkers/classes/class_checker.py +++ b/pylint/checkers/classes/class_checker.py @@ -1926,6 +1926,9 @@ def _check_first_arg_for_type( self.add_message("bad-staticmethod-argument", args=first, node=node) return self._first_attrs[-1] = None + elif any(name == "builtins.staticmethod" for name in node.decoratornames()): + # Check if there is a decorator which is not named `staticmethod` but is assigned to one. + return # class / regular method with no args elif not node.args.args and not node.args.posonlyargs: self.add_message("no-method-argument", node=node) diff --git a/tests/functional/n/no/no_self_argument.py b/tests/functional/n/no/no_self_argument.py index 38f6040b54..e0be906954 100644 --- a/tests/functional/n/no/no_self_argument.py +++ b/tests/functional/n/no/no_self_argument.py @@ -1,8 +1,15 @@ """Check for method without self as first argument""" -# pylint: disable=useless-object-inheritance -from __future__ import print_function -class NoSelfArgument(object): + +MYSTATICMETHOD = staticmethod + + +def returns_staticmethod(my_function): + """Create a staticmethod from function `my_function`""" + return staticmethod(my_function) + + +class NoSelfArgument: """dummy class""" def __init__(truc): # [no-self-argument] @@ -16,3 +23,18 @@ def abdc(yoo): # [no-self-argument] def edf(self): """just another method""" print('yapudju in', self) + + @staticmethod + def say_hello(): + """A standard staticmethod""" + print("hello!") + + @MYSTATICMETHOD + def say_goodbye(): + """A staticmethod but using a different name""" + print("goodbye!") + + @returns_staticmethod + def sum_strings(string1, string2): + """A staticmethod created by `returns_staticmethod` function""" + return string1 + string2 diff --git a/tests/functional/n/no/no_self_argument.txt b/tests/functional/n/no/no_self_argument.txt index 45d12cc321..9fd34c8d29 100644 --- a/tests/functional/n/no/no_self_argument.txt +++ b/tests/functional/n/no/no_self_argument.txt @@ -1,2 +1,2 @@ -no-self-argument:8:4:8:16:NoSelfArgument.__init__:"Method should have ""self"" as first argument":UNDEFINED -no-self-argument:12:4:12:12:NoSelfArgument.abdc:"Method should have ""self"" as first argument":UNDEFINED +no-self-argument:15:4:15:16:NoSelfArgument.__init__:"Method should have ""self"" as first argument":UNDEFINED +no-self-argument:19:4:19:12:NoSelfArgument.abdc:"Method should have ""self"" as first argument":UNDEFINED From 23b4a871bfc2f93306c5976e8202f8a96a428c65 Mon Sep 17 00:00:00 2001 From: Mark Byrne <31762852+mbyrnepr2@users.noreply.github.com> Date: Sat, 13 Aug 2022 19:42:39 +0200 Subject: [PATCH 2/4] Update pylint/checkers/classes/class_checker.py Co-authored-by: Jacob Walls --- pylint/checkers/classes/class_checker.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pylint/checkers/classes/class_checker.py b/pylint/checkers/classes/class_checker.py index a6ca132c7a..4ee9473773 100644 --- a/pylint/checkers/classes/class_checker.py +++ b/pylint/checkers/classes/class_checker.py @@ -1926,7 +1926,7 @@ def _check_first_arg_for_type( self.add_message("bad-staticmethod-argument", args=first, node=node) return self._first_attrs[-1] = None - elif any(name == "builtins.staticmethod" for name in node.decoratornames()): + elif "builtins.staticmethod" in node.decoratornames(): # Check if there is a decorator which is not named `staticmethod` but is assigned to one. return # class / regular method with no args From 26d97b54c6f3324d45573c025aacefcdd2955b44 Mon Sep 17 00:00:00 2001 From: Mark Byrne <31762852+mbyrnepr2@users.noreply.github.com> Date: Sat, 13 Aug 2022 19:43:06 +0200 Subject: [PATCH 3/4] Update tests/functional/n/no/no_self_argument.py Co-authored-by: Jacob Walls --- tests/functional/n/no/no_self_argument.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/functional/n/no/no_self_argument.py b/tests/functional/n/no/no_self_argument.py index e0be906954..09bc146bdd 100644 --- a/tests/functional/n/no/no_self_argument.py +++ b/tests/functional/n/no/no_self_argument.py @@ -35,6 +35,6 @@ def say_goodbye(): print("goodbye!") @returns_staticmethod - def sum_strings(string1, string2): + def concatenate_strings(string1, string2): """A staticmethod created by `returns_staticmethod` function""" return string1 + string2 From 90aa512e3e44924510608b963035b0bbe25f9d50 Mon Sep 17 00:00:00 2001 From: Mark Byrne <31762852+mbyrnepr2@users.noreply.github.com> Date: Sat, 13 Aug 2022 19:43:30 +0200 Subject: [PATCH 4/4] Update doc/whatsnew/fragments/7300.false_positive Co-authored-by: Jacob Walls --- doc/whatsnew/fragments/7300.false_positive | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/whatsnew/fragments/7300.false_positive b/doc/whatsnew/fragments/7300.false_positive index e926b20688..b23352ea99 100644 --- a/doc/whatsnew/fragments/7300.false_positive +++ b/doc/whatsnew/fragments/7300.false_positive @@ -1,3 +1,3 @@ -Fix false positive for `no-self-argument` when a staticmethod is applied to a function but uses a different name. +Fix false positive for `no-self-argument`/`no-method-argument` when a staticmethod is applied to a function but uses a different name. Closes #7300