tonybaloney / perflint

Python Linter for performance anti patterns
MIT License
659 stars 10 forks source link

Migrate to pylint v3 #45

Closed jenstroeger closed 8 months ago

jenstroeger commented 8 months ago

perflint requires a version of pylint older than v3, which won’t allow users to move forward anymore:

https://github.com/tonybaloney/perflint/blob/c07391c17671c3c9d5a7fd69120d1f570e268d58/pyproject.toml#L11

The following patch should at least get the plugin working, though I’ve not yet read thoroughly through the code yet:

diff --git a/perflint/comprehension_checker.py b/perflint/comprehension_checker.py
index 9ae4b84..f7ebd8c 100644
--- a/perflint/comprehension_checker.py
+++ b/perflint/comprehension_checker.py
@@ -1,7 +1,6 @@
 from astroid import nodes
 from pylint.checkers import BaseChecker
 from pylint.checkers import utils as checker_utils
-from pylint.interfaces import IAstroidChecker
 from astroid.helpers import safe_infer

@@ -10,8 +9,6 @@ class ComprehensionChecker(BaseChecker):
     Check for comprehension usage
     """

-    __implements__ = IAstroidChecker
-
     name = "comprehension-checker"
     priority = -1
     msgs = {
@@ -35,7 +32,7 @@ class ComprehensionChecker(BaseChecker):
     def visit_for(self, node: nodes.For):
         pass

-    @checker_utils.check_messages(
+    @checker_utils.only_required_for_messages(^M
         "use-list-comprehension", "use-dict-comprehension", "use-list-copy"
     )
     def leave_for(self, node: nodes.For):
diff --git a/perflint/for_loop_checker.py b/perflint/for_loop_checker.py
index c17d4a8..f1f97f8 100644
--- a/perflint/for_loop_checker.py
+++ b/perflint/for_loop_checker.py
@@ -3,7 +3,6 @@ from astroid import nodes
 from astroid.helpers import safe_infer
 from pylint.checkers import BaseChecker
 from pylint.checkers import utils as checker_utils
-from pylint.interfaces import IAstroidChecker

 iterable_types = (
     nodes.Tuple,
@@ -52,8 +51,6 @@ class ForLoopChecker(BaseChecker):
     Check for poor for-loop usage.
     """

-    __implements__ = IAstroidChecker
-
     name = "for-loop-checker"
     priority = -1
     msgs = {
@@ -69,7 +66,7 @@ class ForLoopChecker(BaseChecker):
         ),
     }

