Plugins/CheckerPlugins/CodeStyleChecker/MiscellaneousChecker.py

changeset 6889
334257ef9435
parent 6882
65d1bf4b7427
equal deleted inserted replaced
6888:e5f03f779b00 6889:334257ef9435
1432 """ 1432 """
1433 if isinstance(node, ast.Tuple): 1433 if isinstance(node, ast.Tuple):
1434 for elt in node.elts: 1434 for elt in node.elts:
1435 self.__visitAssignTarget(elt) 1435 self.__visitAssignTarget(elt)
1436 return 1436 return
1437 1437
1438 if isinstance(node, ast.Name): 1438 if isinstance(node, ast.Name):
1439 self.assigns[node.id].append(node.lineno) 1439 self.assigns[node.id].append(node.lineno)
1440 return 1440 return
1441 1441
1442 self.generic_visit(node) 1442 self.generic_visit(node)
1443 1443
1444 def __checkFunction(self, node): 1444 def __checkFunction(self, node):
1445 """ 1445 """
1446 Private method to check a function definition node. 1446 Private method to check a function definition node.
1447 1447
1448 @param node reference to the node to check 1448 @param node reference to the node to check
1449 @type ast.AsyncFunctionDef or ast.FunctionDef 1449 @type ast.AsyncFunctionDef or ast.FunctionDef
1450 """ 1450 """
1451 if not self.returns or not node.body: 1451 if not self.returns or not node.body:
1452 return 1452 return
1453 1453
1454 if len(node.body) == 1 and isinstance(node.body[-1], ast.Return): 1454 if len(node.body) == 1 and isinstance(node.body[-1], ast.Return):
1455 # skip functions that consist of `return None` only 1455 # skip functions that consist of `return None` only
1456 return 1456 return
1457 1457
1458 if not self.__resultExists(): 1458 if not self.__resultExists():
1459 self.__checkUnnecessaryReturnNone() 1459 self.__checkUnnecessaryReturnNone()
1460 return 1460 return
1461 1461
1462 self.__checkImplicitReturnValue() 1462 self.__checkImplicitReturnValue()
1463 self.__checkImplicitReturn(node.body[-1]) 1463 self.__checkImplicitReturn(node.body[-1])
1464 1464
1465 for n in self.returns: 1465 for n in self.returns:
1466 if n.value: 1466 if n.value:
1467 self.__checkUnnecessaryAssign(n.value) 1467 self.__checkUnnecessaryAssign(n.value)
1468 1468
1469 def __isNone(self, node): 1469 def __isNone(self, node):
1470 """ 1470 """
1471 Private method to check, if a node value is None. 1471 Private method to check, if a node value is None.
1472 1472
1473 @param node reference to the node to check 1473 @param node reference to the node to check
1474 @type ast.AST 1474 @type ast.AST
1475 @return flag indicating the node contains a None value 1475 @return flag indicating the node contains a None value
1476 """ 1476 """
1477 return isinstance(node, ast.NameConstant) and node.value is None 1477 try:
1478 return isinstance(node, ast.NameConstant) and node.value is None
1479 except AttributeError:
1480 # try Py2
1481 return isinstance(node, ast.Name) and node.id == "None"
1478 1482
1479 def __resultExists(self): 1483 def __resultExists(self):
1480 """ 1484 """
1481 Private method to check the existance of a return result. 1485 Private method to check the existance of a return result.
1482 1486
1487 value = node.value 1491 value = node.value
1488 if value and not self.__isNone(value): 1492 if value and not self.__isNone(value):
1489 return True 1493 return True
1490 1494
1491 return False 1495 return False
1492 1496
1493 def __checkImplicitReturnValue(self): 1497 def __checkImplicitReturnValue(self):
1494 """ 1498 """
1495 Private method to check for implicit return values. 1499 Private method to check for implicit return values.
1496 """ 1500 """
1497 for node in self.returns: 1501 for node in self.returns:
1498 if not node.value: 1502 if not node.value:
1499 self.violations.append((node, "M832")) 1503 self.violations.append((node, "M832"))
1500 1504
1501 def __checkUnnecessaryReturnNone(self): 1505 def __checkUnnecessaryReturnNone(self):
1502 """ 1506 """
1503 Private method to check for an unnecessary 'return None' statement. 1507 Private method to check for an unnecessary 'return None' statement.
1504 """ 1508 """
1505 for node in self.returns: 1509 for node in self.returns:
1506 if self.__isNone(node.value): 1510 if self.__isNone(node.value):
1507 self.violations.append((node, "M831")) 1511 self.violations.append((node, "M831"))
1508 1512
1509 def __checkImplicitReturn(self, node): 1513 def __checkImplicitReturn(self, node):
1510 """ 1514 """
1511 Private method to check for an implicit return statement. 1515 Private method to check for an implicit return statement.
1512 1516
1513 @param node reference to the node to check 1517 @param node reference to the node to check
1515 """ 1519 """
1516 if isinstance(node, ast.If): 1520 if isinstance(node, ast.If):
1517 if not node.body or not node.orelse: 1521 if not node.body or not node.orelse:
1518 self.violations.append((node, "M833")) 1522 self.violations.append((node, "M833"))
1519 return 1523 return
1520 1524
1521 self.__checkImplicitReturn(node.body[-1]) 1525 self.__checkImplicitReturn(node.body[-1])
1522 self.__checkImplicitReturn(node.orelse[-1]) 1526 self.__checkImplicitReturn(node.orelse[-1])
1523 return 1527 return
1524 1528
1525 if isinstance(node, ast.For) and node.orelse: 1529 if isinstance(node, ast.For) and node.orelse:
1526 self.__checkImplicitReturn(node.orelse[-1]) 1530 self.__checkImplicitReturn(node.orelse[-1])
1527 return 1531 return
1528 1532
1529 if isinstance(node, ast.With): 1533 if isinstance(node, ast.With):
1530 self.__checkImplicitReturn(node.body[-1]) 1534 self.__checkImplicitReturn(node.body[-1])
1531 return 1535 return
1532 1536
1533 if not isinstance(node, 1537 try:
1534 (ast.Return, ast.Raise, ast.While, ast.Try)): 1538 okNodes = (ast.Return, ast.Raise, ast.While, ast.Try)
1539 except AttributeError:
1540 # Py2
1541 okNodes = (ast.Return, ast.Raise, ast.While)
1542 if not isinstance(node, okNodes):
1535 self.violations.append((node, "M833")) 1543 self.violations.append((node, "M833"))
1536 1544
1537 def __checkUnnecessaryAssign(self, node): 1545 def __checkUnnecessaryAssign(self, node):
1538 """ 1546 """
1539 Private method to check for an unnecessary assign statement. 1547 Private method to check for an unnecessary assign statement.
1540 1548
1541 @param node reference to the node to check 1549 @param node reference to the node to check
1542 @type ast.AST 1550 @type ast.AST
1543 """ 1551 """
1544 if not isinstance(node, ast.Name): 1552 if not isinstance(node, ast.Name):
1545 return 1553 return
1546 1554
1547 varname = node.id 1555 varname = node.id
1548 returnLineno = node.lineno 1556 returnLineno = node.lineno
1549 1557
1550 if varname not in self.assigns: 1558 if varname not in self.assigns:
1551 return 1559 return
1552 1560
1553 if varname not in self.refs: 1561 if varname not in self.refs:
1554 self.violations.append((node, "M834")) 1562 self.violations.append((node, "M834"))
1555 return 1563 return
1556 1564
1557 if self.__hasRefsBeforeNextAssign(varname, returnLineno): 1565 if self.__hasRefsBeforeNextAssign(varname, returnLineno):
1558 return 1566 return
1559 1567
1560 self.violations.append((node, "M834")) 1568 self.violations.append((node, "M834"))
1561 1569
1562 def __hasRefsBeforeNextAssign(self, varname, returnLineno): 1570 def __hasRefsBeforeNextAssign(self, varname, returnLineno):
1563 """ 1571 """
1564 Private method to check for references before a following assign 1572 Private method to check for references before a following assign
1571 @return flag indicating the existence of references 1579 @return flag indicating the existence of references
1572 @rtype bool 1580 @rtype bool
1573 """ 1581 """
1574 beforeAssign = 0 1582 beforeAssign = 0
1575 afterAssign = None 1583 afterAssign = None
1576 1584
1577 for lineno in sorted(self.assigns[varname]): 1585 for lineno in sorted(self.assigns[varname]):
1578 if lineno > returnLineno: 1586 if lineno > returnLineno:
1579 afterAssign = lineno 1587 afterAssign = lineno
1580 break 1588 break
1581 1589
1582 if lineno <= returnLineno: 1590 if lineno <= returnLineno:
1583 beforeAssign = lineno 1591 beforeAssign = lineno
1584 1592
1585 for lineno in self.refs[varname]: 1593 for lineno in self.refs[varname]:
1586 if lineno == returnLineno: 1594 if lineno == returnLineno:
1587 continue 1595 continue
1588 1596
1589 if afterAssign: 1597 if afterAssign:
1590 if beforeAssign < lineno <= afterAssign: 1598 if beforeAssign < lineno <= afterAssign:
1591 return True 1599 return True
1592 1600
1593 elif beforeAssign < lineno: 1601 elif beforeAssign < lineno:
1594 return True 1602 return True
1595 1603
1596 return False 1604 return False
1597 # 1605 #
1598 # eflag: noqa = M702 1606 # eflag: noqa = M702

eric ide

mercurial