src/eric7/Plugins/CheckerPlugins/CodeStyleChecker/Pydantic/PydanticVisitor.py

branch
eric7
changeset 11150
73d80859079c
parent 11143
ef75c265ab47
equal deleted inserted replaced
11149:fc45672fae42 11150:73d80859079c
35 35
36 def __init__(self, errorCallback): 36 def __init__(self, errorCallback):
37 """ 37 """
38 Constructor 38 Constructor
39 39
40 @param errorCallback callback function to register an error 40 @param errorCallback callback function to register an issue
41 @type func 41 @type func
42 """ 42 """
43 super().__init__() 43 super().__init__()
44 44
45 self.__error = errorCallback 45 self.__error = errorCallback
92 self.__currentClass in {"pydantic_model", "dataclass"} 92 self.__currentClass in {"pydantic_model", "dataclass"}
93 and isinstance(node.value, ast.Call) 93 and isinstance(node.value, ast.Call)
94 and isFunction(node.value, "Field") 94 and isFunction(node.value, "Field")
95 and len(node.value.args) >= 1 95 and len(node.value.args) >= 1
96 ): 96 ):
97 self.__error(node.lineno - 1, node.col_offset, "PYD001") 97 self.__error(node, "PYD-001")
98 98
99 def __checkForPyd002(self, node): 99 def __checkForPyd002(self, node):
100 """ 100 """
101 Private method to check non-annotated attribute inside Pydantic model. 101 Private method to check non-annotated attribute inside Pydantic model.
102 102
111 if isinstance(assign.targets[0], ast.Name) 111 if isinstance(assign.targets[0], ast.Name)
112 if not assign.targets[0].id.startswith("_") 112 if not assign.targets[0].id.startswith("_")
113 if assign.targets[0].id != "model_config" 113 if assign.targets[0].id != "model_config"
114 ] 114 ]
115 for assignment in invalidAssignments: 115 for assignment in invalidAssignments:
116 self.__error(assignment.lineno - 1, assignment.col_offset, "PYD002") 116 self.__error(assignment, "PYD-002")
117 117
118 def __checkForPyd003(self, node): 118 def __checkForPyd003(self, node):
119 """ 119 """
120 Private method to check unecessary Field call to specify a default value. 120 Private method to check unecessary Field call to specify a default value.
121 121
127 and isinstance(node.value, ast.Call) 127 and isinstance(node.value, ast.Call)
128 and isFunction(node.value, "Field") 128 and isFunction(node.value, "Field")
129 and len(node.value.keywords) == 1 129 and len(node.value.keywords) == 1
130 and node.value.keywords[0].arg == "default" 130 and node.value.keywords[0].arg == "default"
131 ): 131 ):
132 self.__error(node.lineno - 1, node.col_offset, "PYD003") 132 self.__error(node, "PYD-003")
133 133
134 def __checkForPyd004(self, node): 134 def __checkForPyd004(self, node):
135 """ 135 """
136 Private method to check for a default argument specified in annotated. 136 Private method to check for a default argument specified in annotated.
137 137
153 and any(k.arg == "default" for k in elt.keywords) 153 and any(k.arg == "default" for k in elt.keywords)
154 ), 154 ),
155 None, 155 None,
156 ) 156 )
157 if fieldCall is not None: 157 if fieldCall is not None:
158 self.__error(node.lineno - 1, node.col_offset, "PYD004") 158 self.__error(node, "PYD-004")
159 159
160 def __checkForPyd005(self, node): 160 def __checkForPyd005(self, node):
161 """ 161 """
162 Private method to check for a field name overriding the annotation. 162 Private method to check for a field name overriding the annotation.
163 163
171 if isinstance(stmt, ast.AnnAssign) and isinstance( 171 if isinstance(stmt, ast.AnnAssign) and isinstance(
172 stmt.target, ast.Name 172 stmt.target, ast.Name
173 ): 173 ):
174 previousTargets.add(stmt.target.id) 174 previousTargets.add(stmt.target.id)
175 if previousTargets & extractAnnotations(stmt.annotation): 175 if previousTargets & extractAnnotations(stmt.annotation):
176 self.__error(stmt.lineno - 1, stmt.col_offset, "PYD005") 176 self.__error(stmt, "PYD-005")
177 177
178 def __checkForPyd006(self, node): 178 def __checkForPyd006(self, node):
179 """ 179 """
180 Private method to check for duplicate field names. 180 Private method to check for duplicate field names.
181 181
188 for stmt in node.body: 188 for stmt in node.body:
189 if isinstance(stmt, ast.AnnAssign) and isinstance( 189 if isinstance(stmt, ast.AnnAssign) and isinstance(
190 stmt.target, ast.Name 190 stmt.target, ast.Name
191 ): 191 ):
192 if stmt.target.id in previousTargets: 192 if stmt.target.id in previousTargets:
193 self.__error(stmt.lineno - 1, stmt.col_offset, "PYD006") 193 self.__error(stmt, "PYD-006")
194 194
195 previousTargets.add(stmt.target.id) 195 previousTargets.add(stmt.target.id)
196 196
197 def __checkForPyd010(self, node: ast.ClassDef) -> None: 197 def __checkForPyd010(self, node: ast.ClassDef) -> None:
198 """ 198 """
207 isinstance(stmt, ast.AnnAssign) 207 isinstance(stmt, ast.AnnAssign)
208 and isinstance(stmt.target, ast.Name) 208 and isinstance(stmt.target, ast.Name)
209 and stmt.target.id == "__pydantic_config__" 209 and stmt.target.id == "__pydantic_config__"
210 ): 210 ):
211 ##~ __pydantic_config__: ... = ... 211 ##~ __pydantic_config__: ... = ...
212 self.__error(stmt.lineno - 1, stmt.col_offset, "PYD010") 212 self.__error(stmt, "PYD-010")
213 213
214 if isinstance(stmt, ast.Assign) and any( 214 if isinstance(stmt, ast.Assign) and any(
215 t.id == "__pydantic_config__" 215 t.id == "__pydantic_config__"
216 for t in stmt.targets 216 for t in stmt.targets
217 if isinstance(t, ast.Name) 217 if isinstance(t, ast.Name)
218 ): 218 ):
219 ##~ __pydantic_config__ = ... 219 ##~ __pydantic_config__ = ...
220 self.__error(stmt.lineno - 1, stmt.col_offset, "PYD010") 220 self.__error(stmt, "PYD-010")
221 221
222 def visit_ClassDef(self, node: ast.ClassDef) -> None: 222 def visit_ClassDef(self, node: ast.ClassDef) -> None:
223 """ 223 """
224 Public method to process class definitions. 224 Public method to process class definitions.
225 225
226 @param node reference to the node to be processed. 226 @param node reference to the node to be processed.
227 @type ast.ClassDef 227 @type ast.ClassDef
228 """ 228 """
229 self.__enterClass(node) 229 self.__enterClass(node)
230 230
231 # TODO: implement these methods
232 self.__checkForPyd002(node) 231 self.__checkForPyd002(node)
233 self.__checkForPyd005(node) 232 self.__checkForPyd005(node)
234 self.__checkForPyd006(node) 233 self.__checkForPyd006(node)
235 self.__checkForPyd010(node) 234 self.__checkForPyd010(node)
236 235

eric ide

mercurial