def func_annotations_filter(node: nc.NodeNG) -> nc.NodeNG:
    """Filter annotated function args/retvals.

    This accounts for deferred evaluation available in in Python 3.7+
    via 'from __future__ import annotations'. In this case we don't
    want Pylint to complain about missing symbols in annotations when
    they aren't actually needed at runtime.
    """
    # Only do this if deferred annotations are on.
    if not using_future_annotations(node):
        return node

    # Wipe out argument annotations.

    # Special-case: certain function decorators *do*
    # evaluate annotations at runtime so we want to leave theirs intact.
    # This includes functools.singledispatch, ba.dispatchmethod, and
    # efro.MessageReceiver.
    # Lets just look for a @XXX.register or @XXX.handler decorators for
    # now; can get more specific if we get false positives.
    if node.decorators is not None:
        for dnode in node.decorators.nodes:
            if (isinstance(dnode, astroid.nodes.Name)
                    and dnode.name in {'dispatchmethod', 'singledispatch'}):
                return node  # Leave annotations intact.

            if (isinstance(dnode, astroid.nodes.Attribute)
                    and dnode.attrname in {'register', 'handler'}):
                return node  # Leave annotations intact.

    node.args.annotations = [None for _ in node.args.args]
    node.args.varargannotation = None
    node.args.kwargannotation = None
    node.args.kwonlyargs_annotations = [None for _ in node.args.kwonlyargs]
    node.args.posonlyargs_annotations = [None for _ in node.args.kwonlyargs]

    # Wipe out return-value annotation.
    if node.returns is not None:
        node.returns = None

    return node
Beispiel #2
0
def func_annotations_filter(node: nc.NodeNG) -> nc.NodeNG:
    """Filter annotated function args/retvals.

    This accounts for deferred evaluation available in in Python 3.7+
    via 'from __future__ import annotations'. In this case we don't
    want Pylint to complain about missing symbols in annotations when
    they aren't actually needed at runtime.
    """
    # Only do this if deferred annotations are on.
    if not using_future_annotations(node):
        return node

    # Wipe out argument annotations.

    # Special-case: functools.singledispatch and ba.dispatchmethod *do*
    # evaluate annotations at runtime so we want to leave theirs intact.
    # Lets just look for a @XXX.register decorator used by both I guess.
    if node.decorators is not None:
        for dnode in node.decorators.nodes:
            if (isinstance(dnode, astroid.nodes.Name)
                    and dnode.name in ('dispatchmethod', 'singledispatch')):
                return node  # Leave annotations intact.

            if (isinstance(dnode, astroid.nodes.Attribute)
                    and dnode.attrname == 'register'):
                return node  # Leave annotations intact.

    node.args.annotations = [None for _ in node.args.args]
    node.args.varargannotation = None
    node.args.kwargannotation = None
    node.args.kwonlyargs_annotations = [None for _ in node.args.kwonlyargs]
    node.args.posonlyargs_annotations = [None for _ in node.args.kwonlyargs]

    # Wipe out return-value annotation.
    if node.returns is not None:
        node.returns = None

    return node