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

branch
eric7
changeset 10058
5d965939ab85
parent 9653
e67609152c5e
child 10119
64147a7e6393
diff -r 1e31ca1078ab -r 5d965939ab85 src/eric7/Plugins/CheckerPlugins/CodeStyleChecker/Annotations/AnnotationsFunctionVisitor.py
--- a/src/eric7/Plugins/CheckerPlugins/CodeStyleChecker/Annotations/AnnotationsFunctionVisitor.py	Tue May 23 14:39:14 2023 +0200
+++ b/src/eric7/Plugins/CheckerPlugins/CodeStyleChecker/Annotations/AnnotationsFunctionVisitor.py	Tue May 23 15:58:50 2023 +0200
@@ -7,18 +7,19 @@
 Module implementing a node visitor for function type annotations.
 """
 
-#
-# The visitor and associated classes are adapted from flake8-annotations v2.9.0
-#
+#####################################################################################
+## The visitor and associated classes are adapted from flake8-annotations v3.0.1
+#####################################################################################
 
 import ast
-import itertools
 import sys
 
 from .AnnotationsEnums import AnnotationType, ClassDecoratorType, FunctionType
 
 # The order of AST_ARG_TYPES must match Python's grammar
-AST_ARG_TYPES = ("posonlyargs", "args", "vararg", "kwonlyargs", "kwarg")
+AST_ARG_TYPES = ("args", "vararg", "kwonlyargs", "kwarg")
+if sys.version_info >= (3, 8, 0):
+    AST_ARG_TYPES = ("posonlyargs",) + AST_ARG_TYPES
 
 
 class Argument:
@@ -33,7 +34,6 @@
         col_offset,
         annotationType,
         hasTypeAnnotation=False,
-        has3107Annotation=False,
         hasTypeComment=False,
         isDynamicallyTyped=False,
     ):
@@ -51,9 +51,6 @@
         @param hasTypeAnnotation flag indicating the presence of a type
             annotation (defaults to False)
         @type bool (optional)
-        @param has3107Annotation flag indicating the presence of a PEP 3107
-            annotation (defaults to False)
-        @type bool (optional)
         @param hasTypeComment flag indicating the presence of a type comment
             (defaults to False)
         @type bool (optional)
@@ -65,7 +62,6 @@
         self.col_offset = col_offset
         self.annotationType = annotationType
         self.hasTypeAnnotation = hasTypeAnnotation
-        self.has3107Annotation = has3107Annotation
         self.hasTypeComment = hasTypeComment
         self.isDynamicallyTyped = isDynamicallyTyped
 
@@ -84,18 +80,15 @@
         annotationType = AnnotationType[annotationTypeName]
         newArg = cls(node.arg, node.lineno, node.col_offset, annotationType)
 
-        newArg.hasTypeAnnotation = False
         if node.annotation:
             newArg.hasTypeAnnotation = True
-            newArg.has3107Annotation = True
+
+            if cls._isAnnotatedAny(node.annotation):
+                newArg.isDynamicallyTyped = True
 
         if node.type_comment:
-            newArg.hasTypeAnnotation = True
             newArg.hasTypeComment = True
 
-            if cls._isAnnotatedAny(node.type_comment):
-                newArg.isDynamicallyTyped = True
-
         return newArg
 
     @staticmethod
@@ -109,10 +102,6 @@
             * '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'
@@ -122,8 +111,6 @@
             return True
         elif isinstance(argExpr, ast.Attribute) and argExpr.attr == "Any":
             return True
-        elif isinstance(argExpr, str) and argExpr.split(".", maxsplit=1)[-1] == "Any":
-            return True
 
         return False
 
@@ -352,7 +339,6 @@
         )
         if node.returns:
             returnArg.hasTypeAnnotation = True
-            returnArg.has3107Annotation = True
             newFunction.isReturnAnnotated = True
 
             if Argument._isAnnotatedAny(node.returns):
@@ -360,12 +346,8 @@
 
         newFunction.args.append(returnArg)
 
-        # Type comments in-line with input arguments are handled by the
-        # Argument class. If a function-level type comment is present, attempt
-        # to parse for any missed type hints.
         if node.type_comment:
             newFunction.hasTypeComment = True
-            newFunction = cls.tryTypeComment(newFunction, node)
 
         # Check for the presence of non-`None` returns using the special-case
         # return node visitor.
@@ -440,95 +422,6 @@
         return node.lineno, defEndColOffset
 
     @staticmethod
-    def tryTypeComment(funcObj, node):
-        """
-        Static method to infer type hints from a function-level type comment.
-
-        If a function is type commented it is assumed to have a return
-        annotation, otherwise Python will fail to parse the hint.
-
-        @param funcObj reference to the Function object
-        @type Function
-        @param node reference to the function definition node
-        @type ast.AsyncFunctionDef or ast.FunctionDef
-        @return reference to the modified Function object
-        @rtype Function
-        """
-        hintTree = ast.parse(node.type_comment, "<func_type>", "func_type")
-        hintTree = Function._maybeInjectClassArgument(hintTree, funcObj)
-
-        for arg, hintComment in itertools.zip_longest(funcObj.args, hintTree.argtypes):
-            if isinstance(hintComment, ast.Ellipsis):
-                continue
-
-            if arg and hintComment:
-                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
-
-    @staticmethod
-    def _maybeInjectClassArgument(hintTree, funcObj):
-        """
-        Static method to inject `self` or `cls` args into a type comment to
-        align with PEP 3107-style annotations.
-
-        Because PEP 484 does not describe a method to provide partial function-
-        level type comments, there is a potential for ambiguity in the context
-        of both class methods and classmethods when aligning type comments to
-        method arguments.
-
-        These two class methods, for example, should lint equivalently:
-
-            def bar(self, a):
-                # type: (int) -> int
-                ...
-
-            def bar(self, a: int) -> int
-                ...
-
-        When this example type comment is parsed by `ast` and then matched with
-        the method's arguments, it associates the `int` hint to `self` rather
-        than `a`, so a dummy hint needs to be provided in situations where
-        `self` or `class` are not hinted in the type comment in order to
-        achieve equivalent linting results to PEP-3107 style annotations.
-
-        A dummy `ast.Ellipses` constant is injected if the following criteria
-        are met:
-            1. The function node is either a class method or classmethod
-            2. The number of hinted args is at least 1 less than the number
-               of function args
-
-        @param hintTree parsed type hint node
-        @type ast.FunctionType
-        @param funcObj reference to the Function object
-        @type Function
-        @return reference to the hint node
-        @rtype ast.FunctionType
-        """
-        if not funcObj.isClassMethod:
-            # Short circuit
-            return hintTree
-
-        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
-
-        return hintTree
-
-    @staticmethod
     def getFunctionType(functionName):
         """
         Static method to determine the function's FunctionType from its name.

eric ide

mercurial