diff -r ca636e8d80fd -r f1427d95cfde src/eric7/Plugins/CheckerPlugins/CodeStyleChecker/Annotations/AnnotationsFutureVisitor.py --- a/src/eric7/Plugins/CheckerPlugins/CodeStyleChecker/Annotations/AnnotationsFutureVisitor.py Fri May 19 16:01:53 2023 +0200 +++ b/src/eric7/Plugins/CheckerPlugins/CodeStyleChecker/Annotations/AnnotationsFutureVisitor.py Fri May 19 18:08:45 2023 +0200 @@ -8,8 +8,7 @@ """ # -# The visitor and associated classes are adapted from flake8-future-annotations -# v0.0.5 +# The visitor and associated classes are adapted from flake8-future-annotations v1.1.0 # import ast @@ -32,6 +31,16 @@ "Union", "Type", ) + SimplifiedTypes = ( + "defaultdict", + "deque", + "dict", + "frozenset", + "list", + "set", + "tuple", + "type", + ) def __init__(self): """ @@ -44,6 +53,7 @@ # e.g. from typing import List, typing.List, t.List self.__typingImports = [] + self.__simplifiedTypes = set() def visit_Import(self, node): """ @@ -109,6 +119,57 @@ self.generic_visit(node) + def visit_AnnAssign(self, node): + """ + Public method to check type annotations. + + @param node reference to the AST Assign node + @type ast.AnnAssign + """ + if not self.__importsFutureAnnotations and node.annotation is not None: + self.__processAnnotation(node.annotation) + + self.generic_visit(node) + + def visit_arg(self, node: ast.arg): + """ + Public method to check argument annotations. + + @param node reference to the AST argument node + @type ast.arg + """ + if not self.__importsFutureAnnotations and node.annotation is not None: + self.__processAnnotation(node.annotation) + + self.generic_visit(node) + + def __processAnnotation(self, node): + """ + Private method to process the given annotations. + + @param node reference to the AST node containing the annotations + @type ast.expr + """ + if ( + isinstance(node, ast.Name) + and node.id in AnnotationsFutureVisitor.SimplifiedTypes + ): + self.__simplifiedTypes.add(node.id) + elif isinstance(node, ast.Subscript): + self.__processAnnotation(node.value) + self.__processAnnotation(node.slice) + elif isinstance(node, ast.Tuple): + for subNode in node.elts: + self.__processAnnotation(subNode) + elif isinstance(node, ast.BinOp): + if isinstance(node.op, ast.BitOr): + self.__simplifiedTypes.add("union") + self.__processAnnotation(node.left) + self.__processAnnotation(node.right) + elif isinstance(node, ast.Index): + # Index is only used in Python 3.7 and 3.8, deprecated after. + self.__processAnnotation(node.value) + def importsFutureAnnotations(self): """ Public method to check, if the analyzed code uses future annotation. @@ -135,3 +196,22 @@ @rtype list of str """ return self.__typingImports[:] + + def hasSimplifiedTypes(self): + """ + Public method to check, if the analyzed code includes annotations with + simplified types. + + @return flag indicating the presence of simplified types + @rtype bool + """ + return bool(self.__simplifiedTypes) + + def getSimplifiedTypes(self): + """ + Public method Public method to get the list of detected simplified types. + + @return list of simplified types + @rtype list of str + """ + return list(self.__simplifiedTypes)