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

branch
eric7
changeset 9278
36448ca469c2
parent 9277
471c5a263d53
child 9595
2bd590c40309
equal deleted inserted replaced
9277:471c5a263d53 9278:36448ca469c2
240 self.__check206(node) 240 self.__check206(node)
241 self.__check207(node) 241 self.__check207(node)
242 self.__check208(node) 242 self.__check208(node)
243 243
244 self.generic_visit(node) 244 self.generic_visit(node)
245 245
246 def visit_Subscript(self, node): 246 def visit_Subscript(self, node):
247 """ 247 """
248 Public method to process a Subscript node. 248 Public method to process a Subscript node.
249 249
250 @param node reference to the Subscript node 250 @param node reference to the Subscript node
284 return [name for name, count in counter.items() if count > 1] 284 return [name for name, count in counter.items() if count > 1]
285 285
286 def __isConstantIncrease(self, expr): 286 def __isConstantIncrease(self, expr):
287 """ 287 """
288 Private method to check an expression for being a constant increase. 288 Private method to check an expression for being a constant increase.
289 289
290 @param expr reference to the node to be checked 290 @param expr reference to the node to be checked
291 @type ast.AugAssign 291 @type ast.AugAssign
292 @return flag indicating a constant increase 292 @return flag indicating a constant increase
293 @rtype bool 293 @rtype bool
294 """ 294 """
295 return isinstance(expr.op, ast.Add) and ( 295 return isinstance(expr.op, ast.Add) and (
296 ( 296 (isinstance(expr.value, ast.Constant) and expr.value.value == 1)
297 isinstance(expr.value, ast.Constant)
298 and expr.value.value == 1
299 )
300 or (isinstance(expr.value, ast.Num) and expr.value.n == 1) 297 or (isinstance(expr.value, ast.Num) and expr.value.n == 1)
301 ) 298 )
302 299
303 def __getIfBodyPairs(self, node): 300 def __getIfBodyPairs(self, node):
304 """ 301 """
432 return newNode 429 return newNode
433 430
434 def __expressionUsesVariable(self, expr, var): 431 def __expressionUsesVariable(self, expr, var):
435 """ 432 """
436 Private method to check, if a variable is used by an expression. 433 Private method to check, if a variable is used by an expression.
437 434
438 @param expr expression node to be checked 435 @param expr expression node to be checked
439 @type ast.expr 436 @type ast.expr
440 @param var variable name to be checked for 437 @param var variable name to be checked for
441 @type str 438 @type str
442 @return flag indicating the expression uses the variable 439 @return flag indicating the expression uses the variable
447 # false-positives. 444 # false-positives.
448 445
449 def __bodyContainsContinue(self, stmts): 446 def __bodyContainsContinue(self, stmts):
450 """ 447 """
451 Private method to check, if a list of statements contain a 'continue' statement. 448 Private method to check, if a list of statements contain a 'continue' statement.
452 449
453 @param stmts list of statements 450 @param stmts list of statements
454 @type list of ast.stmt 451 @type list of ast.stmt
455 @return flag indicating a continue statement 452 @return flag indicating a continue statement
456 @rtype bool 453 @rtype bool
457 """ 454 """
651 if isinstance(stmt, ast.Return): 648 if isinstance(stmt, ast.Return):
652 finallyHasReturn = True 649 finallyHasReturn = True
653 finallyReturn = stmt 650 finallyReturn = stmt
654 break 651 break
655 652
656 if ( 653 if (tryHasReturn or exceptHasReturn) and finallyHasReturn:
657 (tryHasReturn or exceptHasReturn)
658 and finallyHasReturn
659 ):
660 self.__error(finallyReturn.lineno - 1, finallyReturn.col_offset, "Y107") 654 self.__error(finallyReturn.lineno - 1, finallyReturn.col_offset, "Y107")
661 655
662 def __check108(self, node): 656 def __check108(self, node):
663 """ 657 """
664 Private method to check for if-elses which could be a ternary 658 Private method to check for if-elses which could be a ternary
691 and node.body[0].targets[0].id == node.orelse[0].targets[0].id 685 and node.body[0].targets[0].id == node.orelse[0].targets[0].id
692 and not isinstance(node.parent, ast.If) 686 and not isinstance(node.parent, ast.If)
693 ): 687 ):
694 targetVar = node.body[0].targets[0] 688 targetVar = node.body[0].targets[0]
695 assign = unparse(targetVar) 689 assign = unparse(targetVar)
696 690
697 # It's part of a bigger if-elseif block: 691 # It's part of a bigger if-elseif block:
698 if isinstance(node.parent, ast.If): 692 if isinstance(node.parent, ast.If):
699 for n in node.parent.body: 693 for n in node.parent.body:
700 if ( 694 if (
701 isinstance(n, ast.Assign) 695 isinstance(n, ast.Assign)
702 and isinstance(n.targets[0], ast.Name) 696 and isinstance(n.targets[0], ast.Name)
703 and n.targets[0].id == targetVar.id 697 and n.targets[0].id == targetVar.id
704 ): 698 ):
705 return 699 return
706 700
707 body = unparse(node.body[0].value) 701 body = unparse(node.body[0].value)
708 cond = unparse(node.test) 702 cond = unparse(node.test)
709 orelse = unparse(node.orelse[0].value) 703 orelse = unparse(node.orelse[0].value)
710 704
711 self.__error( 705 self.__error(
792 786
793 if isCompoundExpression: 787 if isCompoundExpression:
794 check = f"not ({check})" 788 check = f"not ({check})"
795 else: 789 else:
796 if check.startswith("not "): 790 if check.startswith("not "):
797 check = check[len("not "):] 791 check = check[len("not ") :]
798 else: 792 else:
799 check = f"not {check}" 793 check = f"not {check}"
800 self.__error( 794 self.__error(
801 node.lineno - 1, node.col_offset, "Y111", check, target, iterable 795 node.lineno - 1, node.col_offset, "Y111", check, target, iterable
802 ) 796 )
924 while sibling is not None: 918 while sibling is not None:
925 sibling = sibling.previous_sibling 919 sibling = sibling.previous_sibling
926 920
927 for match in matches: 921 for match in matches:
928 variable = unparse(match) 922 variable = unparse(match)
929 self.__error( 923 self.__error(match.lineno - 1, match.col_offset, "Y113", variable)
930 match.lineno - 1, match.col_offset, "Y113", variable
931 )
932 924
933 def __check114(self, node): 925 def __check114(self, node):
934 """ 926 """
935 Private method to check for alternative if clauses with identical 927 Private method to check for alternative if clauses with identical
936 bodies. 928 bodies.
1018 else: 1010 else:
1019 bodyValueStr = "None" 1011 bodyValueStr = "None"
1020 if isinstance(node.test.comparators[0], ast.Str): 1012 if isinstance(node.test.comparators[0], ast.Str):
1021 value = ( 1013 value = (
1022 bodyValueStr 1014 bodyValueStr
1023 if bodyValueStr[0] == '"' and bodyValueStr[-1] == '"' else 1015 if bodyValueStr[0] == '"' and bodyValueStr[-1] == '"'
1024 bodyValueStr[1:-1] 1016 else bodyValueStr[1:-1]
1025 ) 1017 )
1026 keyValuePairs = {node.test.comparators[0].s: value} 1018 keyValuePairs = {node.test.comparators[0].s: value}
1027 elif isinstance(node.test.comparators[0], ast.Num): 1019 elif isinstance(node.test.comparators[0], ast.Num):
1028 keyValuePairs = {node.test.comparators[0].n: bodyValueStr} 1020 keyValuePairs = {node.test.comparators[0].n: bodyValueStr}
1029 else: 1021 else:
1231 self.__error(node.lineno - 1, node.col_offset, "Y122", dictname, key) 1223 self.__error(node.lineno - 1, node.col_offset, "Y122", dictname, key)
1232 1224
1233 def __check123(self, node): 1225 def __check123(self, node):
1234 """ 1226 """
1235 Private method to check for complicated dictionary access with default value. 1227 Private method to check for complicated dictionary access with default value.
1236 1228
1237 @param node reference to the AST node to be checked 1229 @param node reference to the AST node to be checked
1238 @type ast.If 1230 @type ast.If
1239 """ 1231 """
1240 isPattern1 = ( 1232 isPattern1 = (
1241 len(node.body) == 1 1233 len(node.body) == 1
1288 dictStr = unparse(dictName) 1280 dictStr = unparse(dictName)
1289 defaultStr = unparse(defaultValue) 1281 defaultStr = unparse(defaultValue)
1290 valueStr = unparse(valueNode) 1282 valueStr = unparse(valueNode)
1291 else: 1283 else:
1292 return 1284 return
1293 self.__error(node.lineno - 1, node.col_offset, "Y123", valueStr, dictStr, 1285 self.__error(
1294 keyStr, defaultStr) 1286 node.lineno - 1,
1287 node.col_offset,
1288 "Y123",
1289 valueStr,
1290 dictStr,
1291 keyStr,
1292 defaultStr,
1293 )
1295 1294
1296 def __check181(self, node): 1295 def __check181(self, node):
1297 """ 1296 """
1298 Private method to check for assignments that could be converted into 1297 Private method to check for assignments that could be converted into
1299 an augmented assignment. 1298 an augmented assignment.
1719 self.__error(node.lineno - 1, node.col_offset, "Y402") 1718 self.__error(node.lineno - 1, node.col_offset, "Y402")
1720 1719
1721 def __check901(self, node): 1720 def __check901(self, node):
1722 """ 1721 """
1723 Private method to check for unnecessary bool conversion. 1722 Private method to check for unnecessary bool conversion.
1724 1723
1725 @param node reference to the AST node to be checked 1724 @param node reference to the AST node to be checked
1726 @type ast.Call 1725 @type ast.Call
1727 """ 1726 """
1728 if ( 1727 if (
1729 isinstance(node.func, ast.Name) 1728 isinstance(node.func, ast.Name)
1736 self.__error(node.lineno - 1, node.col_offset, "Y901", expected, actual) 1735 self.__error(node.lineno - 1, node.col_offset, "Y901", expected, actual)
1737 1736
1738 def __check904(self, node): 1737 def __check904(self, node):
1739 """ 1738 """
1740 Private method to check for dictionary initialization. 1739 Private method to check for dictionary initialization.
1741 1740
1742 @param node reference to the AST node to be checked 1741 @param node reference to the AST node to be checked
1743 @type ast.Assign 1742 @type ast.Assign
1744 """ 1743 """
1745 # a = {}; a['b'] = 'c' 1744 # a = {}; a['b'] = 'c'
1746 n2 = node.next_sibling 1745 n2 = node.next_sibling
1759 self.__error(node.lineno - 1, node.col_offset, "Y904", dictName) 1758 self.__error(node.lineno - 1, node.col_offset, "Y904", dictName)
1760 1759
1761 def __check905(self, node): 1760 def __check905(self, node):
1762 """ 1761 """
1763 Private method to check for list initialization by splitting a string. 1762 Private method to check for list initialization by splitting a string.
1764 1763
1765 @param node reference to the AST node to be checked 1764 @param node reference to the AST node to be checked
1766 @type ast.Call 1765 @type ast.Call
1767 """ 1766 """
1768 if ( 1767 if (
1769 isinstance(node.func, ast.Attribute) 1768 isinstance(node.func, ast.Attribute)
1780 self.__error(node.lineno - 1, node.col_offset, "Y905", expected, actual) 1779 self.__error(node.lineno - 1, node.col_offset, "Y905", expected, actual)
1781 1780
1782 def __check906(self, node): 1781 def __check906(self, node):
1783 """ 1782 """
1784 Private method to check for unnecessary nesting of os.path.join(). 1783 Private method to check for unnecessary nesting of os.path.join().
1785 1784
1786 @param node reference to the AST node to be checked 1785 @param node reference to the AST node to be checked
1787 @type ast.Call 1786 @type ast.Call
1788 """ 1787 """
1789 # __IGNORE_WARNING_D234r__ 1788 # __IGNORE_WARNING_D234r__
1790 def getOsPathJoinArgs(node): 1789 def getOsPathJoinArgs(node):
1828 ) 1827 )
1829 ): 1828 ):
1830 names = getOsPathJoinArgs(node) 1829 names = getOsPathJoinArgs(node)
1831 1830
1832 actual = unparse(node) 1831 actual = unparse(node)
1833 expected = "os.path.join({0})".format(', '.join(names)) 1832 expected = "os.path.join({0})".format(", ".join(names))
1834 self.__error(node.lineno - 1, node.col_offset, "Y906", expected, actual) 1833 self.__error(node.lineno - 1, node.col_offset, "Y906", expected, actual)
1835 1834
1836 def __check907(self, node): 1835 def __check907(self, node):
1837 """ 1836 """
1838 Private method to check for Union type annotation with None. 1837 Private method to check for Union type annotation with None.
1839 1838
1840 @param node reference to the AST node to be checked 1839 @param node reference to the AST node to be checked
1841 @type ast.Subscript 1840 @type ast.Subscript
1842 """ 1841 """
1843 if (isinstance(node.value, ast.Name) and node.value.id == "Union"): 1842 if isinstance(node.value, ast.Name) and node.value.id == "Union":
1844 if ( 1843 if isinstance(node.slice, ast.Index) and isinstance(
1845 isinstance(node.slice, ast.Index) 1844 node.slice.value, ast.Tuple
1846 and isinstance(node.slice.value, ast.Tuple)
1847 ): 1845 ):
1848 # Python 3.8 1846 # Python 3.8
1849 tupleVar = node.slice.value 1847 tupleVar = node.slice.value
1850 elif isinstance(node.slice, ast.Tuple): 1848 elif isinstance(node.slice, ast.Tuple):
1851 # Python 3.9+ 1849 # Python 3.9+
1868 ) 1866 )
1869 1867
1870 def __check909(self, node): 1868 def __check909(self, node):
1871 """ 1869 """
1872 Private method to check for reflexive assignments. 1870 Private method to check for reflexive assignments.
1873 1871
1874 @param node reference to the AST node to be checked 1872 @param node reference to the AST node to be checked
1875 @type ast.Assign 1873 @type ast.Assign
1876 """ 1874 """
1877 names = [] 1875 names = []
1878 if isinstance(node.value, (ast.Name, ast.Subscript, ast.Tuple)): 1876 if isinstance(node.value, (ast.Name, ast.Subscript, ast.Tuple)):
1882 1880
1883 if len(names) != len(set(names)) and not isinstance(node.parent, ast.ClassDef): 1881 if len(names) != len(set(names)) and not isinstance(node.parent, ast.ClassDef):
1884 srccode = unparse(node) 1882 srccode = unparse(node)
1885 self.__error(node.lineno - 1, node.col_offset, "Y909", srccode) 1883 self.__error(node.lineno - 1, node.col_offset, "Y909", srccode)
1886 1884
1885
1887 # 1886 #
1888 # eflag: noqa = M891 1887 # eflag: noqa = M891

eric ide

mercurial