-    @checker_utils.check_messages(
+    @checker_utils.only_required_for_messages(
         "unnecessary-list-cast", "incorrect-dictionary-iterator"
     )
     def visit_for(self, node: nodes.For) -> None:
@@ -130,8 +127,6 @@ class LoopInvariantChecker(BaseChecker):
     Check for poor for-loop usage.
     """

-    __implements__ = IAstroidChecker
-
     name = "loop-invariant-checker"
     priority = -1
     msgs = {
@@ -170,7 +165,7 @@ class LoopInvariantChecker(BaseChecker):
         self._loop_consts: List[List[nodes.Const]] = []
         self._ignore: List[nodes.NodeNG] = []

-    @checker_utils.check_messages("loop-invariant-statement")
+    @checker_utils.only_required_for_messages("loop-invariant-statement")
     def visit_for(self, node: nodes.For) -> None:
         """Visit for loop bodies."""
         self._loop_level += 1
@@ -184,7 +179,7 @@ class LoopInvariantChecker(BaseChecker):
         self._loop_consts.append([])
         self._ignore.append(node.iter)

-    @checker_utils.check_messages("loop-invariant-statement")
+    @checker_utils.only_required_for_messages("loop-invariant-statement")
     def visit_while(self, node: nodes.While) -> None:
         """Visit while loop bodies."""
         self._loop_level += 1
@@ -214,11 +209,11 @@ class LoopInvariantChecker(BaseChecker):
         ):
             self._ignore.append(node)

-    @checker_utils.check_messages("loop-invariant-statement")
+    @checker_utils.only_required_for_messages("loop-invariant-statement")
     def leave_for(self, node: nodes.For) -> None:
         self._leave_loop(node)

-    @checker_utils.check_messages("loop-invariant-statement")
+    @checker_utils.only_required_for_messages("loop-invariant-statement")
     def leave_while(self, node: nodes.While) -> None:
         self._leave_loop(node)

@@ -303,7 +298,7 @@ class LoopInvariantChecker(BaseChecker):
         if isinstance(node.target, nodes.AssignName):
             self._loop_assignments[-1].add(node.target.name)

-    @checker_utils.check_messages("loop-global-usage")
+    @checker_utils.only_required_for_messages("loop-global-usage")
     def visit_name(self, node: nodes.Name) -> None:
         """Look for global names"""
         if self._loop_names:
@@ -338,12 +333,12 @@ class LoopInvariantChecker(BaseChecker):
         if isinstance(node.func.expr, nodes.Name):
             self._loop_assignments[-1].add(node.func.expr.name)

-    @checker_utils.check_messages("loop-try-except-usage")
-    def visit_tryexcept(self, node: nodes.TryExcept) -> None:
+    @checker_utils.only_required_for_messages("loop-try-except-usage")
+    def visit_tryexcept(self, node: nodes.Try) -> None:
         if self._loop_level > 0:
             self.add_message("loop-try-except-usage", node=node)

-    @checker_utils.check_messages("memoryview-over-bytes")
+    @checker_utils.only_required_for_messages("memoryview-over-bytes")
     def visit_subscript(self, node: nodes.Subscript) -> None:
         if self._loop_level == 0:
             return
@@ -360,7 +355,7 @@ class LoopInvariantChecker(BaseChecker):
         ):
             self.add_message("memoryview-over-bytes", node=node)

-    @checker_utils.check_messages("dotted-import-in-loop")
+    @checker_utils.only_required_for_messages("dotted-import-in-loop")
     def visit_attribute(self, node: nodes.Attribute) -> None:
         if self._loop_level == 0:
             return
diff --git a/perflint/list_checker.py b/perflint/list_checker.py
index 681ed51..9ded539 100644
--- a/perflint/list_checker.py
+++ b/perflint/list_checker.py
@@ -2,7 +2,6 @@ from typing import Dict, List
 from astroid import nodes
 from pylint.checkers import BaseChecker
 from pylint.checkers import utils as checker_utils
-from pylint.interfaces import IAstroidChecker

 class ListChecker(BaseChecker):
@@ -10,8 +9,6 @@ class ListChecker(BaseChecker):
     Check for inefficient list usage
     """

-    __implements__ = IAstroidChecker
-
     name = 'list-checker'
     priority = -1
     msgs = {
@@ -42,14 +39,14 @@ class ListChecker(BaseChecker):
         for _assignment in _lists.values():
             self.add_message("use-tuple-over-list", node=_assignment.parent.value)

-    @checker_utils.check_messages("use-tuple-over-list")
+    @checker_utils.only_required_for_messages("use-tuple-over-list")
     def leave_module(self, node: nodes.Module):
         self._raise_for_scope()

     def visit_functiondef(self, node: nodes.FunctionDef):
         self._lists_to_watch.append({})

-    @checker_utils.check_messages("use-tuple-over-list")
+    @checker_utils.only_required_for_messages("use-tuple-over-list")
     def leave_functiondef(self, node: nodes.FunctionDef):
         self._raise_for_scope()

diff --git a/pyproject.toml b/pyproject.toml
index a7ca680..386adc1 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -8,7 +8,7 @@ authors = [{name = "Anthony Shaw"}]
 readme = "README.md"
 classifiers = ["License :: OSI Approved :: MIT License"]
 dynamic = ["version", "description"]
-dependencies = ["pylint >= 2.12.0, < 3.0"]
+dependencies = ["pylint >=3.0.0,<4.0.0"]

 [project.urls]
 Home = "https://github.com/tonybaloney/perflint"