eric6/Plugins/CheckerPlugins/CodeStyleChecker/Simplify/SimplifyNodeVisitor.py

changeset 8192
e1157bd8b4c2
parent 8191
9125da0c227e
child 8194
b925628bf91f
equal deleted inserted replaced
8191:9125da0c227e 8192:e1157bd8b4c2
113 @type ast.For 113 @type ast.For
114 """ 114 """
115 self.__check104(node) 115 self.__check104(node)
116 self.__check110_111(node) 116 self.__check110_111(node)
117 self.__check113(node) 117 self.__check113(node)
118 self.__check118b(node)
118 119
119 self.generic_visit(node) 120 self.generic_visit(node)
120 121
121 def visit_Try(self, node): 122 def visit_Try(self, node):
122 """ 123 """
136 137
137 @param node reference to the Call node 138 @param node reference to the Call node
138 @type ast.Call 139 @type ast.Call
139 """ 140 """
140 self.__check115(node) 141 self.__check115(node)
142
143 self.generic_visit(node)
144
145 def visit_With(self, node):
146 """
147 Public method to process a With node.
148
149 @param node reference to the With node
150 @type ast.With
151 """
152 self.__check117(node)
153
154 self.generic_visit(node)
155
156 def visit_Compare(self, node):
157 """
158 Public method to process a Compare node.
159
160 @param node reference to the Compare node
161 @type ast.Compare
162 """
163 self.__check118a(node)
164
165 self.generic_visit(node)
166
167 def visit_ClassDef(self, node):
168 """
169 Public method to process a ClassDef node.
170
171 @param node reference to the ClassDef node
172 @type ast.ClassDef
173 """
174 self.__check119(node)
141 175
142 self.generic_visit(node) 176 self.generic_visit(node)
143 177
144 ############################################################# 178 #############################################################
145 ## Helper methods for the various checkers below 179 ## Helper methods for the various checkers below
466 ): 500 ):
467 assign = unparse(node.body[0].targets[0]) 501 assign = unparse(node.body[0].targets[0])
468 body = unparse(node.body[0].value) 502 body = unparse(node.body[0].value)
469 cond = unparse(node.test) 503 cond = unparse(node.test)
470 orelse = unparse(node.orelse[0].value) 504 orelse = unparse(node.orelse[0].value)
471 self.__error(node.lineno - 1, node.col_offset, "Y108", 505 if len(
472 assign, body, cond, orelse) 506 "{0} = {1} if {2} else {3}".format(assign, body, cond, orelse)
507 ) > 79:
508 self.__error(node.lineno - 1, node.col_offset, "Y108a")
509 else:
510 self.__error(node.lineno - 1, node.col_offset, "Y108b",
511 assign, body, cond, orelse)
473 512
474 def __check109(self, node): 513 def __check109(self, node):
475 """ 514 """
476 Private method to check for multiple equalities with the same value 515 Private method to check for multiple equalities with the same value
477 are combined via "or". 516 are combined via "or".
728 isinstance(node.orelse[0], ast.If) 767 isinstance(node.orelse[0], ast.If)
729 ): 768 ):
730 variable = node.test.left 769 variable = node.test.left
731 child = node.orelse[0] 770 child = node.orelse[0]
732 elseValue = None 771 elseValue = None
772 if node.body[0].value is not None:
773 bodyValueStr = unparse(node.body[0].value).strip("'")
774 else:
775 bodyValueStr = "None"
733 if isinstance(node.test.comparators[0], ast.Str): 776 if isinstance(node.test.comparators[0], ast.Str):
734 keyValuePairs = { 777 keyValuePairs = {
735 node.test.comparators[0].s: 778 node.test.comparators[0].s: bodyValueStr
736 unparse(node.body[0].value).strip("'")
737 } 779 }
738 elif isinstance(node.test.comparators[0], ast.Num): 780 elif isinstance(node.test.comparators[0], ast.Num):
739 keyValuePairs = { 781 keyValuePairs = {
740 node.test.comparators[0].n: 782 node.test.comparators[0].n: bodyValueStr,
741 unparse(node.body[0].value).strip("'")
742 } 783 }
743 else: 784 else:
744 keyValuePairs = { 785 keyValuePairs = {
745 node.test.comparators[0].value: 786 node.test.comparators[0].value: bodyValueStr
746 unparse(node.body[0].value).strip("'")
747 } 787 }
748 while child: 788 while child:
749 if not ( 789 if not (
750 isinstance(child.test, ast.Compare) and 790 isinstance(child.test, ast.Compare) and
751 isinstance(child.test.left, ast.Name) and 791 isinstance(child.test.left, ast.Name) and
785 ret = f"{keyValuePairs}.get({variable.id}, {elseValue})" 825 ret = f"{keyValuePairs}.get({variable.id}, {elseValue})"
786 else: 826 else:
787 ret = f"{keyValuePairs}.get({variable.id})" 827 ret = f"{keyValuePairs}.get({variable.id})"
788 828
789 self.__error(node.lineno - 1, node.col_offset, "Y116", ret) 829 self.__error(node.lineno - 1, node.col_offset, "Y116", ret)
830
831 def __check117(self, node):
832 """
833 Private method to check for multiple with-statements with same scope.
834
835 @param node reference to the AST node to be checked
836 @type ast.With
837 """
838 # with A() as a:
839 # with B() as b:
840 # print("hello")
841 if (
842 len(node.body) == 1 and
843 isinstance(node.body[0], ast.With)
844 ):
845 withItems = []
846 for withitem in node.items + node.body[0].items:
847 withItems.append(f"{unparse(withitem)}")
848 mergedWith = f"with {', '.join(withItems)}:"
849 self.__error(node.lineno - 1, node.col_offset, "Y117", mergedWith)
850
851 def __check118a(self, node):
852 """
853 Private method to check for usages of "key in dict.keys()".
854
855 @param node reference to the AST node to be checked
856 @type ast.Compare
857 """
858 # key in dict.keys()
859 if (
860 len(node.ops) == 1 and
861 isinstance(node.ops[0], ast.In) and
862 len(node.comparators) == 1
863 ):
864 callNode = node.comparators[0]
865 if not isinstance(callNode, ast.Call):
866 return
867
868 attrNode = callNode.func
869 if (
870 isinstance(callNode.func, ast.Attribute) and
871 callNode.func.attr == "keys" and
872 isinstance(callNode.func.ctx, ast.Load)
873 ):
874 keyStr = unparse(node.left)
875 dictStr = unparse(attrNode.value)
876 self.__error(node.lineno - 1, node.col_offset, "Y118",
877 keyStr, dictStr)
878
879 def __check118b(self, node):
880 """
881 Private method to check for usages of "key in dict.keys()".
882
883 @param node reference to the AST node to be checked
884 @type ast.For
885 """
886 # for key in dict.keys():
887 # # do something
888 callNode = node.iter
889 if not isinstance(callNode, ast.Call):
890 return
891
892 attrNode = callNode.func
893 if (
894 isinstance(callNode.func, ast.Attribute) and
895 callNode.func.attr == "keys" and
896 isinstance(callNode.func.ctx, ast.Load)
897 ):
898 keyStr = unparse(node.target)
899 dictStr = unparse(attrNode.value)
900 self.__error(node.lineno - 1, node.col_offset, "Y118",
901 keyStr, dictStr)
902
903 def __check119(self, node):
904 """
905 Public method to check for classes that should be "dataclasses".
906
907 @param node reference to the AST node to be checked
908 @type ast.ClassDef
909 """
910 if (
911 len(node.decorator_list) == 0 and
912 len(node.bases) == 0
913 ):
914 dataclassFunctions = [
915 "__init__",
916 "__eq__",
917 "__hash__",
918 "__repr__",
919 "__str__",
920 ]
921 hasOnlyConstructorMethod = True
922 for bodyElement in node.body:
923 if (
924 isinstance(bodyElement, ast.FunctionDef) and
925 bodyElement.name not in dataclassFunctions
926 ):
927 hasOnlyConstructorMethod = False
928 break
929
930 if (
931 hasOnlyConstructorMethod and
932 sum(1 for el in node.body
933 if isinstance(el, ast.FunctionDef)) > 0
934 ):
935 self.__error(node.lineno - 1, node.col_offset, "Y119",
936 node.name)
790 937
791 # 938 #
792 # eflag: noqa = M891 939 # eflag: noqa = M891

eric ide

mercurial