Sat, 10 Apr 2021 15:11:43 +0200
Code Style Checker
- don't treat 'if __name__ == "__main__":' as an issue
- added a check for if-blocks which only check if a key is in a dictionary
- added a check for bare boolean function arguments
- added a check for bare numeric function arguments
--- a/eric6/Plugins/CheckerPlugins/CodeStyleChecker/Simplify/SimplifyChecker.py Sat Apr 10 13:02:08 2021 +0200 +++ b/eric6/Plugins/CheckerPlugins/CodeStyleChecker/Simplify/SimplifyChecker.py Sat Apr 10 15:11:43 2021 +0200 @@ -21,7 +21,7 @@ # Python-specifics "Y101", "Y102", "Y103", "Y104", "Y105", "Y106", "Y107", "Y108", "Y109", "Y110", "Y111", "Y112", "Y113", "Y114", "Y115", "Y116", - "Y117", "Y118", "Y119", "Y120", "Y121", + "Y117", "Y118", "Y119", "Y120", "Y121", "Y122", # Python-specifics not part of flake8-simplify "Y181", "Y182", @@ -33,6 +33,9 @@ # Opinionated "Y301", + + # General Code Style + "Y401", "Y402", ] def __init__(self, source, filename, tree, selected, ignored, expected,
--- a/eric6/Plugins/CheckerPlugins/CodeStyleChecker/Simplify/SimplifyNodeVisitor.py Sat Apr 10 13:02:08 2021 +0200 +++ b/eric6/Plugins/CheckerPlugins/CodeStyleChecker/Simplify/SimplifyNodeVisitor.py Sat Apr 10 15:11:43 2021 +0200 @@ -120,6 +120,7 @@ self.__check108(node) self.__check114(node) self.__check116(node) + self.__check122(node) self.generic_visit(node) @@ -171,6 +172,8 @@ """ self.__check115(node) self.__check182(node) + self.__check401(node) + self.__check402(node) self.generic_visit(node) @@ -208,7 +211,7 @@ self.__classDefinitionStack.append(node.name) self.__check119(node) - self.__check120(node) + self.__check120_121(node) self.generic_visit(node) @@ -433,6 +436,17 @@ @param node reference to the AST node to be checked @type ast.If """ + # Don't treat 'if __name__ == "__main__":' as an issue. + if ( + isinstance(node.test, ast.Compare) and + isinstance(node.test.left, ast.Name) and + node.test.left.id == "__name__" and + isinstance(node.test.ops[0], ast.Eq) and + isinstance(node.test.comparators[0], ast.Constant) and + node.test.comparators[0].value == "__main__" + ): + return + # ## Pattern 1 # if a: <--- # if b: <--- @@ -444,7 +458,7 @@ node.body[0].orelse == [] ) # ## Pattern 2 - # if a: < irrelvant for here + # if a: < irrelevant for here # pass # elif b: <--- this is treated like a nested block # if c: <--- @@ -712,7 +726,7 @@ check, target, iterable) elif node.body[0].body[0].value.value is False: check = "not " + check - if check.startswith("not not"): + if check.startswith("not not "): check = check[len("not not "):] self.__error(node.lineno - 1, node.col_offset, "Y111", check, target, iterable) @@ -1059,7 +1073,7 @@ self.__error(node.lineno - 1, node.col_offset, "Y119", node.name) - def __check120(self, node): + def __check120_121(self, node): """ Private method to check for classes that inherit from object. @@ -1084,6 +1098,34 @@ self.__error(node.lineno - 1, node.col_offset, "Y121", node.name, ", ".join(b.id for b in node.bases[:-1])) + def __check122(self, node): + """ + Private method to check for all if-blocks which only check if a key + is in a dictionary. + + @param node reference to the AST node to be checked + @type ast.If + """ + if ( + isinstance(node.test, ast.Compare) and + len(node.test.ops) == 1 and + isinstance(node.test.ops[0], ast.In) and + len(node.body) == 1 and + len(node.orelse) == 0 + ) and ( + # We might still be left with a check if a value is in a list or + # in the body the developer might remove the element from the list. + # We need to have a look at the body. + isinstance(node.body[0], ast.Assign) and + isinstance(node.body[0].value, ast.Subscript) and + len(node.body[0].targets) == 1 and + isinstance(node.body[0].targets[0], ast.Name) + ): + key = unparse(node.test.left) + dictname = unparse(node.test.comparators[0]) + self.__error(node.lineno - 1, node.col_offset, "Y122", + dictname, key) + def __check181(self, node): """ Private method to check for assignments that could be converted into @@ -1494,6 +1536,54 @@ right = unparse(node.comparators[0]) self.__error(node.lineno - 1, node.col_offset, "Y301", left, right) + + def __check401(self, node): + """ + Private method to check for bare boolean function arguments. + + @param node reference to the AST node to be checked + @type ast.Call + """ + # foo(a, b, True) + hasBareBool = any( + isinstance(callArg, ast.Constant) and + (callArg.value is True or callArg.value is False) + for callArg in node.args + ) + + isException = ( + isinstance(node.func, ast.Attribute) and + node.func.attr in ["get"] + ) + + if hasBareBool and not isException: + self.__error(node.lineno - 1, node.col_offset, "Y401") + + def __check402(self, node): + """ + Private method to check for bare numeric function arguments. + + @param node reference to the AST node to be checked + @type ast.Call + """ + # foo(a, b, 123123) + hasBareNumeric = any( + isinstance(callArg, ast.Constant) and + type(callArg.value) in (float, int) + for callArg in node.args + ) + + isException = ( + isinstance(node.func, ast.Name) and + node.func.id == "range" + ) + isException = isException or ( + isinstance(node.func, ast.Attribute) and + node.func.attr in ["get", "insert",] + ) + + if hasBareNumeric and not isException: + self.__error(node.lineno - 1, node.col_offset, "Y402") # # eflag: noqa = M891
--- a/eric6/Plugins/CheckerPlugins/CodeStyleChecker/Simplify/translations.py Sat Apr 10 13:02:08 2021 +0200 +++ b/eric6/Plugins/CheckerPlugins/CodeStyleChecker/Simplify/translations.py Sat Apr 10 15:11:43 2021 +0200 @@ -44,10 +44,10 @@ '''Use "{0} in {1}" instead of "{2}"'''), "Y110": QCoreApplication.translate( "SimplifyChecker", - '''Use "return any({0} for {1} in {2})"'''), + '''Use "any({0} for {1} in {2})"'''), "Y111": QCoreApplication.translate( "SimplifyChecker", - '''Use "return all({0} for {1} in {2})"'''), + '''Use "all({0} for {1} in {2})"'''), "Y112": QCoreApplication.translate( "SimplifyChecker", '''Use "{0}" instead of "{1}"'''), @@ -79,6 +79,9 @@ "Y121": QCoreApplication.translate( "SimplifyChecker", '''Use "class {0}({1}):" instead of "class {0}({1}, object):"'''), + "Y122": QCoreApplication.translate( + "SimplifyChecker", + '''Use "{0}.get({1})" instead of "if {1} in {0}: {0}[{1}]"'''), # Python-specifics not part of flake8-simplify "Y181": QCoreApplication.translate( @@ -137,9 +140,18 @@ "SimplifyChecker", '''Use "False" instead of "... and False"'''), + # Opinionated "Y301": QCoreApplication.translate( "SimplifyChecker", '''Use "{1} == {0}" instead of "{0} == {1}" (Yoda-condition)'''), + + # General Code Style + "Y401": QCoreApplication.translate( + "SimplifyChecker", + '''Use keyword-argument instead of magic boolean'''), + "Y402": QCoreApplication.translate( + "SimplifyChecker", + '''Use keyword-argument instead of magic number'''), } _simplifyMessagesSampleArgs = { @@ -161,6 +173,7 @@ "Y119": ["Foo"], "Y120": ["Foo"], "Y121": ["FooBar", "Foo"], + "Y122": ["bar_dict", "'foo'"], # Python-specifics not part of flake8-simplify "Y181": ["foo += 42", "foo = foo + 42"], @@ -183,5 +196,8 @@ "Y221": ["foo"], "Y222": ["foo"], + # Opinionated "Y301": ["42", "foo"], + + # General Code Style }