src/eric7/Plugins/CheckerPlugins/CodeStyleChecker/Naming/NamingStyleChecker.py

branch
eric7
changeset 11150
73d80859079c
parent 11148
15e30f0c76a8
child 11163
f6c0a18254d6
diff -r fc45672fae42 -r 73d80859079c src/eric7/Plugins/CheckerPlugins/CodeStyleChecker/Naming/NamingStyleChecker.py
--- a/src/eric7/Plugins/CheckerPlugins/CodeStyleChecker/Naming/NamingStyleChecker.py	Thu Feb 27 09:22:15 2025 +0100
+++ b/src/eric7/Plugins/CheckerPlugins/CodeStyleChecker/Naming/NamingStyleChecker.py	Thu Feb 27 14:42:39 2025 +0100
@@ -9,7 +9,6 @@
 
 import ast
 import collections
-import copy
 import functools
 import os
 
@@ -18,9 +17,10 @@
 except AttributeError:
     ast.AsyncFunctionDef = ast.FunctionDef
 
+from CodeStyleTopicChecker import CodeStyleTopicChecker
 
-# TODO: change this to a checker like the others
-class NamingStyleChecker:
+
+class NamingStyleChecker(CodeStyleTopicChecker):
     """
     Class implementing a checker for naming conventions.
     """
@@ -46,6 +46,7 @@
         "N-823",
         "N-831",
     ]
+    Category = "N"
 
     def __init__(self, source, filename, tree, select, ignore, expected, repeat, args):
         """
@@ -68,23 +69,20 @@
         @param args dictionary of arguments for the various checks
         @type dict
         """
-        self.__select = tuple(select)
-        self.__ignore = tuple(ignore)
-        self.__expected = expected[:]
-        self.__repeat = repeat
-        self.__filename = filename
-        self.__source = source[:]
-        self.__tree = copy.deepcopy(tree)
-        self.__args = args
+        super().__init__(
+            NamingStyleChecker.Category,
+            source,
+            filename,
+            tree,
+            select,
+            ignore,
+            expected,
+            repeat,
+            args,
+        )
 
         self.__parents = collections.deque()
 
-        # statistics counters
-        self.counters = {}
-
-        # collection of detected errors
-        self.errors = []
-
         self.__checkersWithCodes = {
             "classdef": [
                 (self.__checkClassName, ("N-801", "N-818")),
@@ -130,32 +128,19 @@
         self.__checkers = collections.defaultdict(list)
         for key, checkers in self.__checkersWithCodes.items():
             for checker, codes in checkers:
-                if any(not (code and self.__ignoreCode(code)) for code in codes):
+                if any(not (code and self._ignoreCode(code)) for code in codes):
                     self.__checkers[key].append(checker)
 
-    def __ignoreCode(self, code):
+    def addErrorFromNode(self, node, msgCode):
         """
-        Private method to check if the message code should be ignored.
-
-        @param code message code to check for
-        @type str
-        @return flag indicating to ignore the given code
-        @rtype bool
-        """
-        return code in self.__ignore or (
-            code.startswith(self.__ignore) and not code.startswith(self.__select)
-        )
-
-    def __error(self, node, code):
-        """
-        Private method to build the error information.
+        Public method to build the error information.
 
         @param node AST node to report an error for
         @type ast.AST
-        @param code error code to report
+        @param msgCode message code
         @type str
         """
-        if self.__ignoreCode(code):
+        if self._ignoreCode(msgCode):
             return
 
         if isinstance(node, ast.Module):
@@ -171,41 +156,21 @@
                 lineno += len(node.decorator_list)
                 offset += 4
 
-        # record the issue with one based line number
-        errorInfo = {
-            "file": self.__filename,
-            "line": lineno,
-            "offset": offset,
-            "code": code,
-            "args": [],
-        }
-
-        if errorInfo not in self.errors:
-            # this issue was not seen before
-            if code in self.counters:
-                self.counters[code] += 1
-            else:
-                self.counters[code] = 1
-
-            # Don't care about expected codes
-            if code in self.__expected:
-                return
-
-            if code and (self.counters[code] == 1 or self.__repeat):
-                self.errors.append(errorInfo)
+        self.addError(lineno, offset, msgCode, [])
 
     def run(self):
         """
-        Public method run by the pycodestyle.py checker.
+        Public method to execute the relevant checks.
+        """
+        if not self.filename:
+            # don't do anything, if essential data is missing
+            return
 
-        @return tuple giving line number, offset within line, code and
-            checker function
-        @rtype tuple of (int, int, str, function)
-        """
-        if self.__tree and self.__checkers:
-            return self.__visitTree(self.__tree)
-        else:
-            return ()
+        if not self.__checkers:
+            # don't do anything, if no codes were selected
+            return
+
+        self.__visitTree(self.tree)
 
     def __visitTree(self, node):
         """
@@ -338,13 +303,13 @@
         if isinstance(node, (ast.ClassDef, ast.FunctionDef, ast.AsyncFunctionDef)):
             name = node.name
             if self.__isNameToBeAvoided(name):
-                self.__error(node, "N-831")
+                self.addErrorFromNode(node, "N-831")
 
         elif isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef)):
             argNames = self.__getArgNames(node)
             for arg in argNames:
                 if self.__isNameToBeAvoided(arg):
