eric6/Plugins/CheckerPlugins/CodeStyleChecker/Annotations/AnnotationsChecker.py

changeset 8246
e4b95b0ebd31
parent 8244
ed8cb108b27b
child 8249
8232e8e4eeef
equal deleted inserted replaced
8245:dce55f623991 8246:e4b95b0ebd31
13 from functools import lru_cache 13 from functools import lru_cache
14 14
15 import AstUtilities 15 import AstUtilities
16 16
17 from .AnnotationsEnums import AnnotationType, ClassDecoratorType, FunctionType 17 from .AnnotationsEnums import AnnotationType, ClassDecoratorType, FunctionType
18 from .AnnotationsCheckerDefaults import AnnotationsCheckerDefaultArgs
18 19
19 20
20 class AnnotationsChecker: 21 class AnnotationsChecker:
21 """ 22 """
22 Class implementing a checker for function type annotations. 23 Class implementing a checker for function type annotations.
87 ), 88 ),
88 (self.__checkAnnotationsCoverage, ("A881",)), 89 (self.__checkAnnotationsCoverage, ("A881",)),
89 (self.__checkAnnotationComplexity, ("A891", "A892")), 90 (self.__checkAnnotationComplexity, ("A891", "A892")),
90 ] 91 ]
91 92
92 # TODO: the parameters to CodeStyleCheckerDialog
93 self.__defaultArgs = {
94 # Annotations
95 "SuppressNoneReturning": False,
96 "SuppressDummyArgs": False,
97 "AllowUntypedDefs": False,
98 "AllowUntypedNested": False,
99 "MypyInitReturn": False,
100 "DispatchDecorators": [
101 "singledispatch",
102 "singledispatchmethod",
103 ],
104 "OverloadDecorators": ["overload"],
105
106 # Annotation Coverage
107 "MinimumCoverage": 75, # % of type annotation coverage
108
109 # Annotation Complexity
110 "MaximumComplexity": 3,
111 "MaximumLength": 7,
112 }
113
114 self.__checkers = [] 93 self.__checkers = []
115 for checker, codes in checkersWithCodes: 94 for checker, codes in checkersWithCodes:
116 if any(not (code and self.__ignoreCode(code)) 95 if any(not (code and self.__ignoreCode(code))
117 for code in codes): 96 for code in codes):
118 self.__checkers.append(checker) 97 self.__checkers.append(checker)
191 """ 170 """
192 Private method to check for function annotation issues. 171 Private method to check for function annotation issues.
193 """ 172 """
194 suppressNoneReturning = self.__args.get( 173 suppressNoneReturning = self.__args.get(
195 "SuppressNoneReturning", 174 "SuppressNoneReturning",
196 self.__defaultArgs["SuppressNoneReturning"]) 175 AnnotationsCheckerDefaultArgs["SuppressNoneReturning"])
197 suppressDummyArgs = self.__args.get( 176 suppressDummyArgs = self.__args.get(
198 "SuppressDummyArgs", 177 "SuppressDummyArgs",
199 self.__defaultArgs["SuppressDummyArgs"]) 178 AnnotationsCheckerDefaultArgs["SuppressDummyArgs"])
200 allowUntypedDefs = self.__args.get( 179 allowUntypedDefs = self.__args.get(
201 "AllowUntypedDefs", 180 "AllowUntypedDefs",
202 self.__defaultArgs["AllowUntypedDefs"]) 181 AnnotationsCheckerDefaultArgs["AllowUntypedDefs"])
203 allowUntypedNested = self.__args.get( 182 allowUntypedNested = self.__args.get(
204 "AllowUntypedNested", 183 "AllowUntypedNested",
205 self.__defaultArgs["AllowUntypedNested"]) 184 AnnotationsCheckerDefaultArgs["AllowUntypedNested"])
206 mypyInitReturn = self.__args.get( 185 mypyInitReturn = self.__args.get(
207 "MypyInitReturn", 186 "MypyInitReturn",
208 self.__defaultArgs["MypyInitReturn"]) 187 AnnotationsCheckerDefaultArgs["MypyInitReturn"])
209 188
210 # Store decorator lists as sets for easier lookup 189 # Store decorator lists as sets for easier lookup
211 dispatchDecorators = set(self.__args.get( 190 dispatchDecorators = set(self.__args.get(
212 "DispatchDecorators", 191 "DispatchDecorators",
213 self.__defaultArgs["DispatchDecorators"])) 192 AnnotationsCheckerDefaultArgs["DispatchDecorators"]))
214 overloadDecorators = set(self.__args.get( 193 overloadDecorators = set(self.__args.get(
215 "OverloadDecorators", 194 "OverloadDecorators",
216 self.__defaultArgs["OverloadDecorators"])) 195 AnnotationsCheckerDefaultArgs["OverloadDecorators"]))
217 196
218 from .AnnotationsFunctionVisitor import FunctionVisitor 197 from .AnnotationsFunctionVisitor import FunctionVisitor
219 visitor = FunctionVisitor(self.__source) 198 visitor = FunctionVisitor(self.__source)
220 visitor.visit(self.__tree) 199 visitor.visit(self.__tree)
221 200
230 if ( 209 if (
231 function.isDynamicallyTyped() and 210 function.isDynamicallyTyped() and
232 (allowUntypedDefs or 211 (allowUntypedDefs or
233 (function.isNested and allowUntypedNested)) 212 (function.isNested and allowUntypedNested))
234 ): 213 ):
235 # Skip yielding errors from dynamically typed functions 214 # Skip recording errors from dynamically typed functions
236 # or nested functions 215 # or nested functions
237 continue 216 continue
238 217
239 # Skip yielding errors for configured dispatch functions, such as 218 # Skip recording errors for configured dispatch functions, such as
240 # (by default) `functools.singledispatch` and 219 # (by default) `functools.singledispatch` and
241 # `functools.singledispatchmethod` 220 # `functools.singledispatchmethod`
242 if function.hasDecorator(dispatchDecorators): 221 if function.hasDecorator(dispatchDecorators):
243 continue 222 continue
244 223
422 def __checkAnnotationsCoverage(self): 401 def __checkAnnotationsCoverage(self):
423 """ 402 """
424 Private method to check for function annotation coverage. 403 Private method to check for function annotation coverage.
425 """ 404 """
426 minAnnotationsCoverage = self.__args.get( 405 minAnnotationsCoverage = self.__args.get(
427 "MinimumCoverage", self.__defaultArgs["MinimumCoverage"]) 406 "MinimumCoverage", AnnotationsCheckerDefaultArgs["MinimumCoverage"])
428 if minAnnotationsCoverage == 0: 407 if minAnnotationsCoverage == 0:
429 # 0 means it is switched off 408 # 0 means it is switched off
430 return 409 return
431 410
432 functionDefs = [ 411 functionDefs = [
477 def __checkAnnotationComplexity(self): 456 def __checkAnnotationComplexity(self):
478 """ 457 """
479 Private method to check the type annotation complexity. 458 Private method to check the type annotation complexity.
480 """ 459 """
481 maxAnnotationComplexity = self.__args.get( 460 maxAnnotationComplexity = self.__args.get(
482 "MaximumComplexity", self.__defaultArgs["MaximumComplexity"]) 461 "MaximumComplexity", AnnotationsCheckerDefaultArgs["MaximumComplexity"])
483 # TODO: include 'MaximumLength' in CodeStyleCheckerDialog 462 # TODO: include 'MaximumLength' in CodeStyleCheckerDialog
484 maxAnnotationLength = self.__args.get( 463 maxAnnotationLength = self.__args.get(
485 "MaximumLength", self.__defaultArgs["MaximumLength"]) 464 "MaximumLength", AnnotationsCheckerDefaultArgs["MaximumLength"])
486 typeAnnotations = [] 465 typeAnnotations = []
487 466
488 functionDefs = [ 467 functionDefs = [
489 f for f in ast.walk(self.__tree) 468 f for f in ast.walk(self.__tree)
490 if isinstance(f, (ast.AsyncFunctionDef, ast.FunctionDef)) 469 if isinstance(f, (ast.AsyncFunctionDef, ast.FunctionDef))

eric ide

mercurial