42 self.__typingAliases = [] |
51 self.__typingAliases = [] |
43 self.__importsFutureAnnotations = False |
52 self.__importsFutureAnnotations = False |
44 |
53 |
45 # e.g. from typing import List, typing.List, t.List |
54 # e.g. from typing import List, typing.List, t.List |
46 self.__typingImports = [] |
55 self.__typingImports = [] |
|
56 self.__simplifiedTypes = set() |
47 |
57 |
48 def visit_Import(self, node): |
58 def visit_Import(self, node): |
49 """ |
59 """ |
50 Public method to check imports for typing related stuff. |
60 Public method to check imports for typing related stuff. |
51 |
61 |
107 ): |
117 ): |
108 self.__typingImports.append(f"{node.value.id}.{node.attr}") |
118 self.__typingImports.append(f"{node.value.id}.{node.attr}") |
109 |
119 |
110 self.generic_visit(node) |
120 self.generic_visit(node) |
111 |
121 |
|
122 def visit_AnnAssign(self, node): |
|
123 """ |
|
124 Public method to check type annotations. |
|
125 |
|
126 @param node reference to the AST Assign node |
|
127 @type ast.AnnAssign |
|
128 """ |
|
129 if not self.__importsFutureAnnotations and node.annotation is not None: |
|
130 self.__processAnnotation(node.annotation) |
|
131 |
|
132 self.generic_visit(node) |
|
133 |
|
134 def visit_arg(self, node: ast.arg): |
|
135 """ |
|
136 Public method to check argument annotations. |
|
137 |
|
138 @param node reference to the AST argument node |
|
139 @type ast.arg |
|
140 """ |
|
141 if not self.__importsFutureAnnotations and node.annotation is not None: |
|
142 self.__processAnnotation(node.annotation) |
|
143 |
|
144 self.generic_visit(node) |
|
145 |
|
146 def __processAnnotation(self, node): |
|
147 """ |
|
148 Private method to process the given annotations. |
|
149 |
|
150 @param node reference to the AST node containing the annotations |
|
151 @type ast.expr |
|
152 """ |
|
153 if ( |
|
154 isinstance(node, ast.Name) |
|
155 and node.id in AnnotationsFutureVisitor.SimplifiedTypes |
|
156 ): |
|
157 self.__simplifiedTypes.add(node.id) |
|
158 elif isinstance(node, ast.Subscript): |
|
159 self.__processAnnotation(node.value) |
|
160 self.__processAnnotation(node.slice) |
|
161 elif isinstance(node, ast.Tuple): |
|
162 for subNode in node.elts: |
|
163 self.__processAnnotation(subNode) |
|
164 elif isinstance(node, ast.BinOp): |
|
165 if isinstance(node.op, ast.BitOr): |
|
166 self.__simplifiedTypes.add("union") |
|
167 self.__processAnnotation(node.left) |
|
168 self.__processAnnotation(node.right) |
|
169 elif isinstance(node, ast.Index): |
|
170 # Index is only used in Python 3.7 and 3.8, deprecated after. |
|
171 self.__processAnnotation(node.value) |
|
172 |
112 def importsFutureAnnotations(self): |
173 def importsFutureAnnotations(self): |
113 """ |
174 """ |
114 Public method to check, if the analyzed code uses future annotation. |
175 Public method to check, if the analyzed code uses future annotation. |
115 |
176 |
116 @return flag indicatung the use of future annotation |
177 @return flag indicatung the use of future annotation |
133 |
194 |
134 @return list of typing imports |
195 @return list of typing imports |
135 @rtype list of str |
196 @rtype list of str |
136 """ |
197 """ |
137 return self.__typingImports[:] |
198 return self.__typingImports[:] |
|
199 |
|
200 def hasSimplifiedTypes(self): |
|
201 """ |
|
202 Public method to check, if the analyzed code includes annotations with |
|
203 simplified types. |
|
204 |
|
205 @return flag indicating the presence of simplified types |
|
206 @rtype bool |
|
207 """ |
|
208 return bool(self.__simplifiedTypes) |
|
209 |
|
210 def getSimplifiedTypes(self): |
|
211 """ |
|
212 Public method Public method to get the list of detected simplified types. |
|
213 |
|
214 @return list of simplified types |
|
215 @rtype list of str |
|
216 """ |
|
217 return list(self.__simplifiedTypes) |