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

branch
eric7
changeset 9221
bf71ee032bb4
parent 9209
b99e7fd55fd3
child 9271
f655c20ff500
--- a/src/eric7/Plugins/CheckerPlugins/CodeStyleChecker/Naming/NamingStyleChecker.py	Wed Jul 13 11:16:20 2022 +0200
+++ b/src/eric7/Plugins/CheckerPlugins/CodeStyleChecker/Naming/NamingStyleChecker.py	Wed Jul 13 14:55:47 2022 +0200
@@ -13,7 +13,7 @@
 import os
 
 try:
-    ast.AsyncFunctionDef    # __IGNORE_EXCEPTION__
+    ast.AsyncFunctionDef  # __IGNORE_EXCEPTION__
 except AttributeError:
     ast.AsyncFunctionDef = ast.FunctionDef
 
@@ -22,20 +22,33 @@
     """
     Class implementing a checker for naming conventions.
     """
+
     LowercaseRegex = re.compile(r"[_a-z][_a-z0-9]*$")
     UppercaseRegexp = re.compile(r"[_A-Z][_A-Z0-9]*$")
     CamelcaseRegexp = re.compile(r"_?[A-Z][a-zA-Z0-9]*$")
     MixedcaseRegexp = re.compile(r"_?[a-z][a-zA-Z0-9]*$")
-    
+
     Codes = [
-        "N801", "N802", "N803", "N804", "N805", "N806", "N807", "N808",
-        "N811", "N812", "N813", "N814", "N821", "N831"
+        "N801",
+        "N802",
+        "N803",
+        "N804",
+        "N805",
+        "N806",
+        "N807",
+        "N808",
+        "N811",
+        "N812",
+        "N813",
+        "N814",
+        "N821",
+        "N831",
     ]
-    
+
     def __init__(self, tree, filename, options):
         """
         Constructor (according to 'extended' pycodestyle.py API)
-        
+
         @param tree AST tree of the source file
         @param filename name of the source file (string)
         @param options options as parsed by pycodestyle.StyleGuide
@@ -43,7 +56,7 @@
         self.__parents = collections.deque()
         self.__tree = tree
         self.__filename = filename
-        
+
         self.__checkersWithCodes = {
             "classdef": [
                 (self.__checkClassName, ("N801",)),
@@ -51,8 +64,7 @@
             ],
             "functiondef": [
                 (self.__checkFunctionName, ("N802",)),
-                (self.__checkFunctionArgumentNames,
-                    ("N803", "N804", "N805", "N806")),
+                (self.__checkFunctionArgumentNames, ("N803", "N804", "N805", "N806")),
                 (self.__checkNameToBeAvoided, ("N831",)),
             ],
             "assign": [
@@ -66,12 +78,11 @@
                 (self.__checkModule, ("N807", "N808")),
             ],
         }
-        
+
         self.__checkers = {}
         for key, checkers in self.__checkersWithCodes.items():
             for checker, codes in checkers:
-                if any(not (code and options.ignore_code(code))
-                        for code in codes):
+                if any(not (code and options.ignore_code(code)) for code in codes):
                     if key not in self.__checkers:
                         self.__checkers[key] = []
                     self.__checkers[key].append(checker)
@@ -79,7 +90,7 @@
     def run(self):
         """
         Public method run by the pycodestyle.py checker.
-        
+
         @return tuple giving line number, offset within line, code and
             checker function
         """
@@ -87,11 +98,11 @@
             return self.__visitTree(self.__tree)
         else:
             return ()
-    
+
     def __visitTree(self, node):
         """
         Private method to scan the given AST tree.
-        
+
         @param node AST tree node to scan
         @yield tuple giving line number, offset within line and error code
         @ytype tuple of (int, int, str)
@@ -101,11 +112,11 @@
         for child in ast.iter_child_nodes(node):
             yield from self.__visitTree(child)
         self.__parents.pop()
-    
+
     def __visitNode(self, node):
         """
         Private method to inspect the given AST node.
-        
+
         @param node AST tree node to inspect
         @yield tuple giving line number, offset within line and error code
         @ytype tuple of (int, int, str)
@@ -114,31 +125,33 @@
             self.__tagClassFunctions(node)
         elif isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef)):
             self.__findGlobalDefs(node)
-        
+
         checkerName = node.__class__.__name__.lower()
         if checkerName in self.__checkers:
             for checker in self.__checkers[checkerName]:
                 for error in checker(node, self.__parents):
                     yield error + (self.__checkers[checkerName],)
-    
+
     def __tagClassFunctions(self, classNode):
         """
         Private method to tag functions if they are methods, class methods or
         static methods.
