104 "A202", |
104 "A202", |
105 "A203", |
105 "A203", |
106 "A204", |
106 "A204", |
107 "A205", |
107 "A205", |
108 "A206", |
108 "A206", |
109 "A301", |
|
110 "A401", |
109 "A401", |
|
110 "A402", |
111 ), |
111 ), |
112 ), |
112 ), |
113 (self.__checkAnnotationsFuture, ("A871", "A872", "A873")), |
113 (self.__checkAnnotationsFuture, ("A871", "A872", "A873")), |
114 (self.__checkAnnotationsCoverage, ("A881",)), |
114 (self.__checkAnnotationsCoverage, ("A881",)), |
115 (self.__checkAnnotationComplexity, ("A891", "A892")), |
115 (self.__checkAnnotationComplexity, ("A891", "A892")), |
184 check() |
184 check() |
185 |
185 |
186 ####################################################################### |
186 ####################################################################### |
187 ## Annotations |
187 ## Annotations |
188 ## |
188 ## |
189 ## adapted from: flake8-annotations v2.9.1 |
189 ## adapted from: flake8-annotations v3.0.1 |
190 ####################################################################### |
190 ####################################################################### |
191 |
191 |
192 def __checkFunctionAnnotations(self): |
192 def __checkFunctionAnnotations(self): |
193 """ |
193 """ |
194 Private method to check for function annotation issues. |
194 Private method to check for function annotation issues. |
238 # exactly one non-overload-decorated definition of the same function. |
238 # exactly one non-overload-decorated definition of the same function. |
239 lastOverloadDecoratedFunctionName = None |
239 lastOverloadDecoratedFunctionName = None |
240 |
240 |
241 # Iterate over the arguments with missing type hints, by function. |
241 # Iterate over the arguments with missing type hints, by function. |
242 for function in visitor.functionDefinitions: |
242 for function in visitor.functionDefinitions: |
|
243 if function.hasTypeComment: |
|
244 self.__error(function.lineno - 1, function.col_offset, "A402") |
|
245 |
243 if function.isDynamicallyTyped() and ( |
246 if function.isDynamicallyTyped() and ( |
244 allowUntypedDefs or (function.isNested and allowUntypedNested) |
247 allowUntypedDefs or (function.isNested and allowUntypedNested) |
245 ): |
248 ): |
246 # Skip recording errors from dynamically typed functions |
249 # Skip recording errors from dynamically typed functions |
247 # or nested functions |
250 # or nested functions |
251 # (by default) `functools.singledispatch` and |
254 # (by default) `functools.singledispatch` and |
252 # `functools.singledispatchmethod` |
255 # `functools.singledispatchmethod` |
253 if function.hasDecorator(dispatchDecorators): |
256 if function.hasDecorator(dispatchDecorators): |
254 continue |
257 continue |
255 |
258 |
256 # Create sentinels to check for mixed hint styles |
259 # Iterate over the annotated args to look for opinionated warnings |
257 hasTypeComment = function.hasTypeComment |
|
258 |
|
259 has3107Annotation = False |
|
260 # PEP 3107 annotations are captured by the return arg |
|
261 |
|
262 annotatedArgs = function.getAnnotatedArguments() |
260 annotatedArgs = function.getAnnotatedArguments() |
263 |
|
264 # Iterate over annotated args to detect mixing of type annotations |
|
265 # and type comments. Emit this only once per function definition |
|
266 for arg in annotatedArgs: |
|
267 if arg.hasTypeComment: |
|
268 hasTypeComment = True |
|
269 |
|
270 if arg.has3107Annotation: |
|
271 has3107Annotation = True |
|
272 |
|
273 if hasTypeComment and has3107Annotation: |
|
274 # Short-circuit check for mixing of type comments & |
|
275 # 3107-style annotations |
|
276 self.__error(function.lineno - 1, function.col_offset, "A301") |
|
277 break |
|
278 |
|
279 # Iterate over the annotated args to look for 'typing.Any' annotations |
|
280 # We could combine this with the above loop but I'd rather not add even |
|
281 # more sentinels unless we'd notice a significant enough performance impact |
|
282 for arg in annotatedArgs: |
261 for arg in annotatedArgs: |
283 if arg.isDynamicallyTyped: |
262 if arg.isDynamicallyTyped: |
284 if allowStarArgAny and arg.annotationType in { |
263 if allowStarArgAny and arg.annotationType in { |
285 AnnotationType.VARARG, |
264 AnnotationType.VARARG, |
286 AnnotationType.KWARG, |
265 AnnotationType.KWARG, |
300 if function.hasDecorator(overloadDecorators): |
279 if function.hasDecorator(overloadDecorators): |
301 lastOverloadDecoratedFunctionName = function.name |
280 lastOverloadDecoratedFunctionName = function.name |
302 |
281 |
303 # Record explicit errors for arguments that are missing annotations |
282 # Record explicit errors for arguments that are missing annotations |
304 for arg in function.getMissedAnnotations(): |
283 for arg in function.getMissedAnnotations(): |
|
284 # Check for type comments here since we're not considering them as |
|
285 # typed args |
|
286 if arg.hasTypeComment: |
|
287 self.__error(arg.lineno - 1, arg.col_offset, "A402") |
|
288 |
305 if arg.argname == "return": |
289 if arg.argname == "return": |
306 # return annotations have multiple possible short-circuit |
290 # return annotations have multiple possible short-circuit |
307 # paths |
291 # paths |
308 if ( |
292 if ( |
309 suppressNoneReturning |
293 suppressNoneReturning |