eric6/Plugins/CheckerPlugins/CodeStyleChecker/MiscellaneousChecker.py

changeset 7651
ca87b7490449
parent 7639
422fd05e9c91
--- a/eric6/Plugins/CheckerPlugins/CodeStyleChecker/MiscellaneousChecker.py	Mon Jul 27 19:15:26 2020 +0200
+++ b/eric6/Plugins/CheckerPlugins/CodeStyleChecker/MiscellaneousChecker.py	Wed Jul 29 17:37:09 2020 +0200
@@ -1471,6 +1471,17 @@
         
         self.generic_visit(node)
     
+    def visit_AsyncFor(self, node):
+        """
+        Public method to handle 'for' statements.
+        
+        @param node reference to the node to be processed
+        @type ast.AsyncFor
+        """
+        self.__checkForM507(node)
+        
+        self.generic_visit(node)
+    
     def visit_Assert(self, node):
         """
         Public method to handle 'assert' statements.
@@ -1602,6 +1613,7 @@
         
         self.__stack = []
         self.violations = []
+        self.__loopCount = 0
     
     @property
     def assigns(self):
@@ -1636,6 +1648,44 @@
         """
         return self.__stack[-1][ReturnVisitor.Returns]
     
+    def visit_For(self, node):
+        """
+        Public method to handle a for loop.
+        
+        @param node reference to the for node to handle
+        @type ast.For
+        """
+        self.__visitLoop(node)
+    
+    def visit_AsyncFor(self, node):
+        """
+        Public method to handle an async for loop.
+        
+        @param node reference to the async for node to handle
+        @type ast.AsyncFor
+        """
+        self.__visitLoop(node)
+    
+    def visit_While(self, node):
+        """
+        Public method to handle a while loop.
+        
+        @param node reference to the while node to handle
+        @type ast.While
+        """
+        self.__visitLoop(node)
+    
+    def __visitLoop(self, node):
+        """
+        Private method to handle loop nodes.
+        
+        @param node reference to the loop node to handle
+        @type ast.For, ast.AsyncFor or ast.While
+        """
+        self.__loopCount += 1
+        self.generic_visit(node)
+        self.__loopCount -= 1
+    
     def __visitWithStack(self, node):
         """
         Private method to traverse a given function node using a stack.
@@ -1690,10 +1740,18 @@
         """
         if not self.__stack:
             return
+
+        self.generic_visit(node.value)
         
-        for target in node.targets:
-            self.__visitAssignTarget(target)
-        self.generic_visit(node.value)
+        target = node.targets[0]
+        if (
+            isinstance(target, ast.Tuple) and
+            not isinstance(node.value, ast.Tuple)
+        ):
+            # skip unpacking assign
+            return
+        
+        self.__visitAssignTarget(target)
     
     def visit_Name(self, node):
         """
@@ -1717,7 +1775,7 @@
                 self.__visitAssignTarget(elt)
             return
         
-        if isinstance(node, ast.Name):
+        if not self.__loopCount and isinstance(node, ast.Name):
             self.assigns[node.id].append(node.lineno)
             return
         
@@ -1755,12 +1813,27 @@
         @param node reference to the node to check
         @type ast.AST
         @return flag indicating the node contains a None value
+        @rtype bool
         """
         return (
             AstUtilities.isNameConstant(node) and
             AstUtilities.getValue(node) is None
         )
     
+    def __isFalse(self, node):
+        """
+        Private method to check, if a node value is False.
+        
+        @param node reference to the node to check
+        @type ast.AST
+        @return flag indicating the node contains a False value
+        @rtype bool
+        """
+        return (
+            AstUtilities.isNameConstant(node) and
+            AstUtilities.getValue(node) is False
+        )
+    
     def __resultExists(self):
         """
         Private method to check the existance of a return result.
@@ -1807,14 +1880,17 @@
             self.__checkImplicitReturn(node.orelse[-1])
             return
         
-        if isinstance(node, ast.For) and node.orelse:
+        if isinstance(node, (ast.For, ast.AsyncFor)) and node.orelse:
             self.__checkImplicitReturn(node.orelse[-1])
             return
         
-        if isinstance(node, ast.With):
+        if isinstance(node, (ast.With, ast.AsyncWith)):
             self.__checkImplicitReturn(node.body[-1])
             return
         
+        if isinstance(node, ast.Assert) and self.__isFalse(node.test):
+            return
+        
         try:
             okNodes = (ast.Return, ast.Raise, ast.While, ast.Try)
         except AttributeError:

eric ide

mercurial