--- 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: