eric6/Plugins/CheckerPlugins/CodeStyleChecker/MiscellaneousChecker.py

changeset 7021
2894aa889a4e
parent 6942
2602857055c5
child 7040
f89952e5fc11
equal deleted inserted replaced
7020:7c7d96c28872 7021:2894aa889a4e
44 "M191", "M192", "M193", "M194", 44 "M191", "M192", "M193", "M194",
45 "M195", "M196", "M197", "M198", 45 "M195", "M196", "M197", "M198",
46 46
47 "M201", 47 "M201",
48 48
49 "M501", "M502", "M503", "M504", "M505", "M506", "M507", 49 "M501", "M502", "M503", "M504", "M505", "M506", "M507", "M508",
50 "M511", "M512", "M513", "M514", 50 "M509",
51 "M511", "M512", "M513",
52 "M521", "M522", "M523", "M524",
51 53
52 "M601", 54 "M601",
53 "M611", "M612", "M613", 55 "M611", "M612", "M613",
54 "M621", "M622", "M623", "M624", "M625", 56 "M621", "M622", "M623", "M624", "M625",
55 "M631", "M632", 57 "M631", "M632",
131 (self.__checkPep3101, ("M601",)), 133 (self.__checkPep3101, ("M601",)),
132 (self.__checkFormatString, ("M611", "M612", "M613", 134 (self.__checkFormatString, ("M611", "M612", "M613",
133 "M621", "M622", "M623", "M624", "M625", 135 "M621", "M622", "M623", "M624", "M625",
134 "M631", "M632")), 136 "M631", "M632")),
135 (self.__checkBugBear, ("M501", "M502", "M503", "M504", "M505", 137 (self.__checkBugBear, ("M501", "M502", "M503", "M504", "M505",
136 "M506", "M507", 138 "M506", "M507", "M508", "M509",
137 "M511", "M512", "M513", "M514")), 139 "M511", "M512", "M513",
140 "M521", "M522", "M523", "M524")),
138 (self.__checkLogging, ("M651", "M652", "M653", "M654", "M655")), 141 (self.__checkLogging, ("M651", "M652", "M653", "M654", "M655")),
139 (self.__checkFuture, ("M701", "M702")), 142 (self.__checkFuture, ("M701", "M702")),
140 (self.__checkGettext, ("M711",)), 143 (self.__checkGettext, ("M711",)),
141 (self.__checkPrintStatements, ("M801",)), 144 (self.__checkPrintStatements, ("M801",)),
142 (self.__checkTuple, ("M811", )), 145 (self.__checkTuple, ("M811", )),
651 "deque", 654 "deque",
652 "dict", 655 "dict",
653 "list", 656 "list",
654 "set", 657 "set",
655 ) 658 )
659 immutableCalls = (
660 "tuple",
661 "frozenset",
662 )
656 functionDefs = [ast.FunctionDef] 663 functionDefs = [ast.FunctionDef]
657 try: 664 try:
658 functionDefs.append(ast.AsyncFunctionDef) 665 functionDefs.append(ast.AsyncFunctionDef)
659 except AttributeError: 666 except AttributeError:
660 pass 667 pass
661 668
662 for node in ast.walk(self.__tree): 669 for node in ast.walk(self.__tree):
663 if any(isinstance(node, functionDef) 670 if any(isinstance(node, functionDef)
664 for functionDef in functionDefs): 671 for functionDef in functionDefs):
665 for default in node.args.defaults: 672 for default in node.args.defaults + node.args.kw_defaults:
666 if any(isinstance(default, mutableType) 673 if any(isinstance(default, mutableType)
667 for mutableType in mutableTypes): 674 for mutableType in mutableTypes):
668 typeName = type(default).__name__ 675 typeName = type(default).__name__
669 if isinstance(default, ast.Call): 676 if isinstance(default, ast.Call):
670 callPath = '.'.join(composeCallPath(default.func)) 677 callPath = '.'.join(composeCallPath(default.func))
671 if callPath in mutableCalls: 678 if callPath in mutableCalls:
672 self.__error(default.lineno - 1, 679 self.__error(default.lineno - 1,
673 default.col_offset, 680 default.col_offset,
674 "M823", callPath + "()") 681 "M823", callPath + "()")
675 else: 682 elif callPath not in immutableCalls:
676 self.__error(default.lineno - 1, 683 self.__error(default.lineno - 1,
677 default.col_offset, 684 default.col_offset,
678 "M822", typeName) 685 "M822", typeName)
679 else: 686 else:
680 self.__error(default.lineno - 1, 687 self.__error(default.lineno - 1,
729 self.__error(node.lineno - 1, node.col_offset, "M711", 736 self.__error(node.lineno - 1, node.col_offset, "M711",
730 node.names[0].name) 737 node.names[0].name)
731 738
732 def __checkBugBear(self): 739 def __checkBugBear(self):
733 """ 740 """
734 Private method to bugbear checks. 741 Private method for bugbear checks.
735 """ 742 """
736 visitor = BugBearVisitor() 743 visitor = BugBearVisitor()
737 visitor.visit(self.__tree) 744 visitor.visit(self.__tree)
738 for violation in visitor.violations: 745 for violation in visitor.violations:
739 node = violation[0] 746 node = violation[0]
1077 class BugBearVisitor(ast.NodeVisitor): 1084 class BugBearVisitor(ast.NodeVisitor):
1078 """ 1085 """
1079 Class implementing a node visitor to check for various topics. 1086 Class implementing a node visitor to check for various topics.
1080 """ 1087 """
1081 # 1088 #
1082 # This class was implemented along the BugBear flake8 extension (v 18.2.0). 1089 # This class was implemented along the BugBear flake8 extension (v 19.3.0).
1083 # Original: Copyright (c) 2016 Łukasz Langa 1090 # Original: Copyright (c) 2016 Łukasz Langa
1084 # 1091 #
1085 1092
1086 NodeWindowSize = 4 1093 NodeWindowSize = 4
1087 1094
1133 @type ast.Call 1140 @type ast.Call
1134 """ 1141 """
1135 if sys.version_info >= (3, 0): 1142 if sys.version_info >= (3, 0):
1136 validPaths = ("six", "future.utils", "builtins") 1143 validPaths = ("six", "future.utils", "builtins")
1137 methodsDict = { 1144 methodsDict = {
1138 "M511": ("iterkeys", "itervalues", "iteritems", "iterlists"), 1145 "M521": ("iterkeys", "itervalues", "iteritems", "iterlists"),
1139 "M512": ("viewkeys", "viewvalues", "viewitems", "viewlists"), 1146 "M522": ("viewkeys", "viewvalues", "viewitems", "viewlists"),
1140 "M513": ("next",), 1147 "M523": ("next",),
1141 } 1148 }
1142 else: 1149 else:
1143 validPaths = () 1150 validPaths = ()
1144 methodsDict = {} 1151 methodsDict = {}
1145 1152
1152 break 1159 break
1153 else: 1160 else:
1154 self.__checkForM502(node) 1161 self.__checkForM502(node)
1155 else: 1162 else:
1156 try: 1163 try:
1164 # bad super() call
1165 if isinstance(node.func, ast.Name) and node.func.id == "super":
1166 args = node.args
1167 if (
1168 len(args) == 2 and
1169 isinstance(args[0], ast.Attribute) and
1170 isinstance(args[0].value, ast.Name) and
1171 args[0].value.id == 'self' and
1172 args[0].attr == '__class__'
1173 ):
1174 self.violations.append((node, "M509"))
1175
1176 # bad getattr and setattr
1157 if ( 1177 if (
1158 node.func.id in ("getattr", "hasattr") and 1178 node.func.id in ("getattr", "hasattr") and
1159 node.args[1].s == "__call__" 1179 node.args[1].s == "__call__"
1160 ): 1180 ):
1161 self.violations.append((node, "M503")) 1181 self.violations.append((node, "M511"))
1182 if (
1183 node.func.id == "getattr" and
1184 len(node.args) == 2 and
1185 isinstance(node.args[1], ast.Str)
1186 ):
1187 self.violations.append((node, "M512"))
1188 elif (
1189 node.func.id == "setattr" and
1190 len(node.args) == 3 and
1191 isinstance(node.args[1], ast.Str)
1192 ):
1193 self.violations.append((node, "M513"))
1162 except (AttributeError, IndexError): 1194 except (AttributeError, IndexError):
1163 pass 1195 pass
1164 1196
1165 self.generic_visit(node) 1197 self.generic_visit(node)
1166 1198
1194 if isinstance(self.__nodeStack[-2], ast.ClassDef): 1226 if isinstance(self.__nodeStack[-2], ast.ClassDef):
1195 # By using 'hasattr' below we're ignoring starred arguments, slices 1227 # By using 'hasattr' below we're ignoring starred arguments, slices
1196 # and tuples for simplicity. 1228 # and tuples for simplicity.
1197 assignTargets = {t.id for t in node.targets if hasattr(t, 'id')} 1229 assignTargets = {t.id for t in node.targets if hasattr(t, 'id')}
1198 if '__metaclass__' in assignTargets and sys.version_info >= (3, 0): 1230 if '__metaclass__' in assignTargets and sys.version_info >= (3, 0):
1199 self.violations.append((node, "M514")) 1231 self.violations.append((node, "M524"))
1200 1232
1201 elif len(node.targets) == 1: 1233 elif len(node.targets) == 1:
1202 target = node.targets[0] 1234 target = node.targets[0]
1203 if isinstance(target, ast.Attribute) and \ 1235 if isinstance(target, ast.Attribute) and \
1204 isinstance(target.value, ast.Name): 1236 isinstance(target.value, ast.Name):
1215 @type ast.For 1247 @type ast.For
1216 """ 1248 """
1217 self.__checkForM507(node) 1249 self.__checkForM507(node)
1218 1250
1219 self.generic_visit(node) 1251 self.generic_visit(node)
1252
1253 def visit_Assert(self, node):
1254 """
1255 Public method to handle 'assert' statements.
1256
1257 @param node reference to the node to be processed
1258 @type ast.Assert
1259 """
1260 if isinstance(node.test, ast.NameConstant) and \
1261 node.test.value is False:
1262 self.violations.append((node, "M503"))
1263
1264 self.generic_visit(node)
1265
1266 def visit_JoinedStr(self, node):
1267 """
1268 Public method to handle f-string arguments.
1269
1270 @param node reference to the node to be processed
1271 @type ast.JoinedStr
1272 """
1273 if sys.version_info >= (3, 6):
1274 for value in node.values:
1275 if isinstance(value, ast.FormattedValue):
1276 return
1277
1278 self.violations.append((node, "M508"))
1220 1279
1221 def __checkForM502(self, node): 1280 def __checkForM502(self, node):
1222 """ 1281 """
1223 Private method to check the use of *strip(). 1282 Private method to check the use of *strip().
1224 1283

eric ide

mercurial