src/eric7/Plugins/CheckerPlugins/CodeStyleChecker/Complexity/ComplexityChecker.py

branch
eric7
changeset 9221
bf71ee032bb4
parent 9209
b99e7fd55fd3
child 9473
3f23dbf37dbe
diff -r e9e7eca7efee -r bf71ee032bb4 src/eric7/Plugins/CheckerPlugins/CodeStyleChecker/Complexity/ComplexityChecker.py
--- a/src/eric7/Plugins/CheckerPlugins/CodeStyleChecker/Complexity/ComplexityChecker.py	Wed Jul 13 11:16:20 2022 +0200
+++ b/src/eric7/Plugins/CheckerPlugins/CodeStyleChecker/Complexity/ComplexityChecker.py	Wed Jul 13 14:55:47 2022 +0200
@@ -17,15 +17,17 @@
     """
     Class implementing a checker for code complexity.
     """
+
     Codes = [
         "C101",
-        "C111", "C112",
+        "C111",
+        "C112",
     ]
 
     def __init__(self, source, filename, tree, select, ignore, args):
         """
         Constructor
-        
+
         @param source source code to be checked
         @type list of str
         @param filename name of the source file
@@ -43,32 +45,31 @@
         self.__source = source[:]
         self.__tree = copy.deepcopy(tree)
         self.__select = tuple(select)
-        self.__ignore = ('',) if select else tuple(ignore)
+        self.__ignore = ("",) if select else tuple(ignore)
         self.__args = args
-        
+
         self.__defaultArgs = {
             "McCabeComplexity": 10,
             "LineComplexity": 15,
             "LineComplexityScore": 10,
         }
-        
+
         # statistics counters
         self.counters = {}
-        
+
         # collection of detected errors
         self.errors = []
-        
+
         checkersWithCodes = [
             (self.__checkMcCabeComplexity, ("C101",)),
             (self.__checkLineComplexity, ("C111", "C112")),
         ]
-        
+
         self.__checkers = []
         for checker, codes in checkersWithCodes:
-            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.append(checker)
-    
+
     def __ignoreCode(self, code):
         """
         Private method to check if the message code should be ignored.
@@ -78,13 +79,12 @@
         @return flag indicating to ignore the given code
         @rtype bool
         """
-        return (code.startswith(self.__ignore) and
-                not code.startswith(self.__select))
-    
+        return code.startswith(self.__ignore) and not code.startswith(self.__select)
+
     def __error(self, lineNumber, offset, code, *args):
         """
         Private method to record an issue.
-        
+
         @param lineNumber line number of the issue
         @type int
         @param offset position within line of the issue
@@ -96,12 +96,12 @@
         """
         if self.__ignoreCode(code):
             return
-        
+
         if code in self.counters:
             self.counters[code] += 1
         else:
             self.counters[code] = 1
-        
+
         if code:
             # record the issue with one based line number
             self.errors.append(
@@ -113,7 +113,7 @@
                     "args": args,
                 }
             )
-    
+
     def run(self):
         """
         Public method to check the given source for code complexity.
@@ -121,59 +121,62 @@
         if not self.__filename or not self.__source:
             # don't do anything, if essential data is missing
             return
-        
+
         if not self.__checkers:
             # don't do anything, if no codes were selected
             return
-        
+
         for check in self.__checkers:
             check()
-    
+
     def __checkMcCabeComplexity(self):
         """
         Private method to check the McCabe code complexity.
         """
         try:
             # create the AST again because it is modified by the checker
-            tree = compile(''.join(self.__source), self.__filename, 'exec',
-                           ast.PyCF_ONLY_AST)
+            tree = compile(
+                "".join(self.__source), self.__filename, "exec", ast.PyCF_ONLY_AST
+            )
         except (SyntaxError, TypeError):
             # compile errors are already reported by the run() method
             return
-        
-        maxComplexity = self.__args.get("McCabeComplexity",
-                                        self.__defaultArgs["McCabeComplexity"])
-        
+
+        maxComplexity = self.__args.get(
+            "McCabeComplexity", self.__defaultArgs["McCabeComplexity"]
+        )
+
         visitor = PathGraphingAstVisitor()
         visitor.preorder(tree, visitor)
         for graph in visitor.graphs.values():
             if graph.complexity() > maxComplexity:
-                self.__error(graph.lineno, 0, "C101",
-                             graph.entity, graph.complexity())
-    
+                self.__error(graph.lineno, 0, "C101", graph.entity, graph.complexity())
+
     def __checkLineComplexity(self):
         """
         Private method to check the complexity of a single line of code and
         the median line complexity of the source code.
-        
+
         Complexity is defined as the number of AST nodes produced by a line
         of code.
         """
         maxLineComplexity = self.__args.get(
-            "LineComplexity", self.__defaultArgs["LineComplexity"])
+            "LineComplexity", self.__defaultArgs["LineComplexity"]
+        )
         maxLineComplexityScore = self.__args.get(
-            "LineComplexityScore", self.__defaultArgs["LineComplexityScore"])
-        
+            "LineComplexityScore", self.__defaultArgs["LineComplexityScore"]
+        )
+
         visitor = LineComplexityVisitor()
         visitor.visit(self.__tree)
-        
+
         sortedItems = visitor.sortedList()
         score = visitor.score()
-        
+
         for line, complexity in sortedItems:
             if complexity > maxLineComplexity:
                 self.__error(line, 0, "C111", complexity)
-        
+
         if score > maxLineComplexityScore:
             self.__error(0, 0, "C112", score)
 
@@ -183,40 +186,40 @@
     Class calculating the number of AST nodes per line of code
     and the median nodes/line score.
     """
+
     def __init__(self):
         """
         Constructor
         """
         super().__init__()
         self.__count = {}
-    
+
     def visit(self, node):
         """
         Public method to recursively visit all the nodes and add up the
         instructions.
-        
+
         @param node reference to the node
         @type ast.AST
         """
-        if hasattr(node, 'lineno'):
+        if hasattr(node, "lineno"):
             self.__count[node.lineno] = self.__count.get(node.lineno, 0) + 1
         self.generic_visit(node)
-    
+
     def sortedList(self):
         """
         Public method to get a sorted list of (line, nodes) tuples.
-        
+
         @return sorted list of (line, nodes) tuples
         @rtype list of tuple of (int,int)
         """
-        lst = [(line, self.__count[line])
-               for line in sorted(self.__count.keys())]
+        lst = [(line, self.__count[line]) for line in sorted(self.__count.keys())]
         return lst
 
     def score(self):
         """
         Public method to calculate the median.
-        
+
         @return median line complexity value
         @rtype float
         """
@@ -224,12 +227,10 @@
         sortedList = sorted(lst)
         listLength = len(lst)
         medianIndex = (listLength - 1) // 2
-        
+
         if listLength == 0:
             return 0.0
-        elif (listLength % 2):
+        elif listLength % 2:
             return float(sortedList[medianIndex])
         else:
-            return (
-                (sortedList[medianIndex] + sortedList[medianIndex + 1]) / 2.0
-            )
+            return (sortedList[medianIndex] + sortedList[medianIndex + 1]) / 2.0

eric ide

mercurial