-                    self.__error(node, "N-831")
+                    self.addErrorFromNode(node, "N-831")
 
         elif isinstance(node, (ast.Assign, ast.NamedExpr, ast.AnnAssign)):
             if isinstance(node, ast.Assign):
@@ -355,14 +320,14 @@
                 if isinstance(target, ast.Name):
                     name = target.id
                     if bool(name) and self.__isNameToBeAvoided(name):
-                        self.__error(node, "N-831")
+                        self.addErrorFromNode(node, "N-831")
 
                 elif isinstance(target, (ast.Tuple, ast.List)):
                     for element in target.elts:
                         if isinstance(element, ast.Name):
                             name = element.id
                             if bool(name) and self.__isNameToBeAvoided(name):
-                                self.__error(node, "N-831")
+                                self.addErrorFromNode(node, "N-831")
 
     def __getClassdef(self, name, parents):
         """
@@ -425,11 +390,11 @@
         name = node.name
         strippedName = name.strip("_")
         if not strippedName[:1].isupper() or "_" in strippedName:
-            self.__error(node, "N-801")
+            self.addErrorFromNode(node, "N-801")
 
         superClasses = self.__superClassNames(name, parents)
         if "Exception" in superClasses and not name.endswith("Error"):
-            self.__error(node, "N-818")
+            self.addErrorFromNode(node, "N-818")
 
     def __checkFunctionName(self, node, _parents):
         """
@@ -454,9 +419,9 @@
             return
 
         if name.lower() != name:
-            self.__error(node, "N-802")
+            self.addErrorFromNode(node, "N-802")
         if functionType == "function" and name[:2] == "__" and name[-2:] == "__":
-            self.__error(node, "N-809")
+            self.addErrorFromNode(node, "N-809")
 
     def __checkFunctionArgumentNames(self, node, _parents):
         """
@@ -475,12 +440,12 @@
         if node.args.kwarg is not None:
             kwarg = node.args.kwarg.arg
             if kwarg.lower() != kwarg:
-                self.__error(node, "N-803")
+                self.addErrorFromNode(node, "N-803")
 
         elif node.args.vararg is not None:
             vararg = node.args.vararg.arg
             if vararg.lower() != vararg:
-                self.__error(node, "N-803")
+                self.addErrorFromNode(node, "N-803")
 
         else:
             argNames = self.__getArgNames(node)
@@ -488,19 +453,19 @@
 
             if not argNames:
                 if functionType == "method":
-                    self.__error(node, "N-805")
+                    self.addErrorFromNode(node, "N-805")
                 elif functionType == "classmethod":
-                    self.__error(node, "N-804")
+                    self.addErrorFromNode(node, "N-804")
 
             elif functionType == "method" and argNames[0] != "self":
-                self.__error(node, "N-805")
+                self.addErrorFromNode(node, "N-805")
             elif functionType == "classmethod" and argNames[0] != "cls":
-                self.__error(node, "N-804")
+                self.addErrorFromNode(node, "N-804")
             elif functionType == "staticmethod" and argNames[0] in ("cls", "self"):
-                self.__error(node, "N-806")
+                self.addErrorFromNode(node, "N-806")
             for arg in argNames:
                 if arg.lower() != arg:
-                    self.__error(node, "N-803")
+                    self.addErrorFromNode(node, "N-803")
                     break
 
     def __checkVariableNames(self, node, parents):
@@ -563,7 +528,7 @@
         for name in self.__extractNames(assignmentTarget):
             errorCode = checker(name)
             if errorCode:
-                self.__error(assignmentTarget, errorCode)
+                self.addErrorFromNode(assignmentTarget, errorCode)
 
     def __extractNames(self, assignmentTarget):
         """
@@ -678,13 +643,13 @@
         if self.__filename:
             moduleName = os.path.splitext(os.path.basename(self.__filename))[0]
             if moduleName.lower() != moduleName:
-                self.__error(node, "N-807")
+                self.addErrorFromNode(node, "N-807")
 
             if moduleName == "__init__":
                 # we got a package
                 packageName = os.path.split(os.path.dirname(self.__filename))[1]
                 if packageName.lower() != packageName:
-                    self.__error(node, "N-808")
+                    self.addErrorFromNode(node, "N-808")
 
     def __checkImportAs(self, node, _parents):
         """
@@ -704,14 +669,14 @@
             originalName = name.name
             if originalName.isupper():
                 if not asname.isupper():
-                    self.__error(node, "N-811")
+                    self.addErrorFromNode(node, "N-811")
             elif originalName.islower():
                 if asname.lower() != asname:
-                    self.__error(node, "N-812")
+                    self.addErrorFromNode(node, "N-812")
             elif asname.islower():
-                self.__error(node, "N-813")
+                self.addErrorFromNode(node, "N-813")
             elif asname.isupper():
                 if "".join(filter(str.isupper, originalName)) == asname:
-                    self.__error(node, "N-815")
+                    self.addErrorFromNode(node, "N-815")
                 else:
-                    self.__error(node, "N-814")
+                    self.addErrorFromNode(node, "N-814")

eric ide

mercurial