-        
+
         @param classNode AST tree node to tag
         """
         # try to find all 'old style decorators'
         # like m = staticmethod(m)
         lateDecoration = {}
         for node in ast.iter_child_nodes(classNode):
-            if not (isinstance(node, ast.Assign) and
-                    isinstance(node.value, ast.Call) and
-                    isinstance(node.value.func, ast.Name)):
+            if not (
+                isinstance(node, ast.Assign)
+                and isinstance(node.value, ast.Call)
+                and isinstance(node.value.func, ast.Name)
+            ):
                 continue
             funcName = node.value.func.id
             if funcName in ("classmethod", "staticmethod"):
-                meth = (len(node.value.args) == 1 and node.value.args[0])
+                meth = len(node.value.args) == 1 and node.value.args[0]
                 if isinstance(meth, ast.Name):
                     lateDecoration[meth.id] = funcName
 
@@ -146,24 +159,27 @@
         for node in ast.iter_child_nodes(classNode):
             if not isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef)):
                 continue
-            
-            node.function_type = 'method'
+
+            node.function_type = "method"
             if node.name == "__new__":
                 node.function_type = "classmethod"
-            
+
             if node.name in lateDecoration:
                 node.function_type = lateDecoration[node.name]
             elif node.decorator_list:
-                names = [d.id for d in node.decorator_list
-                         if isinstance(d, ast.Name) and
-                         d.id in ("classmethod", "staticmethod")]
+                names = [
+                    d.id
+                    for d in node.decorator_list
+                    if isinstance(d, ast.Name)
+                    and d.id in ("classmethod", "staticmethod")
+                ]
                 if names:
                     node.function_type = names[0]
 
     def __findGlobalDefs(self, functionNode):
         """
         Private method amend a node with global definitions information.
-        
+
         @param functionNode AST tree node to amend
         """
         globalNames = set()
@@ -173,26 +189,27 @@
             if isinstance(node, ast.Global):
                 globalNames.update(node.names)
 
-            if not isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef,
-                                     ast.ClassDef)):
+            if not isinstance(
+                node, (ast.FunctionDef, ast.AsyncFunctionDef, ast.ClassDef)
+            ):
                 nodesToCheck.extend(ast.iter_child_nodes(node))
         functionNode.global_names = globalNames
-    
+
     def __getArgNames(self, node):
         """
         Private method to get the argument names of a function node.
-        
+
         @param node AST node to extract arguments names from
         @return list of argument names (list of string)
         """
         posArgs = [arg.arg for arg in node.args.args]
         kwOnly = [arg.arg for arg in node.args.kwonlyargs]
         return posArgs + kwOnly
-    
+
     def __error(self, node, code):
         """
         Private method to build the error information.
-        
+
         @param node AST node to report an error for
         @param code error code to report (string)
         @return tuple giving line number, offset within line and error code
@@ -211,69 +228,68 @@
                 lineno += len(node.decorator_list)
                 offset += 4
         return (lineno, offset, code)
-    
+
     def __isNameToBeAvoided(self, name):
         """
         Private method to check, if the given name should be avoided.
-        
+
         @param name name to be checked (string)
         @return flag indicating to avoid it (boolen)
         """
         return name in ("l", "O", "I")
-    
+
     def __checkNameToBeAvoided(self, node, parents):
         """
         Private class to check the given node for a name to be avoided (N831).
-        
+
         @param node AST note to check
         @param parents list of parent nodes
         @yield tuple giving line number, offset within line and error code
         @ytype tuple of (int, int, str)
         """
-        if isinstance(node, (ast.ClassDef, ast.FunctionDef,
-                             ast.AsyncFunctionDef)):
+        if isinstance(node, (ast.ClassDef, ast.FunctionDef, ast.AsyncFunctionDef)):
             name = node.name
             if self.__isNameToBeAvoided(name):
                 yield self.__error(node, "N831")
                 return
-        
+
         if isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef)):
             argNames = self.__getArgNames(node)
             for arg in argNames:
                 if self.__isNameToBeAvoided(arg):
                     yield self.__error(node, "N831")
                     return
-        
+
         if isinstance(node, ast.Assign):
             for target in node.targets:
                 if isinstance(target, ast.Name):
                     name = target.id
                     if not name:
                         return
-                    
+
                     if self.__isNameToBeAvoided(name):
                         yield self.__error(node, "N831")
                         return
-                
+
                 elif isinstance(target, (ast.Tuple, ast.List)):
                     for element in target.elts:
                         if isinstance(element, ast.Name):
                             name = element.id
                             if not name:
                                 return
-                            
+
                             if self.__isNameToBeAvoided(name):
                                 yield self.__error(node, "N831")
                                 return
-    
+
     def __checkClassName(self, node, parents):
         """
         Private class to check the given node for class name
         conventions (N801).
-        
+
         Almost without exception, class names use the CapWords convention.
         Classes for internal use have a leading underscore in addition.
-        
+
         @param node AST note to check
         @param parents list of parent nodes
         @yield tuple giving line number, offset within line and error code
@@ -281,18 +297,18 @@
         """
         if not self.CamelcaseRegexp.match(node.name):
             yield self.__error(node, "N801")
