diff -r 7c7d96c28872 -r 2894aa889a4e eric6/Plugins/CheckerPlugins/CodeStyleChecker/MiscellaneousChecker.py --- a/eric6/Plugins/CheckerPlugins/CodeStyleChecker/MiscellaneousChecker.py Wed May 22 18:44:36 2019 +0200 +++ b/eric6/Plugins/CheckerPlugins/CodeStyleChecker/MiscellaneousChecker.py Wed May 22 18:54:05 2019 +0200 @@ -46,8 +46,10 @@ "M201", - "M501", "M502", "M503", "M504", "M505", "M506", "M507", - "M511", "M512", "M513", "M514", + "M501", "M502", "M503", "M504", "M505", "M506", "M507", "M508", + "M509", + "M511", "M512", "M513", + "M521", "M522", "M523", "M524", "M601", "M611", "M612", "M613", @@ -133,8 +135,9 @@ "M621", "M622", "M623", "M624", "M625", "M631", "M632")), (self.__checkBugBear, ("M501", "M502", "M503", "M504", "M505", - "M506", "M507", - "M511", "M512", "M513", "M514")), + "M506", "M507", "M508", "M509", + "M511", "M512", "M513", + "M521", "M522", "M523", "M524")), (self.__checkLogging, ("M651", "M652", "M653", "M654", "M655")), (self.__checkFuture, ("M701", "M702")), (self.__checkGettext, ("M711",)), @@ -653,6 +656,10 @@ "list", "set", ) + immutableCalls = ( + "tuple", + "frozenset", + ) functionDefs = [ast.FunctionDef] try: functionDefs.append(ast.AsyncFunctionDef) @@ -662,7 +669,7 @@ for node in ast.walk(self.__tree): if any(isinstance(node, functionDef) for functionDef in functionDefs): - for default in node.args.defaults: + for default in node.args.defaults + node.args.kw_defaults: if any(isinstance(default, mutableType) for mutableType in mutableTypes): typeName = type(default).__name__ @@ -672,7 +679,7 @@ self.__error(default.lineno - 1, default.col_offset, "M823", callPath + "()") - else: + elif callPath not in immutableCalls: self.__error(default.lineno - 1, default.col_offset, "M822", typeName) @@ -731,7 +738,7 @@ def __checkBugBear(self): """ - Private method to bugbear checks. + Private method for bugbear checks. """ visitor = BugBearVisitor() visitor.visit(self.__tree) @@ -1079,7 +1086,7 @@ Class implementing a node visitor to check for various topics. """ # - # This class was implemented along the BugBear flake8 extension (v 18.2.0). + # This class was implemented along the BugBear flake8 extension (v 19.3.0). # Original: Copyright (c) 2016 Ćukasz Langa # @@ -1135,9 +1142,9 @@ if sys.version_info >= (3, 0): validPaths = ("six", "future.utils", "builtins") methodsDict = { - "M511": ("iterkeys", "itervalues", "iteritems", "iterlists"), - "M512": ("viewkeys", "viewvalues", "viewitems", "viewlists"), - "M513": ("next",), + "M521": ("iterkeys", "itervalues", "iteritems", "iterlists"), + "M522": ("viewkeys", "viewvalues", "viewitems", "viewlists"), + "M523": ("next",), } else: validPaths = () @@ -1154,11 +1161,36 @@ self.__checkForM502(node) else: try: + # bad super() call + if isinstance(node.func, ast.Name) and node.func.id == "super": + args = node.args + if ( + len(args) == 2 and + isinstance(args[0], ast.Attribute) and + isinstance(args[0].value, ast.Name) and + args[0].value.id == 'self' and + args[0].attr == '__class__' + ): + self.violations.append((node, "M509")) + + # bad getattr and setattr if ( node.func.id in ("getattr", "hasattr") and node.args[1].s == "__call__" ): - self.violations.append((node, "M503")) + self.violations.append((node, "M511")) + if ( + node.func.id == "getattr" and + len(node.args) == 2 and + isinstance(node.args[1], ast.Str) + ): + self.violations.append((node, "M512")) + elif ( + node.func.id == "setattr" and + len(node.args) == 3 and + isinstance(node.args[1], ast.Str) + ): + self.violations.append((node, "M513")) except (AttributeError, IndexError): pass @@ -1196,7 +1228,7 @@ # and tuples for simplicity. assignTargets = {t.id for t in node.targets if hasattr(t, 'id')} if '__metaclass__' in assignTargets and sys.version_info >= (3, 0): - self.violations.append((node, "M514")) + self.violations.append((node, "M524")) elif len(node.targets) == 1: target = node.targets[0] @@ -1218,6 +1250,33 @@ self.generic_visit(node) + def visit_Assert(self, node): + """ + Public method to handle 'assert' statements. + + @param node reference to the node to be processed + @type ast.Assert + """ + if isinstance(node.test, ast.NameConstant) and \ + node.test.value is False: + self.violations.append((node, "M503")) + + self.generic_visit(node) + + def visit_JoinedStr(self, node): + """ + Public method to handle f-string arguments. + + @param node reference to the node to be processed + @type ast.JoinedStr + """ + if sys.version_info >= (3, 6): + for value in node.values: + if isinstance(value, ast.FormattedValue): + return + + self.violations.append((node, "M508")) + def __checkForM502(self, node): """ Private method to check the use of *strip().