src/eric7/Plugins/CheckerPlugins/CodeStyleChecker/Annotations/AnnotationsFunctionVisitor.py

branch
eric7
changeset 9276
e6748a5e24b9
parent 9221
bf71ee032bb4
child 9500
5771348ded12
--- a/src/eric7/Plugins/CheckerPlugins/CodeStyleChecker/Annotations/AnnotationsFunctionVisitor.py	Wed Jul 27 18:02:43 2022 +0200
+++ b/src/eric7/Plugins/CheckerPlugins/CodeStyleChecker/Annotations/AnnotationsFunctionVisitor.py	Thu Jul 28 14:19:57 2022 +0200
@@ -8,7 +8,7 @@
 """
 
 #
-# The visitor and associated classes are adapted from flake8-annotations v2.7.0
+# The visitor and associated classes are adapted from flake8-annotations v2.9.0
 #
 
 import ast
@@ -35,6 +35,7 @@
         hasTypeAnnotation=False,
         has3107Annotation=False,
         hasTypeComment=False,
+        isDynamicallyTyped=False,
     ):
         """
         Constructor
@@ -56,6 +57,8 @@
         @param hasTypeComment flag indicating the presence of a type comment
             (defaults to False)
         @type bool (optional)
+        @param isDynamicallyTyped flag indicating dynamic typing (defaults to False)
+        @type bool (optional)
         """
         self.argname = argname
         self.lineno = lineno
@@ -64,6 +67,7 @@
         self.hasTypeAnnotation = hasTypeAnnotation
         self.has3107Annotation = has3107Annotation
         self.hasTypeComment = hasTypeComment
+        self.isDynamicallyTyped = isDynamicallyTyped
 
     @classmethod
     def fromNode(cls, node, annotationTypeName):
@@ -89,8 +93,43 @@
             newArg.hasTypeAnnotation = True
             newArg.hasTypeComment = True
 
+            if cls._isAnnotatedAny(node.type_comment):
+                newArg.isDynamicallyTyped = True
+
         return newArg
 
+    @staticmethod
+    def _isAnnotatedAny(argExpr):
+        """
+        Static method to check if the provided expression node is annotated with
+        'typing.Any'.
+
+        Support is provided for the following patterns:
+            * 'from typing import Any; foo: Any'
+            * 'import typing; foo: typing.Any'
+            * 'import typing as <alias>; foo: <alias>.Any'
+
+        Type comments are also supported. Inline type comments are assumed to be
+        passed here as 'str', and function-level type comments are assumed to be
+        passed as 'ast.expr'.
+
+        @param argExpr DESCRIPTION
+        @type ast.expr or str
+        @return flag indicating an annotation with 'typing.Any'
+        @rtype bool
+        """
+        if isinstance(argExpr, ast.Name):
+            if argExpr.id == "Any":
+                return True
+        elif isinstance(argExpr, ast.Attribute):
+            if argExpr.attr == "Any":
+                return True
+        elif isinstance(argExpr, str):  # __IGNORE_WARNING_Y102__
+            if argExpr.split(".", maxsplit=1)[-1] == "Any":
+                return True
+
+        return False
+
 
 class Function:
     """
@@ -319,6 +358,9 @@
             returnArg.has3107Annotation = True
             newFunction.isReturnAnnotated = True
 
+            if Argument._isAnnotatedAny(node.returns):
+                returnArg.isDynamicallyTyped = True
+
         newFunction.args.append(returnArg)
 
         # Type comments in-line with input arguments are handled by the
@@ -426,10 +468,15 @@
                 arg.hasTypeAnnotation = True
                 arg.hasTypeComment = True
 
+                if Argument._isAnnotatedAny(hintComment):
+                    arg.isDynamicallyTyped = True
+
         # Return arg is always last
         funcObj.args[-1].hasTypeAnnotation = True
         funcObj.args[-1].hasTypeComment = True
         funcObj.isReturnAnnotated = True
+        if Argument._isAnnotatedAny(hintTree.returns):
+            arg.isDynamicallyTyped = True
 
         return funcObj
 
@@ -476,9 +523,9 @@
             # Short circuit
             return hintTree
 
-        if funcObj.classDecoratorType != ClassDecoratorType.STATICMETHOD and len(
-            hintTree.argtypes
-        ) < (len(funcObj.args) - 1):
+        if funcObj.classDecoratorType != ClassDecoratorType.STATICMETHOD and (
+            len(hintTree.argtypes) < (len(funcObj.args) - 1)
+        ):
             # Subtract 1 to skip return arg
             hintTree.argtypes = [ast.Ellipsis()] + hintTree.argtypes
 

eric ide

mercurial