-    
+
     def __checkFunctionName(self, node, parents):
         """
         Private class to check the given node for function name
         conventions (N802).
-        
+
         Function names should be lowercase, with words separated by underscores
         as necessary to improve readability. Functions <b>not</b> being
         methods '__' in front and back are not allowed. Mixed case is allowed
         only in contexts where that's already the prevailing style
         (e.g. threading.py), to retain backwards compatibility.
-        
+
         @param node AST note to check
         @param parents list of parent nodes
         @yield tuple giving line number, offset within line and error code
@@ -301,20 +317,19 @@
         functionType = getattr(node, "function_type", "function")
         name = node.name
         if (
-            (functionType == "function" and "__" in (name[:2], name[-2:])) or
-            not self.LowercaseRegex.match(name)
-        ):
+            functionType == "function" and "__" in (name[:2], name[-2:])
+        ) or not self.LowercaseRegex.match(name):
             yield self.__error(node, "N802")
-    
+
     def __checkFunctionArgumentNames(self, node, parents):
         """
         Private class to check the argument names of functions
         (N803, N804, N805, N806).
-        
+
         The argument names of a function should be lowercase, with words
         separated by underscores. A class method should have 'cls' as the
         first argument. A method should have 'self' as the first argument.
-        
+
         @param node AST note to check
         @param parents list of parent nodes
         @yield tuple giving line number, offset within line and error code
@@ -325,49 +340,40 @@
             if not self.LowercaseRegex.match(kwarg):
                 yield self.__error(node, "N803")
                 return
-        
+
         if node.args.vararg is not None:
             vararg = node.args.vararg.arg
             if not self.LowercaseRegex.match(vararg):
                 yield self.__error(node, "N803")
                 return
-        
+
         argNames = self.__getArgNames(node)
         functionType = getattr(node, "function_type", "function")
-        
+
         if not argNames:
             if functionType == "method":
                 yield self.__error(node, "N805")
             elif functionType == "classmethod":
                 yield self.__error(node, "N804")
             return
-        
-        if (
-            functionType == "method" and
-            argNames[0] != "self"
-        ):
+
+        if functionType == "method" and argNames[0] != "self":
             yield self.__error(node, "N805")
-        elif (
-            functionType == "classmethod" and
-            argNames[0] != "cls"
-        ):
+        elif functionType == "classmethod" and argNames[0] != "cls":
             yield self.__error(node, "N804")
-        elif (
-            functionType == "staticmethod" and
-            argNames[0] in ("cls", "self")
-        ):
+        elif functionType == "staticmethod" and argNames[0] in ("cls", "self"):
             yield self.__error(node, "N806")
         for arg in argNames:
             if not self.LowercaseRegex.match(arg):
                 yield self.__error(node, "N803")
                 return
-    
+
     def __checkVariablesInFunction(self, node, parents):
         """
         Private method to check local variables in functions (N821).
-        
+
         Local variables in functions should be lowercase.
-        
+
         @param node AST note to check
         @param parents list of parent nodes
         @yield tuple giving line number, offset within line and error code
@@ -384,16 +390,16 @@
             name = isinstance(target, ast.Name) and target.id
             if not name or name in parentFunc.global_names:
                 return
-            
-            if not self.LowercaseRegex.match(name) and name[:1] != '_':
+
+            if not self.LowercaseRegex.match(name) and name[:1] != "_":
                 yield self.__error(target, "N821")
-    
+
     def __checkModule(self, node, parents):
         """
         Private method to check module naming conventions (N807, N808).
-        
+
         Module and package names should be lowercase.
-        
+
         @param node AST note to check
         @param parents list of parent nodes
         @yield tuple giving line number, offset within line and error code
@@ -403,20 +409,18 @@
             moduleName = os.path.splitext(os.path.basename(self.__filename))[0]
             if moduleName.lower() != moduleName:
                 yield self.__error(node, "N807")
-            
+
             if moduleName == "__init__":
                 # we got a package
-                packageName = (
-                    os.path.split(os.path.dirname(self.__filename))[1]
-                )
+                packageName = os.path.split(os.path.dirname(self.__filename))[1]
                 if packageName.lower() != packageName:
                     yield self.__error(node, "N808")
-    
+
     def __checkImportAs(self, node, parents):
         """
         Private method to check that imports don't change the
         naming convention (N811, N812, N813, N814).
-        
+
         @param node AST note to check
         @param parents list of parent nodes
         @yield tuple giving line number, offset within line and error code
@@ -425,7 +429,7 @@
         for name in node.names:
             if not name.asname:
                 continue
-            
+
             if self.UppercaseRegexp.match(name.name):
                 if not self.UppercaseRegexp.match(name.asname):
                     yield self.__error(node, "N811")

eric ide

mercurial