src/eric7/Plugins/CheckerPlugins/CodeStyleChecker/Simplify/SimplifyNodeVisitor.py

branch
eric7
changeset 11150
73d80859079c
parent 11148
15e30f0c76a8
equal deleted inserted replaced
11149:fc45672fae42 11150:73d80859079c
457 @param node reference to the AST node to be checked 457 @param node reference to the AST node to be checked
458 @type ast.BoolOp 458 @type ast.BoolOp
459 """ 459 """
460 if isinstance(node.op, ast.Or): 460 if isinstance(node.op, ast.Or):
461 for variable in self.__getDuplicatedIsinstanceCall(node): 461 for variable in self.__getDuplicatedIsinstanceCall(node):
462 self.__error(node.lineno - 1, node.col_offset, "Y-101", variable) 462 self.__error(node, "Y-101", variable)
463 463
464 def __check102(self, node): 464 def __check102(self, node):
465 """ 465 """
466 Private method to check for nested if statements without else blocks. 466 Private method to check for nested if statements without else blocks.
467 467
494 # pass 494 # pass
495 # elif b: <--- this is treated like a nested block 495 # elif b: <--- this is treated like a nested block
496 # if c: <--- 496 # if c: <---
497 # d 497 # d
498 if isPattern1: 498 if isPattern1:
499 self.__error(node.lineno - 1, node.col_offset, "Y-102") 499 self.__error(node, "Y-102")
500 500
501 def __check103(self, node): 501 def __check103(self, node):
502 """ 502 """
503 Private method to check for calls that wrap a condition to return 503 Private method to check for calls that wrap a condition to return
504 a bool. 504 a bool.
524 node.orelse[0].value.value is True 524 node.orelse[0].value.value is True
525 or node.orelse[0].value.value is False 525 or node.orelse[0].value.value is False
526 ) 526 )
527 ): 527 ):
528 condition = unparse(node.test) 528 condition = unparse(node.test)
529 self.__error(node.lineno - 1, node.col_offset, "Y-103", condition) 529 self.__error(node, "Y-103", condition)
530 530
531 def __check104(self, node): 531 def __check104(self, node):
532 """ 532 """
533 Private method to check for "iterate and yield" patterns. 533 Private method to check for "iterate and yield" patterns.
534 534
555 ): 555 ):
556 parent = getattr(parent, "parent", None) 556 parent = getattr(parent, "parent", None)
557 557
558 if not isinstance(parent, ast.AsyncFunctionDef): 558 if not isinstance(parent, ast.AsyncFunctionDef):
559 iterable = unparse(node.iter) 559 iterable = unparse(node.iter)
560 self.__error(node.lineno - 1, node.col_offset, "Y-104", iterable) 560 self.__error(node, "Y-104", iterable)
561 561
562 def __check105(self, node): 562 def __check105(self, node):
563 """ 563 """
564 Private method to check for "try-except-pass" patterns. 564 Private method to check for "try-except-pass" patterns.
565 565
581 exception = "Exception" 581 exception = "Exception"
582 elif isinstance(node.handlers[0].type, ast.Tuple): 582 elif isinstance(node.handlers[0].type, ast.Tuple):
583 exception = ", ".join([unparse(n) for n in node.handlers[0].type.elts]) 583 exception = ", ".join([unparse(n) for n in node.handlers[0].type.elts])
584 else: 584 else:
585 exception = unparse(node.handlers[0].type) 585 exception = unparse(node.handlers[0].type)
586 self.__error(node.lineno - 1, node.col_offset, "Y-105", exception) 586 self.__error(node, "Y-105", exception)
587 587
588 def __check106(self, node): 588 def __check106(self, node):
589 """ 589 """
590 Private method to check for calls where an exception is raised in else. 590 Private method to check for calls where an exception is raised in else.
591 591
607 and len(node.orelse) >= 1 607 and len(node.orelse) >= 1
608 and isinstance(node.orelse[-1], ast.Raise) 608 and isinstance(node.orelse[-1], ast.Raise)
609 and not isinstance(node.body[-1], ast.Raise) 609 and not isinstance(node.body[-1], ast.Raise)
610 ) 610 )
611 if just_one or many: 611 if just_one or many:
612 self.__error(node.lineno - 1, node.col_offset, "Y-106") 612 self.__error(node, "Y-106")
613 613
614 def __check107(self, node): 614 def __check107(self, node):
615 """ 615 """
616 Private method to check for calls where try/except and finally have 616 Private method to check for calls where try/except and finally have
617 'return'. 617 'return'.
646 finallyHasReturn = True 646 finallyHasReturn = True
647 finallyReturn = stmt 647 finallyReturn = stmt
648 break 648 break
649 649
650 if (tryHasReturn or exceptHasReturn) and finallyHasReturn: 650 if (tryHasReturn or exceptHasReturn) and finallyHasReturn:
651 self.__error(finallyReturn.lineno - 1, finallyReturn.col_offset, "Y-107") 651 self.__error(finallyReturn, "Y-107")
652 652
653 def __check108(self, node): 653 def __check108(self, node):
654 """ 654 """
655 Private method to check for if-elses which could be a ternary 655 Private method to check for if-elses which could be a ternary
656 operator assignment. 656 operator assignment.
697 697
698 body = unparse(node.body[0].value) 698 body = unparse(node.body[0].value)
699 cond = unparse(node.test) 699 cond = unparse(node.test)
700 orelse = unparse(node.orelse[0].value) 700 orelse = unparse(node.orelse[0].value)
701 701
702 self.__error( 702 self.__error(node, "Y-108", assign, body, cond, orelse)
703 node.lineno - 1, node.col_offset, "Y-108", assign, body, cond, orelse
704 )
705 703
706 def __check109(self, node): 704 def __check109(self, node):
707 """ 705 """
708 Private method to check for multiple equalities with the same value 706 Private method to check for multiple equalities with the same value
709 are combined via "or". 707 are combined via "or".
736 for value, values in id2count.items(): 734 for value, values in id2count.items():
737 if len(values) == 1: 735 if len(values) == 1:
738 continue 736 continue
739 737
740 self.__error( 738 self.__error(
741 node.lineno - 1, 739 node, "Y-109", value, unparse(ast.Tuple(elts=values)), unparse(node)
742 node.col_offset,
743 "Y-109",
744 value,
745 unparse(ast.Tuple(elts=values)),
746 unparse(node),
747 ) 740 )
748 741
749 def __check110_111(self, node): 742 def __check110_111(self, node):
750 """ 743 """
751 Private method to check if any / all could be used. 744 Private method to check if any / all could be used.
773 ): 766 ):
774 check = unparse(node.body[0].test) 767 check = unparse(node.body[0].test)
775 target = unparse(node.target) 768 target = unparse(node.target)
776 iterable = unparse(node.iter) 769 iterable = unparse(node.iter)
777 if node.body[0].body[0].value.value is True: 770 if node.body[0].body[0].value.value is True:
778 self.__error( 771 self.__error(node, "Y-110", check, target, iterable)
779 node.lineno - 1, node.col_offset, "Y-110", check, target, iterable
780 )
781 elif node.body[0].body[0].value.value is False: 772 elif node.body[0].body[0].value.value is False:
782 isCompoundExpression = " and " in check or " or " in check 773 isCompoundExpression = " and " in check or " or " in check
783 774
784 if isCompoundExpression: 775 if isCompoundExpression:
785 check = f"not ({check})" 776 check = f"not ({check})"
786 else: 777 else:
787 if check.startswith("not "): 778 if check.startswith("not "):
788 check = check[len("not ") :] 779 check = check[len("not ") :]
789 else: 780 else:
790 check = f"not {check}" 781 check = f"not {check}"
791 self.__error( 782 self.__error(node, "Y-111", check, target, iterable)
792 node.lineno - 1, node.col_offset, "Y-111", check, target, iterable
793 )
794 783
795 def __check112(self, node): 784 def __check112(self, node):
796 """ 785 """
797 Private method to check for non-capitalized calls to environment 786 Private method to check for non-capitalized calls to environment
798 variables. 787 variables.
860 defaultValue = unparse(node.value.args[1]) 849 defaultValue = unparse(node.value.args[1])
861 expected = f"os.environ.get('{envName.upper()}', '{defaultValue}')" 850 expected = f"os.environ.get('{envName.upper()}', '{defaultValue}')"
862 else: 851 else:
863 return 852 return
864 853
865 self.__error(node.lineno - 1, node.col_offset, "Y-112", expected, original) 854 self.__error(node, "Y-112", expected, original)
866 855
867 def __check113(self, node): 856 def __check113(self, node):
868 """ 857 """
869 Private method to check for loops in which "enumerate" should be 858 Private method to check for loops in which "enumerate" should be
870 used. 859 used.
909 while sibling is not None: 898 while sibling is not None:
910 sibling = sibling.previous_sibling 899 sibling = sibling.previous_sibling
911 900
912 for match in matches: 901 for match in matches:
913 variable = unparse(match) 902 variable = unparse(match)
914 self.__error(match.lineno - 1, match.col_offset, "Y-113", variable) 903 self.__error(match, "Y-113", variable)
915 904
916 def __check114(self, node): 905 def __check114(self, node):
917 """ 906 """
918 Private method to check for alternative if clauses with identical 907 Private method to check for alternative if clauses with identical
919 bodies. 908 bodies.
932 ifbody1 = ifBodyPairs[i] 921 ifbody1 = ifBodyPairs[i]
933 ifbody2 = ifBodyPairs[i + 1] 922 ifbody2 = ifBodyPairs[i + 1]
934 if self.__isSameBody(ifbody1[1], ifbody2[1]): 923 if self.__isSameBody(ifbody1[1], ifbody2[1]):
935 errorPairs.append((ifbody1, ifbody2)) 924 errorPairs.append((ifbody1, ifbody2))
936 for ifbody1, ifbody2 in errorPairs: 925 for ifbody1, ifbody2 in errorPairs:
937 self.__error( 926 self.__error(ifbody1[0], "Y-114", unparse(ifbody1[0]), unparse(ifbody2[0]))
938 ifbody1[0].lineno - 1,
939 ifbody1[0].col_offset,
940 "Y-114",
941 unparse(ifbody1[0]),
942 unparse(ifbody2[0]),
943 )
944 927
945 def __check115(self, node): 928 def __check115(self, node):
946 """ 929 """
947 Private method to to check for places where open() is called without 930 Private method to to check for places where open() is called without
948 a context handler. 931 a context handler.
956 if ( 939 if (
957 isinstance(node.func, ast.Name) 940 isinstance(node.func, ast.Name)
958 and node.func.id == "open" 941 and node.func.id == "open"
959 and not isinstance(node.parent, ast.withitem) 942 and not isinstance(node.parent, ast.withitem)
960 ): 943 ):
961 self.__error(node.lineno - 1, node.col_offset, "Y-115") 944 self.__error(node, "Y-115")
962 945
963 def __check116(self, node): 946 def __check116(self, node):
964 """ 947 """
965 Private method to check for places with 3 or more consecutive 948 Private method to check for places with 3 or more consecutive
966 if-statements with direct returns. 949 if-statements with direct returns.
1052 if elseValue: 1035 if elseValue:
1053 ret = f"{keyValuePairs}.get({variable.id}, {elseValue})" 1036 ret = f"{keyValuePairs}.get({variable.id}, {elseValue})"
1054 else: 1037 else:
1055 ret = f"{keyValuePairs}.get({variable.id})" 1038 ret = f"{keyValuePairs}.get({variable.id})"
1056 1039
1057 self.__error(node.lineno - 1, node.col_offset, "Y-116", ret) 1040 self.__error(node, "Y-116", ret)
1058 1041
1059 def __check117(self, node): 1042 def __check117(self, node):
1060 """ 1043 """
1061 Private method to check for multiple with-statements with same scope. 1044 Private method to check for multiple with-statements with same scope.
1062 1045
1069 if len(node.body) == 1 and isinstance(node.body[0], ast.With): 1052 if len(node.body) == 1 and isinstance(node.body[0], ast.With):
1070 withItems = [] 1053 withItems = []
1071 for withitem in node.items + node.body[0].items: 1054 for withitem in node.items + node.body[0].items:
1072 withItems.append(f"{unparse(withitem)}") 1055 withItems.append(f"{unparse(withitem)}")
1073 mergedWith = f"with {', '.join(withItems)}:" 1056 mergedWith = f"with {', '.join(withItems)}:"
1074 self.__error(node.lineno - 1, node.col_offset, "Y-117", mergedWith) 1057 self.__error(node, "Y-117", mergedWith)
1075 1058
1076 def __check118(self, node): 1059 def __check118(self, node):
1077 """ 1060 """
1078 Private method to check for usages of "key in dict.keys()". 1061 Private method to check for usages of "key in dict.keys()".
1079 1062
1113 if isinstance(node, ast.Compare): 1096 if isinstance(node, ast.Compare):
1114 keyStr = unparse(node.left) 1097 keyStr = unparse(node.left)
1115 else: 1098 else:
1116 keyStr = unparse(node.target) 1099 keyStr = unparse(node.target)
1117 dictStr = unparse(attrNode.value) 1100 dictStr = unparse(attrNode.value)
1118 self.__error(node.lineno - 1, node.col_offset, "Y-118", keyStr, dictStr) 1101 self.__error(node, "Y-118", keyStr, dictStr)
1119 1102
1120 def __check119(self, node): 1103 def __check119(self, node):
1121 """ 1104 """
1122 Private method to check for classes that should be "dataclasses". 1105 Private method to check for classes that should be "dataclasses".
1123 1106
1143 1126
1144 if ( 1127 if (
1145 hasOnlyConstructorMethod 1128 hasOnlyConstructorMethod
1146 and sum(1 for el in node.body if isinstance(el, ast.FunctionDef)) > 0 1129 and sum(1 for el in node.body if isinstance(el, ast.FunctionDef)) > 0
1147 ): 1130 ):
1148 self.__error(node.lineno - 1, node.col_offset, "Y-119", node.name) 1131 self.__error(node, "Y-119", node.name)
1149 1132
1150 def __check120_121(self, node): 1133 def __check120_121(self, node):
1151 """ 1134 """
1152 Private method to check for classes that inherit from object. 1135 Private method to check for classes that inherit from object.
1153 1136
1159 if ( 1142 if (
1160 len(node.bases) == 1 1143 len(node.bases) == 1
1161 and isinstance(node.bases[0], ast.Name) 1144 and isinstance(node.bases[0], ast.Name)
1162 and node.bases[0].id == "object" 1145 and node.bases[0].id == "object"
1163 ): 1146 ):
1164 self.__error(node.lineno - 1, node.col_offset, "Y-120", node.name) 1147 self.__error(node, "Y-120", node.name)
1165 1148
1166 elif ( 1149 elif (
1167 len(node.bases) > 1 1150 len(node.bases) > 1
1168 and isinstance(node.bases[-1], ast.Name) 1151 and isinstance(node.bases[-1], ast.Name)
1169 and node.bases[-1].id == "object" 1152 and node.bases[-1].id == "object"
1170 ): 1153 ):
1171 self.__error( 1154 self.__error(
1172 node.lineno - 1, 1155 node, "Y-121", node.name, ", ".join(b.id for b in node.bases[:-1])
1173 node.col_offset,
1174 "Y-121",
1175 node.name,
1176 ", ".join(b.id for b in node.bases[:-1]),
1177 ) 1156 )
1178 1157
1179 def __check122(self, node): 1158 def __check122(self, node):
1180 """ 1159 """
1181 Private method to check for all if-blocks which only check if a key 1160 Private method to check for all if-blocks which only check if a key
1202 and isinstance(node.test.comparators[0], ast.Name) 1181 and isinstance(node.test.comparators[0], ast.Name)
1203 and node.body[0].value.value.id == node.test.comparators[0].id 1182 and node.body[0].value.value.id == node.test.comparators[0].id
1204 ): 1183 ):
1205 key = unparse(node.test.left) 1184 key = unparse(node.test.left)
1206 dictname = unparse(node.test.comparators[0]) 1185 dictname = unparse(node.test.comparators[0])
1207 self.__error(node.lineno - 1, node.col_offset, "Y-122", dictname, key) 1186 self.__error(node, "Y-122", dictname, key)
1208 1187
1209 def __check123(self, node): 1188 def __check123(self, node):
1210 """ 1189 """
1211 Private method to check for complicated dictionary access with default value. 1190 Private method to check for complicated dictionary access with default value.
1212 1191
1264 dictStr = unparse(dictName) 1243 dictStr = unparse(dictName)
1265 defaultStr = unparse(defaultValue) 1244 defaultStr = unparse(defaultValue)
1266 valueStr = unparse(valueNode) 1245 valueStr = unparse(valueNode)
1267 else: 1246 else:
1268 return 1247 return
1269 self.__error( 1248 self.__error(node, "Y-123", valueStr, dictStr, keyStr, defaultStr)
1270 node.lineno - 1,
1271 node.col_offset,
1272 "Y-123",
1273 valueStr,
1274 dictStr,
1275 keyStr,
1276 defaultStr,
1277 )
1278 1249
1279 def __check181(self, node): 1250 def __check181(self, node):
1280 """ 1251 """
1281 Private method to check for assignments that could be converted into 1252 Private method to check for assignments that could be converted into
1282 an augmented assignment. 1253 an augmented assignment.
1292 and isinstance(node.value.left, ast.Name) 1263 and isinstance(node.value.left, ast.Name)
1293 and node.value.left.id == node.targets[0].id 1264 and node.value.left.id == node.targets[0].id
1294 and not isinstance(node.value.right, ast.Tuple) 1265 and not isinstance(node.value.right, ast.Tuple)
1295 ): 1266 ):
1296 newNode = ast.AugAssign(node.targets[0], node.value.op, node.value.right) 1267 newNode = ast.AugAssign(node.targets[0], node.value.op, node.value.right)
1297 self.__error( 1268 self.__error(node, "Y-181", unparse(newNode), unparse(node))
1298 node.lineno - 1,
1299 node.col_offset,
1300 "Y-181",
1301 unparse(newNode),
1302 unparse(node),
1303 )
1304 1269
1305 def __check182(self, node): 1270 def __check182(self, node):
1306 """ 1271 """
1307 Private method to check for calls of type 'super()' that could 1272 Private method to check for calls of type 'super()' that could
1308 be shortened to 'super()'. 1273 be shortened to 'super()'.
1318 and len(node.args) == 2 1283 and len(node.args) == 2
1319 and all(isinstance(arg, ast.Name) for arg in node.args) 1284 and all(isinstance(arg, ast.Name) for arg in node.args)
1320 and node.args[0].id == self.__classDefinitionStack[-1] 1285 and node.args[0].id == self.__classDefinitionStack[-1]
1321 and node.args[1].id == "self" 1286 and node.args[1].id == "self"
1322 ): 1287 ):
1323 self.__error(node.lineno - 1, node.col_offset, "Y-182", unparse(node)) 1288 self.__error(node, "Y-182", unparse(node))
1324 1289
1325 def __check201(self, node): 1290 def __check201(self, node):
1326 """ 1291 """
1327 Private method to check for calls where an unary 'not' is used for 1292 Private method to check for calls where an unary 'not' is used for
1328 an unequality. 1293 an unequality.
1342 and self.__isExceptionCheck(node.parent) 1307 and self.__isExceptionCheck(node.parent)
1343 ): 1308 ):
1344 comparison = node.operand 1309 comparison = node.operand
1345 left = unparse(comparison.left) 1310 left = unparse(comparison.left)
1346 right = unparse(comparison.comparators[0]) 1311 right = unparse(comparison.comparators[0])
1347 self.__error(node.lineno - 1, node.col_offset, "Y-201", left, right) 1312 self.__error(node, "Y-201", left, right)
1348 1313
1349 def __check202(self, node): 1314 def __check202(self, node):
1350 """ 1315 """
1351 Private method to check for calls where an unary 'not' is used for 1316 Private method to check for calls where an unary 'not' is used for
1352 an equality. 1317 an equality.
1366 and self.__isExceptionCheck(node.parent) 1331 and self.__isExceptionCheck(node.parent)
1367 ): 1332 ):
1368 comparison = node.operand 1333 comparison = node.operand
1369 left = unparse(comparison.left) 1334 left = unparse(comparison.left)
1370 right = unparse(comparison.comparators[0]) 1335 right = unparse(comparison.comparators[0])
1371 self.__error(node.lineno - 1, node.col_offset, "Y-202", left, right) 1336 self.__error(node, "Y-202", left, right)
1372 1337
1373 def __check203(self, node): 1338 def __check203(self, node):
1374 """ 1339 """
1375 Private method to check for calls where an unary 'not' is used for 1340 Private method to check for calls where an unary 'not' is used for
1376 an in-check. 1341 an in-check.
1390 and self.__isExceptionCheck(node.parent) 1355 and self.__isExceptionCheck(node.parent)
1391 ): 1356 ):
1392 comparison = node.operand 1357 comparison = node.operand
1393 left = unparse(comparison.left) 1358 left = unparse(comparison.left)
1394 right = unparse(comparison.comparators[0]) 1359 right = unparse(comparison.comparators[0])
1395 self.__error(node.lineno - 1, node.col_offset, "Y-203", left, right) 1360 self.__error(node, "Y-203", left, right)
1396 1361
1397 def __check204(self, node): 1362 def __check204(self, node):
1398 """ 1363 """
1399 Private method to check for calls of the type "not (a < b)". 1364 Private method to check for calls of the type "not (a < b)".
1400 1365
1413 and self.__isExceptionCheck(node.parent) 1378 and self.__isExceptionCheck(node.parent)
1414 ): 1379 ):
1415 comparison = node.operand 1380 comparison = node.operand
1416 left = unparse(comparison.left) 1381 left = unparse(comparison.left)
1417 right = unparse(comparison.comparators[0]) 1382 right = unparse(comparison.comparators[0])
1418 self.__error(node.lineno - 1, node.col_offset, "Y-204", left, right) 1383 self.__error(node, "Y-204", left, right)
1419 1384
1420 def __check205(self, node): 1385 def __check205(self, node):
1421 """ 1386 """
1422 Private method to check for calls of the type "not (a <= b)". 1387 Private method to check for calls of the type "not (a <= b)".
1423 1388
1436 and self.__isExceptionCheck(node.parent) 1401 and self.__isExceptionCheck(node.parent)
1437 ): 1402 ):
1438 comparison = node.operand 1403 comparison = node.operand
1439 left = unparse(comparison.left) 1404 left = unparse(comparison.left)
1440 right = unparse(comparison.comparators[0]) 1405 right = unparse(comparison.comparators[0])
1441 self.__error(node.lineno - 1, node.col_offset, "Y-205", left, right) 1406 self.__error(node, "Y-205", left, right)
1442 1407
1443 def __check206(self, node): 1408 def __check206(self, node):
1444 """ 1409 """
1445 Private method to check for calls of the type "not (a > b)". 1410 Private method to check for calls of the type "not (a > b)".
1446 1411
1459 and self.__isExceptionCheck(node.parent) 1424 and self.__isExceptionCheck(node.parent)
1460 ): 1425 ):
1461 comparison = node.operand 1426 comparison = node.operand
1462 left = unparse(comparison.left) 1427 left = unparse(comparison.left)
1463 right = unparse(comparison.comparators[0]) 1428 right = unparse(comparison.comparators[0])
1464 self.__error(node.lineno - 1, node.col_offset, "Y-206", left, right) 1429 self.__error(node, "Y-206", left, right)
1465 1430
1466 def __check207(self, node): 1431 def __check207(self, node):
1467 """ 1432 """
1468 Private method to check for calls of the type "not (a >= b)". 1433 Private method to check for calls of the type "not (a >= b)".
1469 1434
1482 and self.__isExceptionCheck(node.parent) 1447 and self.__isExceptionCheck(node.parent)
1483 ): 1448 ):
1484 comparison = node.operand 1449 comparison = node.operand
1485 left = unparse(comparison.left) 1450 left = unparse(comparison.left)
1486 right = unparse(comparison.comparators[0]) 1451 right = unparse(comparison.comparators[0])
1487 self.__error(node.lineno - 1, node.col_offset, "Y-207", left, right) 1452 self.__error(node, "Y-207", left, right)
1488 1453
1489 def __check208(self, node): 1454 def __check208(self, node):
1490 """ 1455 """
1491 Private method to check for calls of the type "not (not a)". 1456 Private method to check for calls of the type "not (not a)".
1492 1457
1498 isinstance(node.op, ast.Not) 1463 isinstance(node.op, ast.Not)
1499 and isinstance(node.operand, ast.UnaryOp) 1464 and isinstance(node.operand, ast.UnaryOp)
1500 and isinstance(node.operand.op, ast.Not) 1465 and isinstance(node.operand.op, ast.Not)
1501 ): 1466 ):
1502 var = unparse(node.operand.operand) 1467 var = unparse(node.operand.operand)
1503 self.__error(node.lineno - 1, node.col_offset, "Y-208", var) 1468 self.__error(node, "Y-208", var)
1504 1469
1505 def __check211(self, node): 1470 def __check211(self, node):
1506 """ 1471 """
1507 Private method to check for calls of the type "True if a else False". 1472 Private method to check for calls of the type "True if a else False".
1508 1473
1519 cond = unparse(node.test) 1484 cond = unparse(node.test)
1520 if isinstance(node.test, ast.Name): 1485 if isinstance(node.test, ast.Name):
1521 newCond = "bool({0})".format(cond) 1486 newCond = "bool({0})".format(cond)
1522 else: 1487 else:
1523 newCond = cond 1488 newCond = cond
1524 self.__error(node.lineno - 1, node.col_offset, "Y-211", cond, newCond) 1489 self.__error(node, "Y-211", cond, newCond)
1525 1490
1526 def __check212(self, node): 1491 def __check212(self, node):
1527 """ 1492 """
1528 Private method to check for calls of the type "False if a else True". 1493 Private method to check for calls of the type "False if a else True".
1529 1494
1543 else: 1508 else:
1544 if len(node.test.ops) == 1: 1509 if len(node.test.ops) == 1:
1545 newCond = unparse(self.__negateTest(node.test)) 1510 newCond = unparse(self.__negateTest(node.test))
1546 else: 1511 else:
1547 newCond = "not ({0})".format(cond) 1512 newCond = "not ({0})".format(cond)
1548 self.__error(node.lineno - 1, node.col_offset, "Y-212", cond, newCond) 1513 self.__error(node, "Y-212", cond, newCond)
1549 1514
1550 def __check213(self, node): 1515 def __check213(self, node):
1551 """ 1516 """
1552 Private method to check for calls of the type "b if not a else a". 1517 Private method to check for calls of the type "b if not a else a".
1553 1518
1560 and isinstance(node.test.op, ast.Not) 1525 and isinstance(node.test.op, ast.Not)
1561 and self.__isSameExpression(node.test.operand, node.orelse) 1526 and self.__isSameExpression(node.test.operand, node.orelse)
1562 ): 1527 ):
1563 a = unparse(node.test.operand) 1528 a = unparse(node.test.operand)
1564 b = unparse(node.body) 1529 b = unparse(node.body)
1565 self.__error(node.lineno - 1, node.col_offset, "Y-213", a, b) 1530 self.__error(node, "Y-213", a, b)
1566 1531
1567 def __check221(self, node): 1532 def __check221(self, node):
1568 """ 1533 """
1569 Private method to check for calls of the type "a and not a". 1534 Private method to check for calls of the type "a and not a".
1570 1535
1584 nonNegatedExpressions.append(exp) 1549 nonNegatedExpressions.append(exp)
1585 for negatedExpression in negatedExpressions: 1550 for negatedExpression in negatedExpressions:
1586 for nonNegatedExpression in nonNegatedExpressions: 1551 for nonNegatedExpression in nonNegatedExpressions:
1587 if self.__isSameExpression(negatedExpression, nonNegatedExpression): 1552 if self.__isSameExpression(negatedExpression, nonNegatedExpression):
1588 negExp = unparse(negatedExpression) 1553 negExp = unparse(negatedExpression)
1589 self.__error(node.lineno - 1, node.col_offset, "Y-221", negExp) 1554 self.__error(node, "Y-221", negExp)
1590 1555
1591 def __check222(self, node): 1556 def __check222(self, node):
1592 """ 1557 """
1593 Private method to check for calls of the type "a or not a". 1558 Private method to check for calls of the type "a or not a".
1594 1559
1608 nonNegatedExpressions.append(exp) 1573 nonNegatedExpressions.append(exp)
1609 for negatedExpression in negatedExpressions: 1574 for negatedExpression in negatedExpressions:
1610 for nonNegatedExpression in nonNegatedExpressions: 1575 for nonNegatedExpression in nonNegatedExpressions:
1611 if self.__isSameExpression(negatedExpression, nonNegatedExpression): 1576 if self.__isSameExpression(negatedExpression, nonNegatedExpression):
1612 negExp = unparse(negatedExpression) 1577 negExp = unparse(negatedExpression)
1613 self.__error(node.lineno - 1, node.col_offset, "Y-222", negExp) 1578 self.__error(node, "Y-222", negExp)
1614 1579
1615 def __check223(self, node): 1580 def __check223(self, node):
1616 """ 1581 """
1617 Private method to check for calls of the type "... or True". 1582 Private method to check for calls of the type "... or True".
1618 1583
1621 """ 1586 """
1622 # a or True 1587 # a or True
1623 if isinstance(node.op, ast.Or): 1588 if isinstance(node.op, ast.Or):
1624 for exp in node.values: 1589 for exp in node.values:
1625 if isinstance(exp, ast.Constant) and exp.value is True: 1590 if isinstance(exp, ast.Constant) and exp.value is True:
1626 self.__error(node.lineno - 1, node.col_offset, "Y-223") 1591 self.__error(node, "Y-223")
1627 1592
1628 def __check224(self, node): 1593 def __check224(self, node):
1629 """ 1594 """
1630 Private method to check for calls of the type "... and False". 1595 Private method to check for calls of the type "... and False".
1631 1596
1634 """ 1599 """
1635 # a and False 1600 # a and False
1636 if isinstance(node.op, ast.And): 1601 if isinstance(node.op, ast.And):
1637 for exp in node.values: 1602 for exp in node.values:
1638 if isinstance(exp, ast.Constant) and exp.value is False: 1603 if isinstance(exp, ast.Constant) and exp.value is False:
1639 self.__error(node.lineno - 1, node.col_offset, "Y-224") 1604 self.__error(node, "Y-224")
1640 1605
1641 def __check301(self, node): 1606 def __check301(self, node):
1642 """ 1607 """
1643 Private method to check for Yoda conditions. 1608 Private method to check for Yoda conditions.
1644 1609
1656 node.left.value, str 1621 node.left.value, str
1657 ) 1622 )
1658 if isStr: 1623 if isStr:
1659 left = f"'{left}'" 1624 left = f"'{left}'"
1660 right = unparse(node.comparators[0]) 1625 right = unparse(node.comparators[0])
1661 self.__error(node.lineno - 1, node.col_offset, "Y-301", left, right) 1626 self.__error(node, "Y-301", left, right)
1662 1627
1663 def __check401(self, node): 1628 def __check401(self, node):
1664 """ 1629 """
1665 Private method to check for bare boolean function arguments. 1630 Private method to check for bare boolean function arguments.
1666 1631
1675 ) 1640 )
1676 1641
1677 isException = isinstance(node.func, ast.Attribute) and node.func.attr in ["get"] 1642 isException = isinstance(node.func, ast.Attribute) and node.func.attr in ["get"]
1678 1643
1679 if hasBareBool and not isException: 1644 if hasBareBool and not isException:
1680 self.__error(node.lineno - 1, node.col_offset, "Y-401") 1645 self.__error(node, "Y-401")
1681 1646
1682 def __check402(self, node): 1647 def __check402(self, node):
1683 """ 1648 """
1684 Private method to check for bare numeric function arguments. 1649 Private method to check for bare numeric function arguments.
1685 1650
1696 isException = isException or ( 1661 isException = isException or (
1697 isinstance(node.func, ast.Attribute) and node.func.attr in ("get", "insert") 1662 isinstance(node.func, ast.Attribute) and node.func.attr in ("get", "insert")
1698 ) 1663 )
1699 1664
1700 if hasBareNumeric and not isException: 1665 if hasBareNumeric and not isException:
1701 self.__error(node.lineno - 1, node.col_offset, "Y-402") 1666 self.__error(node, "Y-402")
1702 1667
1703 def __check411(self, node): 1668 def __check411(self, node):
1704 """ 1669 """
1705 Private method to check for nested f-strings. 1670 Private method to check for nested f-strings.
1706 1671
1713 if fieldName == "values": 1678 if fieldName == "values":
1714 for innerNode in value: 1679 for innerNode in value:
1715 self.__check411(innerNode) 1680 self.__check411(innerNode)
1716 1681
1717 if fieldName == "value" and isinstance(value, ast.JoinedStr): 1682 if fieldName == "value" and isinstance(value, ast.JoinedStr):
1718 self.__error(node.lineno - 1, node.col_offset, "Y-411") 1683 self.__error(node, "Y-411")
1719 1684
1720 def __check901(self, node): 1685 def __check901(self, node):
1721 """ 1686 """
1722 Private method to check for unnecessary bool conversion. 1687 Private method to check for unnecessary bool conversion.
1723 1688
1730 and len(node.args) == 1 1695 and len(node.args) == 1
1731 and isinstance(node.args[0], ast.Compare) 1696 and isinstance(node.args[0], ast.Compare)
1732 ): 1697 ):
1733 actual = unparse(node) 1698 actual = unparse(node)
1734 expected = unparse(node.args[0]) 1699 expected = unparse(node.args[0])
1735 self.__error(node.lineno - 1, node.col_offset, "Y-901", expected, actual) 1700 self.__error(node, "Y-901", expected, actual)
1736 1701
1737 def __check904(self, node): 1702 def __check904(self, node):
1738 """ 1703 """
1739 Private method to check for dictionary initialization. 1704 Private method to check for dictionary initialization.
1740 1705
1753 and isinstance(node.targets[0], ast.Name) 1718 and isinstance(node.targets[0], ast.Name)
1754 and n2.targets[0].value.id == node.targets[0].id 1719 and n2.targets[0].value.id == node.targets[0].id
1755 ): 1720 ):
1756 dictName = unparse(node.targets[0]) 1721 dictName = unparse(node.targets[0])
1757 if not self.__expressionUsesVariable(n2.value, dictName): 1722 if not self.__expressionUsesVariable(n2.value, dictName):
1758 self.__error(node.lineno - 1, node.col_offset, "Y-904", dictName) 1723 self.__error(node, "Y-904", dictName)
1759 1724
1760 def __check905(self, node): 1725 def __check905(self, node):
1761 """ 1726 """
1762 Private method to check for list initialization by splitting a string. 1727 Private method to check for list initialization by splitting a string.
1763 1728
1771 ): 1736 ):
1772 value = node.func.value.value 1737 value = node.func.value.value
1773 1738
1774 expected = json.dumps(value.split()) 1739 expected = json.dumps(value.split())
1775 actual = unparse(node.func.value) + ".split()" 1740 actual = unparse(node.func.value) + ".split()"
1776 self.__error(node.lineno - 1, node.col_offset, "Y-905", expected, actual) 1741 self.__error(node, "Y-905", expected, actual)
1777 1742
1778 def __check906(self, node): 1743 def __check906(self, node):
1779 """ 1744 """
1780 Private method to check for unnecessary nesting of os.path.join(). 1745 Private method to check for unnecessary nesting of os.path.join().
1781 1746
1825 ): 1790 ):
1826 names = getOsPathJoinArgs(node) 1791 names = getOsPathJoinArgs(node)
1827 1792
1828 actual = unparse(node) 1793 actual = unparse(node)
1829 expected = "os.path.join({0})".format(", ".join(names)) 1794 expected = "os.path.join({0})".format(", ".join(names))
1830 self.__error(node.lineno - 1, node.col_offset, "Y-906", expected, actual) 1795 self.__error(node, "Y-906", expected, actual)
1831 1796
1832 def __check907(self, node): 1797 def __check907(self, node):
1833 """ 1798 """
1834 Private method to check for Union type annotation with None. 1799 Private method to check for Union type annotation with None.
1835 1800
1856 else: 1821 else:
1857 others.append(elt) 1822 others.append(elt)
1858 1823
1859 if len(others) == 1 and hasNone: 1824 if len(others) == 1 and hasNone:
1860 type_ = unparse(others[0]) 1825 type_ = unparse(others[0])
1861 self.__error( 1826 self.__error(node, "Y-907", type_, unparse(node))
1862 node.lineno - 1, node.col_offset, "Y-907", type_, unparse(node)
1863 )
1864 1827
1865 def __check909(self, node): 1828 def __check909(self, node):
1866 """ 1829 """
1867 Private method to check for reflexive assignments. 1830 Private method to check for reflexive assignments.
1868 1831
1875 for target in node.targets: 1838 for target in node.targets:
1876 names.append(unparse(target)) 1839 names.append(unparse(target))
1877 1840
1878 if len(names) != len(set(names)) and not isinstance(node.parent, ast.ClassDef): 1841 if len(names) != len(set(names)) and not isinstance(node.parent, ast.ClassDef):
1879 srccode = unparse(node) 1842 srccode = unparse(node)
1880 self.__error(node.lineno - 1, node.col_offset, "Y-909", srccode) 1843 self.__error(node, "Y-909", srccode)
1881 1844
1882 def __check910(self, node): 1845 def __check910(self, node):
1883 """ 1846 """
1884 Private method to check for uses of 'dict.get(key, None)'. 1847 Private method to check for uses of 'dict.get(key, None)'.
1885 1848
1903 1866
1904 actual = unparse(node) 1867 actual = unparse(node)
1905 func = unparse(node.func) 1868 func = unparse(node.func)
1906 key = unparse(node.args[0]) 1869 key = unparse(node.args[0])
1907 expected = f"{func}({key})" 1870 expected = f"{func}({key})"
1908 self.__error(node.lineno - 1, node.col_offset, "Y-910", expected, actual) 1871 self.__error(node, "Y-910", expected, actual)
1909 1872
1910 def __check911(self, node): 1873 def __check911(self, node):
1911 """ 1874 """
1912 Private method to check for the expression "zip(_.keys(), _.values())". 1875 Private method to check for the expression "zip(_.keys(), _.values())".
1913 1876
1929 and isinstance(secondArg.func, ast.Attribute) 1892 and isinstance(secondArg.func, ast.Attribute)
1930 and isinstance(secondArg.func.value, ast.Name) 1893 and isinstance(secondArg.func.value, ast.Name)
1931 and secondArg.func.attr == "values" 1894 and secondArg.func.attr == "values"
1932 and firstArg.func.value.id == secondArg.func.value.id 1895 and firstArg.func.value.id == secondArg.func.value.id
1933 ): 1896 ):
1934 self.__error( 1897 self.__error(node, "Y-911", firstArg.func.value.id)
1935 node.lineno - 1, node.col_offset, "Y-911", firstArg.func.value.id
1936 )
1937 1898
1938 1899
1939 # 1900 #
1940 # eflag: noqa = M-891 1901 # eflag: noqa = M-891

eric ide

mercurial