def register_builtin_transform(transform, builtin_name):
    """Register a new transform function for the given *builtin_name*.

    The transform function must accept two parameters, a node and
    an optional context.
    """
    def _transform_wrapper(node, context=None):
        result = transform(node, context=context)
        if result:
            if not result.parent:
                # Let the transformation function determine
                # the parent for its result. Otherwise,
                # we set it to be the node we transformed from.
                result.parent = node

            if result.lineno is None:
                result.lineno = node.lineno
            # Can be a 'Module' see https://github.com/PyCQA/pylint/issues/4671
            # We don't have a regression test on this one: tread carefully
            if hasattr(result, "col_offset") and result.col_offset is None:
                result.col_offset = node.col_offset
        return iter([result])

    AstroidManager().register_transform(
        nodes.Call,
        inference_tip(_transform_wrapper),
        partial(_builtin_filter_predicate, builtin_name=builtin_name),
    )
Exemple #2
0
    def _initialize_node_visitors(cls, stats, rel_file_path):
        initialized_node_visitors = []
        for (
                node,
                node_visitor_function,
                predicate,
                inferences,
        ) in cls.node_visitor_registry:
            node_visitor_obj = NodeVisitor(stats, rel_file_path)

            if inferences is not None:
                for inference in inferences:
                    node_visitor_obj.register_transform(
                        inference.node,
                        inference_tip(inference.fn),
                        inference.predicate,
                    )

            node_visitor_obj.register_transform(
                node,
                node_visitor_function,
                predicate,
            )
            initialized_node_visitors.append(node_visitor_obj)
        return initialized_node_visitors
def register_builtin_transform(transform, builtin_name):
    """Register a new transform function for the given *builtin_name*.

    The transform function must accept two parameters, a node and
    an optional context.
    """

    def _transform_wrapper(node, context=None):
        result = transform(node, context=context)
        if result:
            if not result.parent:
                # Let the transformation function determine
                # the parent for its result. Otherwise,
                # we set it to be the node we transformed from.
                result.parent = node

            if result.lineno is None:
                result.lineno = node.lineno
            if result.col_offset is None:
                result.col_offset = node.col_offset
        return iter([result])

    MANAGER.register_transform(
        nodes.Call,
        inference_tip(_transform_wrapper),
        partial(_builtin_filter_predicate, builtin_name=builtin_name),
    )
def register_builtin_transform(transform, builtin_name):
    """Register a new transform function for the given *builtin_name*.

    The transform function must accept two parameters, a node and
    an optional context.
    """
    def _transform_wrapper(node, context=None):
        result = transform(node, context=context)
        if result:
            if not result.parent:
                # Let the transformation function determine
                # the parent for its result. Otherwise,
                # we set it to be the node we transformed from.
                result.parent = node

            if result.lineno is None:
                result.lineno = node.lineno
            if result.col_offset is None:
                result.col_offset = node.col_offset
        return iter([result])

    MANAGER.register_transform(
        nodes.Call,
        inference_tip(_transform_wrapper),
        partial(_builtin_filter_predicate, builtin_name=builtin_name),
    )
def use_inferences(*inference_tips):
  transform_args = [(cls.node_class, astroid.inference_tip(cls.infer), cls.filter)
                    for cls in inference_tips]
  for args in transform_args:
    astroid.MANAGER.register_transform(*args)
  yield
  for args in transform_args:
    astroid.MANAGER.unregister_transform(*args)
def register_builtin_transform(transform, builtin_name):
    """Register a new transform function for the given *builtin_name*.

    The transform function must accept two parameters, a node and
    an optional context.
    """
    def _transform_wrapper(node, context=None):
        result = transform(node, context=context)
        if result:
            result.parent = node
            result.lineno = node.lineno
            result.col_offset = node.col_offset
        return iter([result])

    MANAGER.register_transform(
        nodes.CallFunc, inference_tip(_transform_wrapper), lambda n:
        (isinstance(n.func, nodes.Name) and n.func.name == builtin_name))
def register_builtin_transform(transform, builtin_name):
    """Register a new transform function for the given *builtin_name*.

    The transform function must accept two parameters, a node and
    an optional context.
    """
    def _transform_wrapper(node, context=None):
        result = transform(node, context=context)
        if result:
            result.parent = node
            result.lineno = node.lineno
            result.col_offset = node.col_offset
        return iter([result])

    MANAGER.register_transform(nodes.CallFunc,
                               inference_tip(_transform_wrapper),
                               lambda n: (isinstance(n.func, nodes.Name) and
                                          n.func.name == builtin_name))
Exemple #8
0
    def test_deprecated_no_qname_on_unexpected_nodes(self) -> None:
        """Test that we don't crash on nodes which don't have a qname method.

        While this test might seem weird since it uses a transform, it's actually testing a crash
        that happened in production, but there was no way to retrieve the code for which this
        occurred (how an AssignAttr got to be the result of a function inference beats me..)"""
        def infer_func(
            node: Name,
            context: Optional[Any] = None
        ) -> Iterator[Union[Iterator, Iterator[AssignAttr]]]:  # pylint: disable=unused-argument
            new_node = nodes.AssignAttr(attrname="alpha", parent=node)
            yield new_node

        manager = astroid.MANAGER
        transform = astroid.inference_tip(infer_func)
        with _add_transform(manager, nodes.Name, transform):
            node = astroid.extract_node("""
            call_something()
            """)
            with self.assertNoMessages():
                self.checker.visit_call(node)
Exemple #9
0
    def test_deprecated_no_qname_on_unexpected_nodes(self):
        # Test that we don't crash on nodes which don't have
        # a qname method. While this test might seem weird since
        # it uses a transform, it's actually testing a crash that
        # happened in production, but there was no way to retrieve
        # the code for which this occurred (how an AssignAttr
        # got to be the result of a function inference
        # beats me..)

        def infer_func(node, context=None):  # pylint: disable=unused-argument
            new_node = astroid.AssignAttr()
            new_node.parent = node
            yield new_node

        manager = astroid.MANAGER
        transform = astroid.inference_tip(infer_func)
        with _add_transform(manager, astroid.Name, transform):
            node = astroid.extract_node("""
            call_something()
            """)
            with self.assertNoMessages():
                self.checker.visit_call(node)
    def test_deprecated_no_qname_on_unexpected_nodes(self):
        # Test that we don't crash on nodes which don't have
        # a qname method. While this test might seem weird since
        # it uses a transform, it's actually testing a crash that
        # happened in production, but there was no way to retrieve
        # the code for which this occurred (how an AssignAttr
        # got to be the result of a function inference
        # beats me..)

        def infer_func(node, context=None):
            new_node = astroid.AssignAttr()
            new_node.parent = node
            yield new_node

        manager = astroid.MANAGER
        transform = astroid.inference_tip(infer_func)
        with _add_transform(manager, astroid.Name, transform):
            node = astroid.extract_node('''
            call_something()
            ''')
            with self.assertNoMessages():
                self.checker.visit_call(node)
        if _looks_like_functools_member(decorator, "lru_cache"):
            return True
    return False


def _looks_like_functools_member(node, member):
    """Check if the given Call node is a functools.partial call"""
    if isinstance(node.func, astroid.Name):
        return node.func.name == member
    elif isinstance(node.func, astroid.Attribute):
        return (
            node.func.attrname == member
            and isinstance(node.func.expr, astroid.Name)
            and node.func.expr.name == "functools"
        )


_looks_like_partial = partial(_looks_like_functools_member, member="partial")


MANAGER.register_transform(
    astroid.FunctionDef, _transform_lru_cache, _looks_like_lru_cache
)


MANAGER.register_transform(
    astroid.Call,
    astroid.inference_tip(_functools_partial_inference),
    _looks_like_partial,
)
        except InferenceError:
            raise UseInferenceDefault
        try:
            mro_type = next(node.args[1].infer(context=context))
        except InferenceError:
            raise UseInferenceDefault

    if mro_pointer is YES or mro_type is YES:
        # No way we could understand this.
        raise UseInferenceDefault

    super_obj = objects.Super(mro_pointer=mro_pointer,
                              mro_type=mro_type,
                              self_class=cls,
                              scope=scope)
    super_obj.parent = node
    return iter([super_obj])


# Builtins inference
MANAGER.register_transform(nodes.Call,
                           inference_tip(infer_super),
                           lambda n: (isinstance(n.func, nodes.Name) and
                                      n.func.name == 'super'))

register_builtin_transform(infer_tuple, 'tuple')
register_builtin_transform(infer_set, 'set')
register_builtin_transform(infer_list, 'list')
register_builtin_transform(infer_dict, 'dict')
register_builtin_transform(infer_frozenset, 'frozenset')
    return _build_dict_with_elements([])


# Builtins inference
register_builtin_transform(infer_bool, "bool")
register_builtin_transform(infer_super, "super")
register_builtin_transform(infer_callable, "callable")
register_builtin_transform(infer_property, "property")
register_builtin_transform(infer_getattr, "getattr")
register_builtin_transform(infer_hasattr, "hasattr")
register_builtin_transform(infer_tuple, "tuple")
register_builtin_transform(infer_set, "set")
register_builtin_transform(infer_list, "list")
register_builtin_transform(infer_dict, "dict")
register_builtin_transform(infer_frozenset, "frozenset")
register_builtin_transform(infer_type, "type")
register_builtin_transform(infer_slice, "slice")
register_builtin_transform(infer_isinstance, "isinstance")
register_builtin_transform(infer_issubclass, "issubclass")
register_builtin_transform(infer_len, "len")
register_builtin_transform(infer_str, "str")
register_builtin_transform(infer_int, "int")
register_builtin_transform(infer_dict_fromkeys, "dict.fromkeys")

# Infer object.__new__ calls
MANAGER.register_transform(
    nodes.ClassDef,
    inference_tip(_infer_object__new__decorator),
    _infer_object__new__decorator_check,
)
Exemple #14
0
        return node.name == "type"
    return False


def infer_type_sub(node, context=None):
    """
    Infer a type[...] subscript

    :param node: node to infer
    :type node: astroid.node_classes.NodeNG
    :param context: inference context
    :type context: astroid.context.InferenceContext
    :return: the inferred node
    :rtype: nodes.NodeNG
    """
    node_scope, _ = node.scope().lookup("type")
    if node_scope.qname() != "builtins":
        raise UseInferenceDefault()
    class_src = """
    class type:
        def __class_getitem__(cls, key):
            return cls
     """
    node = extract_node(class_src)
    return node.infer(context=context)


if PY39:
    MANAGER.register_transform(nodes.Name, inference_tip(infer_type_sub),
                               _looks_like_type_subscript)
def infer_arg(node, context=None):
    if not isinstance(node.parent, nodes.Arguments):
        raise UseInferenceDefault()
    if not isinstance(node.parent.parent, nodes.Function):
        raise UseInferenceDefault()

    func = node.parent.parent
    docstring = func.doc
    if docstring is None:
        raise UseInferenceDefault()
    
    doctree = etree.fromstring(publish_doctree(docstring).asdom().toxml())
    field_lists = doctree.findall(".//field_list")
    fields = [f for field_list in field_lists
              for f in field_list.findall('field')]

    if fields:
        for field in fields:
            field_name = field.findall("field_name")[0].text
            field_body = field.findall("field_body")[0].findall("paragraph")[0].text
            
            if field_name == "type %s" % node.name:
                return parse_node(node, context, field_body)
            
    raise UseInferenceDefault()

        
MANAGER.register_transform(nodes.CallFunc, inference_tip(infer_rtype))
MANAGER.register_transform(nodes.AssName, inference_tip(infer_arg))

Exemple #16
0
    # node is a CallFunc node, class name as first argument and generated class
    # attributes as second argument
    if len(node.args) != 2:
        # something weird here, go back to class implementation
        raise UseInferenceDefault()
    # namedtuple list of attributes can be a list of strings or a
    # whitespace-separate string
    try:
        name = node.args[0].value
        try:
            attributes = node.args[1].value.split()
        except AttributeError:
            attributes = [const.value for const in node.args[1].elts]
    except AttributeError:
        raise UseInferenceDefault()
    # we want to return a Class node instance with proper attributes set
    class_node = nodes.Class(name, 'docstring')
    # set base class=tuple
    class_node.bases.append(nodes.Tuple._proxied)
    # XXX add __init__(*attributes) method
    for attr in attributes:
        fake_node = nodes.EmptyNode()
        fake_node.parent = class_node
        class_node.instance_attrs[attr] = [fake_node]
    # we use UseInferenceDefault, we can't be a generator so return an iterator
    return iter([class_node])

MANAGER.register_transform(nodes.CallFunc, inference_tip(infer_named_tuple),
                           AsStringRegexpPredicate('namedtuple', 'func'))

Exemple #17
0
    names = []
    for elt in node.args[1].elts:
        if not isinstance(elt, (nodes.List, nodes.Tuple)):
            raise UseInferenceDefault
        if len(elt.elts) != 2:
            raise UseInferenceDefault
        names.append(elt.elts[0].as_string())

    typename = node.args[0].as_string()
    node = extract_node('namedtuple(%(typename)s, (%(fields)s,)) ' %
        {'typename': typename, 'fields': ",".join(names)})
    return infer_named_tuple(node, context)


MANAGER.register_transform(
    nodes.Call, inference_tip(infer_named_tuple),
    _looks_like_namedtuple,
)
MANAGER.register_transform(
    nodes.Call, inference_tip(infer_enum),
    _looks_like_enum,
)
MANAGER.register_transform(
    nodes.ClassDef, infer_enum_class,
    predicate=lambda cls: any(basename for basename in cls.basenames
                              if basename in ENUM_BASE_NAMES)
)
MANAGER.register_transform(
    nodes.ClassDef,
    inference_tip(infer_typing_namedtuple_class),
    _has_namedtuple_base,
Exemple #18
0
    Match = type(...)
    ```
    """
    return (node.root().name == "re" and isinstance(node.func, nodes.Name)
            and node.func.name == "type"
            and isinstance(node.parent, nodes.Assign)
            and len(node.parent.targets) == 1
            and isinstance(node.parent.targets[0], nodes.AssignName)
            and node.parent.targets[0].name in {"Pattern", "Match"})


def infer_pattern_match(node: nodes.Call,
                        ctx: Optional[context.InferenceContext] = None):
    """Infer re.Pattern and re.Match as classes. For PY39+ add `__class_getitem__`."""
    class_def = nodes.ClassDef(
        name=node.parent.targets[0].name,
        lineno=node.lineno,
        col_offset=node.col_offset,
        parent=node.parent,
    )
    if PY39_PLUS:
        func_to_add = extract_node(CLASS_GETITEM_TEMPLATE)
        class_def.locals["__class_getitem__"] = [func_to_add]
    return iter([class_def])


if PY37_PLUS:
    AstroidManager().register_transform(nodes.Call,
                                        inference_tip(infer_pattern_match),
                                        _looks_like_pattern_or_match)
    # attributes as second argument
    if len(node.args) != 2:
        # something weird here, go back to class implementation
        raise UseInferenceDefault()
    # namedtuple list of attributes can be a list of strings or a
    # whitespace-separate string
    try:
        name = node.args[0].value
        try:
            attributes = node.args[1].value.split()
        except AttributeError:
            attributes = [const.value for const in node.args[1].elts]
    except AttributeError:
        raise UseInferenceDefault()
    # we want to return a Class node instance with proper attributes set
    class_node = nodes.Class(name, "docstring")
    # set base class=tuple
    class_node.bases.append(nodes.Tuple._proxied)
    # XXX add __init__(*attributes) method
    for attr in attributes:
        fake_node = nodes.EmptyNode()
        fake_node.parent = class_node
        class_node.instance_attrs[attr] = [fake_node]
    # we use UseInferenceDefault, we can't be a generator so return an iterator
    return iter([class_node])


MANAGER.register_transform(
    nodes.CallFunc, inference_tip(infer_named_tuple), AsStringRegexpPredicate("namedtuple", "func")
)
        raise astroid.UseInferenceDefault

    try:
        elts = random.sample(inferred_sequence.elts, length.value)
    except ValueError:
        raise astroid.UseInferenceDefault

    new_node = astroid.List(lineno=node.lineno,
                            col_offset=node.col_offset,
                            parent=node.scope())
    new_elts = [
        _clone_node_with_lineno(elt, parent=new_node, lineno=new_node.lineno)
        for elt in elts
    ]
    new_node.postinit(new_elts)
    return iter((new_node, ))


def _looks_like_random_sample(node):
    func = node.func
    if isinstance(func, astroid.Attribute):
        return func.attrname == "sample"
    if isinstance(func, astroid.Name):
        return func.name == "sample"
    return False


MANAGER.register_transform(astroid.Call,
                           astroid.inference_tip(infer_random_sample),
                           _looks_like_random_sample)
    ]
    code = textwrap.dedent('''
    from collections import namedtuple
    namedtuple({typename!r}, {fields!r})
    ''').format(
        typename=node.name,
        fields=",".join(annassigns_fields)
    )
    node = extract_node(code)
    return node.infer(context=context)


def looks_like_typing_namedtuple(node):
    func = node.func
    if isinstance(func, nodes.Attribute):
        return func.attrname == 'NamedTuple'
    if isinstance(func, nodes.Name):
        return func.name == 'NamedTuple'
    return False


MANAGER.register_transform(
    nodes.Call,
    inference_tip(infer_typing_namedtuple),
    looks_like_typing_namedtuple
)
MANAGER.register_transform(
    nodes.ClassDef,
    inference_tip(infer_typing_namedtuple_class)
)
def infer_namespace(node, context=None):
    callsite = arguments.CallSite.from_call(node)
    if not callsite.keyword_arguments:
        # Cannot make sense of it.
        raise UseInferenceDefault()

    class_node = nodes.ClassDef("Namespace", "docstring")
    class_node.parent = node.parent
    for attr in set(callsite.keyword_arguments):
        fake_node = nodes.EmptyNode()
        fake_node.parent = class_node
        fake_node.attrname = attr
        class_node.instance_attrs[attr] = [fake_node]
    return iter((class_node.instantiate_class(),))


def _looks_like_namespace(node):
    func = node.func
    if isinstance(func, nodes.Attribute):
        return (
            func.attrname == "Namespace"
            and isinstance(func.expr, nodes.Name)
            and func.expr.name == "argparse"
        )
    return False


MANAGER.register_transform(
    nodes.Call, inference_tip(infer_namespace), _looks_like_namespace
)
        if not isinstance(elt, (nodes.List, nodes.Tuple)):
            raise UseInferenceDefault
        if len(elt.elts) != 2:
            raise UseInferenceDefault
        names.append(elt.elts[0].as_string())

    typename = node.args[0].as_string()
    node = extract_node(
        "namedtuple(%(typename)s, (%(fields)s,)) "
        % {"typename": typename, "fields": ",".join(names)}
    )
    return infer_named_tuple(node, context)


MANAGER.register_transform(
    nodes.Call, inference_tip(infer_named_tuple), _looks_like_namedtuple
)
MANAGER.register_transform(nodes.Call, inference_tip(infer_enum), _looks_like_enum)
MANAGER.register_transform(
    nodes.ClassDef,
    infer_enum_class,
    predicate=lambda cls: any(
        basename for basename in cls.basenames if basename in ENUM_BASE_NAMES
    ),
)
MANAGER.register_transform(
    nodes.ClassDef, inference_tip(infer_typing_namedtuple_class), _has_namedtuple_base
)
MANAGER.register_transform(
    nodes.Call, inference_tip(infer_typing_namedtuple), _looks_like_typing_namedtuple
)
Exemple #24
0
def infer_namespace(node, context=None):
    callsite = arguments.CallSite.from_call(node, context=context)
    if not callsite.keyword_arguments:
        # Cannot make sense of it.
        raise UseInferenceDefault()

    class_node = nodes.ClassDef("Namespace", "docstring")
    class_node.parent = node.parent
    for attr in set(callsite.keyword_arguments):
        fake_node = nodes.EmptyNode()
        fake_node.parent = class_node
        fake_node.attrname = attr
        class_node.instance_attrs[attr] = [fake_node]
    return iter((class_node.instantiate_class(),))


def _looks_like_namespace(node):
    func = node.func
    if isinstance(func, nodes.Attribute):
        return (
            func.attrname == "Namespace"
            and isinstance(func.expr, nodes.Name)
            and func.expr.name == "argparse"
        )
    return False


MANAGER.register_transform(
    nodes.Call, inference_tip(infer_namespace), _looks_like_namespace
)
Exemple #25
0
        func = next(node.func.infer(context=ctx))
    except (InferenceError, StopIteration) as exc:
        raise UseInferenceDefault from exc
    if (
        not isinstance(func, FunctionDef)
        or func.qname() != "typing.cast"
        or len(node.args) != 2
    ):
        raise UseInferenceDefault

    return node.args[1].infer(context=ctx)


AstroidManager().register_transform(
    Call,
    inference_tip(infer_typing_typevar_or_newtype),
    looks_like_typing_typevar_or_newtype,
)
AstroidManager().register_transform(
    Subscript, inference_tip(infer_typing_attr), _looks_like_typing_subscript
)
AstroidManager().register_transform(
    Call, inference_tip(infer_typing_cast), _looks_like_typing_cast
)

if PY39_PLUS:
    AstroidManager().register_transform(
        FunctionDef, inference_tip(infer_typedDict), _looks_like_typedDict
    )
elif PY38_PLUS:
    AstroidManager().register_transform(
                targets = [stmt.target]

            new_targets = []
            for target in targets:
                # Replace all the assignments with our mocked class.
                classdef = dedent('''
                class %(name)s(%(types)s):
                    @property
                    def value(self):
                        # Not the best return.
                        return None
                    @property
                    def name(self):
                        return %(name)r
                ''' % {'name': target.name, 'types': ', '.join(node.basenames)})
                fake = AstroidBuilder(MANAGER).string_build(classdef)[target.name]
                fake.parent = target.parent
                for method in node.mymethods():
                    fake.locals[method.name] = [method]
                new_targets.append(fake.instantiate_class())
            node.locals[local] = new_targets
        break
    return node


MANAGER.register_transform(nodes.Call, inference_tip(infer_named_tuple),
                           _looks_like_namedtuple)
MANAGER.register_transform(nodes.Call, inference_tip(infer_enum),
                           _looks_like_enum)
MANAGER.register_transform(nodes.ClassDef, infer_enum_class)
Exemple #27
0
    if not isinstance(node.args[1], (List, Tuple)):
        raise UseInferenceDefault

    names = []
    for elt in node.args[1].elts:
        if not isinstance(elt, (List, Tuple)):
            raise UseInferenceDefault
        if len(elt.elts) != 2:
            raise UseInferenceDefault
        names.append(elt.elts[0].as_string())

    typename = node.args[0].as_string()
    node = extract_node('namedtuple(%(typename)s, (%(fields)s,)) ' % {
        'typename': typename,
        'fields': ",".join(names)
    })
    return node.infer(context=context)


def looks_like_typing_namedtuple(node):
    func = node.func
    if isinstance(func, nodes.Attribute):
        return func.attrname == 'NamedTuple'
    if isinstance(func, nodes.Name):
        return func.name == 'NamedTuple'
    return False


MANAGER.register_transform(nodes.Call, inference_tip(infer_typing_namedtuple),
                           looks_like_typing_namedtuple)
        return node.name in TYPING_MEMBERS
    elif isinstance(node, nodes.Attribute):
        return node.attrname in TYPING_MEMBERS
    elif isinstance(node, nodes.Subscript):
        return _looks_like_typing_subscript(node.value)
    return False


def infer_typing_attr(node, context=None):
    """Infer a typing.X[...] subscript"""
    try:
        value = next(node.value.infer())
    except InferenceError as exc:
        raise UseInferenceDefault from exc

    if not value.qname().startswith("typing."):
        raise UseInferenceDefault

    node = extract_node(TYPING_TYPE_TEMPLATE.format(value.qname().split(".")[-1]))
    return node.infer(context=context)


MANAGER.register_transform(
    nodes.Call,
    inference_tip(infer_typing_typevar_or_newtype),
    looks_like_typing_typevar_or_newtype,
)
MANAGER.register_transform(
    nodes.Subscript, inference_tip(infer_typing_attr), _looks_like_typing_subscript
)
Exemple #29
0
    if "id" not in cls.locals:
        cls.locals["id"] = [nodes.ClassDef("id", None)]


def is_model_field(cls: ClassDef) -> bool:
    """
    Guard to apply this transform to Model Fields only
    """
    type_name = "tortoise.fields.base.Field"
    return bool(cls.is_subtype_of(type_name)) and cls.qname() != type_name


def apply_type_shim(cls: ClassDef, _context: Any = None) -> Iterator[ClassDef]:
    """
    Morphs model fields to representative type
    """
    base_nodes: List[ClassDef] = [cls]

    # Use the type inference standard
    try:
        base_nodes.extend(list(cls.getattr("field_type")[0].infer()))
    except AstroidError:
        pass

    return iter(base_nodes)


MANAGER.register_transform(nodes.ClassDef, inference_tip(apply_type_shim),
                           is_model_field)
MANAGER.register_transform(nodes.ClassDef, transform_model, is_model)
Exemple #30
0
from astroid import MANAGER, arguments, nodes, inference_tip, UseInferenceDefault


def infer_namespace(node, context=None):
    callsite = arguments.CallSite.from_call(node, context=context)
    if not callsite.keyword_arguments:
        # Cannot make sense of it.
        raise UseInferenceDefault()

    class_node = nodes.ClassDef("Namespace", "docstring")
    class_node.parent = node.parent
    for attr in set(callsite.keyword_arguments):
        fake_node = nodes.EmptyNode()
        fake_node.parent = class_node
        fake_node.attrname = attr
        class_node.instance_attrs[attr] = [fake_node]
    return iter((class_node.instantiate_class(), ))


def _looks_like_namespace(node):
    func = node.func
    if isinstance(func, nodes.Attribute):
        return (func.attrname == "Namespace"
                and isinstance(func.expr, nodes.Name)
                and func.expr.name == "argparse")
    return False


MANAGER.register_transform(nodes.Call, inference_tip(infer_namespace),
                           _looks_like_namespace)
Exemple #31
0
        return node.attrname in TYPING_MEMBERS
    elif isinstance(node, nodes.Subscript):
        return _looks_like_typing_subscript(node.value)
    return False


def infer_typing_attr(node, context=None):
    """Infer a typing.X[...] subscript"""
    try:
        value = next(node.value.infer())
    except InferenceError as exc:
        raise UseInferenceDefault from exc

    if not value.qname().startswith('typing.'):
        raise UseInferenceDefault

    node = extract_node(TYPING_TYPE_TEMPLATE.format(value.qname().split('.')[-1]))
    return node.infer(context=context)


MANAGER.register_transform(
    nodes.Call,
    inference_tip(infer_typing_typevar_or_newtype),
    looks_like_typing_typevar_or_newtype
)
MANAGER.register_transform(
    nodes.Subscript,
    inference_tip(infer_typing_attr),
    _looks_like_typing_subscript,
)
Exemple #32
0
from astroid import MANAGER, nodes, inference_tip, BRAIN_MODULES_DIR

sys.path.append(BRAIN_MODULES_DIR)
import py2stdlib

logger = logging.getLogger(__name__)  # pylint: disable=invalid-name


def _looks_like_nt_with_defaults(node):
    func = node.func
    if type(func) == nodes.Getattr:  # pylint: disable=unidiomatic-typecheck
        return func.attrname == 'namedtuple_with_defaults'
    elif type(func) == nodes.Name:  # pylint: disable=unidiomatic-typecheck
        return func.name == 'namedtuple_with_defaults'
    return False


def nt_with_defaults_transform(node, *args, **kwargs):
    node.args = node.args[:2]
    return py2stdlib.infer_named_tuple(node, *args, **kwargs)


def register(_linter):
    pass


MANAGER.register_transform(nodes.CallFunc,
                           inference_tip(nt_with_defaults_transform),
                           _looks_like_nt_with_defaults)
        raise astroid.UseInferenceDefault

    try:
        elts = random.sample(inferred_sequence.elts, length.value)
    except ValueError:
        raise astroid.UseInferenceDefault

    new_node = astroid.List(
        lineno=node.lineno, col_offset=node.col_offset, parent=node.scope()
    )
    new_elts = [
        _clone_node_with_lineno(elt, parent=new_node, lineno=new_node.lineno)
        for elt in elts
    ]
    new_node.postinit(new_elts)
    return iter((new_node,))


def _looks_like_random_sample(node):
    func = node.func
    if isinstance(func, astroid.Attribute):
        return func.attrname == "sample"
    if isinstance(func, astroid.Name):
        return func.name == "sample"
    return False


MANAGER.register_transform(
    astroid.Call, astroid.inference_tip(infer_random_sample), _looks_like_random_sample
)
Exemple #34
0
        if not isinstance(decorator, astroid.Call):
            continue

        func = helpers.safe_infer(decorator.func)
        if func in (None, astroid.Uninferable):
            continue

        if isinstance(func, astroid.FunctionDef) and func.qname() == LRU_CACHE:
            return True
    return False


def _looks_like_functools_partial(node):
    """Check if the given Call node is a functools.partial call"""
    if isinstance(node.func, astroid.Name):
        return node.func.name == "partial"
    elif isinstance(node.func, astroid.Attribute):
        return (node.func.attrname == "partial"
                and isinstance(node.func.expr, astroid.Name)
                and node.func.expr.name == "functools")


MANAGER.register_transform(astroid.FunctionDef, _transform_lru_cache,
                           _looks_like_lru_cache)

MANAGER.register_transform(
    astroid.Call,
    astroid.inference_tip(_functools_partial_inference),
    _looks_like_functools_partial,
)
Exemple #35
0
    if not isinstance(klass, ClassDef):
        yield Uninferable
    elif klass.root().name in {
            "typing",
            "_collections_abc",
            "",
    }:  # "" because of synthetic nodes in brain_typing.py
        if klass.name in _INFERABLE_TYPING_TYPES:
            yield klass.instantiate_class()
        else:
            yield Uninferable
    else:
        yield klass.instantiate_class()


if PY37_PLUS:
    AstroidManager().register_transform(ClassDef, dataclass_transform,
                                        is_decorated_with_dataclass)

    AstroidManager().register_transform(
        Call,
        inference_tip(infer_dataclass_field_call, raise_on_overwrite=True),
        _looks_like_dataclass_field_call,
    )

    AstroidManager().register_transform(
        Unknown,
        inference_tip(infer_dataclass_attribute, raise_on_overwrite=True),
        _looks_like_dataclass_attribute,
    )
Exemple #36
0
def add_transforms(manager):
    manager.register_transform(nodes.Class, inference_tip(apply_type_shim), is_model_or_form_field)
        raise UseInferenceDefault

    try:
        func = next(node.func.infer(context=ctx))
    except (InferenceError, StopIteration) as exc:
        raise UseInferenceDefault from exc
    if (not isinstance(func, FunctionDef) or func.qname() != "typing.cast"
            or len(node.args) != 2):
        raise UseInferenceDefault

    return node.args[1].infer(context=ctx)


AstroidManager().register_transform(
    Call,
    inference_tip(infer_typing_typevar_or_newtype),
    looks_like_typing_typevar_or_newtype,
)
AstroidManager().register_transform(Subscript,
                                    inference_tip(infer_typing_attr),
                                    _looks_like_typing_subscript)
AstroidManager().register_transform(Call, inference_tip(infer_typing_cast),
                                    _looks_like_typing_cast)

if PY39_PLUS:
    AstroidManager().register_transform(FunctionDef,
                                        inference_tip(infer_typedDict),
                                        _looks_like_typedDict)
elif PY38_PLUS:
    AstroidManager().register_transform(ClassDef,
                                        inference_tip(infer_old_typedDict),
Exemple #38
0
def add_transform(manager):
    manager.register_transform(nodes.Call, inference_tip(infer_key_classes),
                               is_foreignkey_in_class)
        return node.attrname in TYPING_MEMBERS
    elif isinstance(node, nodes.Subscript):
        return _looks_like_typing_subscript(node.value)
    return False


def infer_typing_attr(node, context=None):
    """Infer a typing.X[...] subscript"""
    try:
        value = next(node.value.infer())
    except InferenceError as exc:
        raise UseInferenceDefault from exc

    if not value.qname().startswith('typing.'):
        raise UseInferenceDefault

    node = extract_node(TYPING_TYPE_TEMPLATE.format(value.qname().split('.')[-1]))
    return node.infer(context=context)


MANAGER.register_transform(
    nodes.Call,
    inference_tip(infer_typing_typevar_or_newtype),
    looks_like_typing_typevar_or_newtype
)
MANAGER.register_transform(
    nodes.Subscript,
    inference_tip(infer_typing_attr),
    _looks_like_typing_subscript,
)
Exemple #40
0
        return node.name in TYPING_MEMBERS
    elif isinstance(node, nodes.Attribute):
        return node.attrname in TYPING_MEMBERS
    elif isinstance(node, nodes.Subscript):
        return _looks_like_typing_subscript(node.value)
    return False


def infer_typing_attr(node, context=None):
    """Infer a typing.X[...] subscript"""
    try:
        value = next(node.value.infer())
    except InferenceError as exc:
        raise UseInferenceDefault from exc

    if not value.qname().startswith("typing."):
        raise UseInferenceDefault

    node = extract_node(TYPING_TYPE_TEMPLATE.format(value.qname().split(".")[-1]))
    return node.infer(context=context)


MANAGER.register_transform(
    nodes.Call,
    inference_tip(infer_typing_typevar_or_newtype),
    looks_like_typing_typevar_or_newtype,
)
MANAGER.register_transform(
    nodes.Subscript, inference_tip(infer_typing_attr), _looks_like_typing_subscript
)
Exemple #41
0
        lineno=node.lineno,
        col_offset=node.col_offset,
        parent=node.scope(),
    )
    new_elts = [
        _clone_node_with_lineno(
            elt,
            parent=new_node,
            lineno=new_node.lineno
        )
        for elt in elts
    ]
    new_node.postinit(new_elts)
    return iter((new_node, ))


def _looks_like_random_sample(node):
    func = node.func
    if isinstance(func, astroid.Attribute):
        return func.attrname == 'sample'
    if isinstance(func, astroid.Name):
        return func.name == 'sample'
    return False


MANAGER.register_transform(
    astroid.Call,
    astroid.inference_tip(infer_random_sample),
    _looks_like_random_sample,
)
Exemple #42
0
        def setfield(self, val, dtype, offset=0): return None
        def setflags(self, write=None, align=None, uic=None): return None
        def sort(self, axis=-1, kind='quicksort', order=None): return None
        def squeeze(self, axis=None): return np.ndarray([0, 0])
        def std(self, axis=None, dtype=None, out=None, ddof=0, keepdims=False): return np.ndarray([0, 0])
        def sum(self, axis=None, dtype=None, out=None, keepdims=False): return np.ndarray([0, 0])
        def swapaxes(self, axis1, axis2): return np.ndarray([0, 0])
        def take(self, indices, axis=None, out=None, mode='raise'): return np.ndarray([0, 0])
        def tobytes(self, order='C'): return b''
        def tofile(self, fid, sep="", format="%s"): return None
        def tolist(self, ): return []
        def tostring(self, order='C'): return b''
        def trace(self, offset=0, axis1=0, axis2=1, dtype=None, out=None): return np.ndarray([0, 0])
        def transpose(self, *axes): return np.ndarray([0, 0])
        def var(self, axis=None, dtype=None, out=None, ddof=0, keepdims=False): return np.ndarray([0, 0])
        def view(self, dtype=None, type=None): return np.ndarray([0, 0])
    """
    node = astroid.extract_node(ndarray)
    return node.infer(context=context)


def _looks_like_numpy_ndarray(node):
    return isinstance(node, astroid.Attribute) and node.attrname == "ndarray"


astroid.MANAGER.register_transform(
    astroid.Attribute,
    astroid.inference_tip(infer_numpy_ndarray),
    _looks_like_numpy_ndarray,
)
Exemple #43
0
    callsite = arguments.CallSite.from_call(node)
    if not callsite.keyword_arguments:
        # Cannot make sense of it.
        raise UseInferenceDefault()

    class_node = nodes.ClassDef('Namespace', 'docstring')
    class_node.parent = node.parent
    for attr in set(callsite.keyword_arguments):
        fake_node = nodes.EmptyNode()
        fake_node.parent = class_node
        fake_node.attrname = attr
        class_node.instance_attrs[attr] = [fake_node]
    return iter((class_node.instantiate_class(), ))


def _looks_like_namespace(node):
    func = node.func
    if isinstance(func, nodes.Attribute):
        return (
            func.attrname == 'Namespace'
            and isinstance(func.expr, nodes.Name)
            and func.expr.name == 'argparse'
        )
    return False


MANAGER.register_transform(
    nodes.Call, inference_tip(infer_namespace),
    _looks_like_namespace,
)
    "array":
    """def array(object, dtype=None, copy=True, order='K', subok=False, ndmin=0):
            return numpy.ndarray([0, 0])""",
    "dot":
    """def dot(a, b, out=None):
            return numpy.ndarray([0, 0])""",
    "empty_like":
    """def empty_like(a, dtype=None, order='K', subok=True):
            return numpy.ndarray((0, 0))""",
    "concatenate":
    """def concatenate(arrays, axis=None, out=None):
            return numpy.ndarray((0, 0))""",
    "where":
    """def where(condition, x=None, y=None):
            return numpy.ndarray([0, 0])""",
    "empty":
    """def empty(shape, dtype=float, order='C'):
            return numpy.ndarray([0, 0])""",
    "zeros":
    """def zeros(shape, dtype=float, order='C'):
            return numpy.ndarray([0, 0])""",
}

for method_name, function_src in METHODS_TO_BE_INFERRED.items():
    inference_function = functools.partial(infer_numpy_member, function_src)
    astroid.MANAGER.register_transform(
        astroid.Attribute,
        astroid.inference_tip(inference_function),
        functools.partial(looks_like_numpy_member, method_name),
    )
def _infer_object__new__decorator(node, context=None):
    if not node.decorators:
        raise UseInferenceDefault

    for decorator in node.decorators.nodes:
        if isinstance(decorator, nodes.Attribute):
            if decorator.as_string() == OBJECT_DUNDER_NEW:
                return iter((node.instantiate_class(),))
    raise UseInferenceDefault


# Builtins inference
register_builtin_transform(infer_bool, 'bool')
register_builtin_transform(infer_super, 'super')
register_builtin_transform(infer_callable, 'callable')
register_builtin_transform(infer_getattr, 'getattr')
register_builtin_transform(infer_hasattr, 'hasattr')
register_builtin_transform(infer_tuple, 'tuple')
register_builtin_transform(infer_set, 'set')
register_builtin_transform(infer_list, 'list')
register_builtin_transform(infer_dict, 'dict')
register_builtin_transform(infer_frozenset, 'frozenset')
register_builtin_transform(infer_type, 'type')
register_builtin_transform(infer_slice, 'slice')

# Infer object.__new__ calls
MANAGER.register_transform(
    nodes.ClassDef,
    inference_tip(_infer_object__new__decorator)
)
Exemple #46
0
            raise UseInferenceDefault
        if len(elt.elts) != 2:
            raise UseInferenceDefault
        names.append(elt.elts[0].as_string())

    typename = node.args[0].as_string()
    if names:
        field_names = "({},)".format(",".join(names))
    else:
        field_names = "''"
    node = extract_node("namedtuple({typename}, {fields})".format(
        typename=typename, fields=field_names))
    return infer_named_tuple(node, context)


MANAGER.register_transform(nodes.Call, inference_tip(infer_named_tuple),
                           _looks_like_namedtuple)
MANAGER.register_transform(nodes.Call, inference_tip(infer_enum),
                           _looks_like_enum)
MANAGER.register_transform(
    nodes.ClassDef,
    infer_enum_class,
    predicate=lambda cls: any(basename for basename in cls.basenames
                              if basename in ENUM_BASE_NAMES),
)
MANAGER.register_transform(nodes.ClassDef,
                           inference_tip(infer_typing_namedtuple_class),
                           _has_namedtuple_base)
MANAGER.register_transform(nodes.Call, inference_tip(infer_typing_namedtuple),
                           _looks_like_typing_namedtuple)
            raise UseInferenceDefault
        names.append(elt.elts[0].as_string())

    typename = node.args[0].as_string()
    if names:
        field_names = "({},)".format(",".join(names))
    else:
        field_names = "''"
    node = extract_node(
        "namedtuple({typename}, {fields})".format(typename=typename, fields=field_names)
    )
    return infer_named_tuple(node, context)


MANAGER.register_transform(
    nodes.Call, inference_tip(infer_named_tuple), _looks_like_namedtuple
)
MANAGER.register_transform(nodes.Call, inference_tip(infer_enum), _looks_like_enum)
MANAGER.register_transform(
    nodes.ClassDef,
    infer_enum_class,
    predicate=lambda cls: any(
        basename for basename in cls.basenames if basename in ENUM_BASE_NAMES
    ),
)
MANAGER.register_transform(
    nodes.ClassDef, inference_tip(infer_typing_namedtuple_class), _has_namedtuple_base
)
MANAGER.register_transform(
    nodes.Call, inference_tip(infer_typing_namedtuple), _looks_like_typing_namedtuple
)
Exemple #48
0
    Pattern = type(...)
    Match = type(...)
    ```
    """
    return (node.root().name == "re" and isinstance(node.func, nodes.Name)
            and node.func.name == "type"
            and isinstance(node.parent, nodes.Assign)
            and len(node.parent.targets) == 1
            and isinstance(node.parent.targets[0], nodes.AssignName)
            and node.parent.targets[0].name in ("Pattern", "Match"))


def infer_pattern_match(node: nodes.Call,
                        ctx: context.InferenceContext = None):
    """Infer re.Pattern and re.Match as classes. For PY39+ add `__class_getitem__`."""
    class_def = nodes.ClassDef(
        name=node.parent.targets[0].name,
        lineno=node.lineno,
        col_offset=node.col_offset,
        parent=node.parent,
    )
    if PY39:
        func_to_add = astroid.extract_node(CLASS_GETITEM_TEMPLATE)
        class_def.locals["__class_getitem__"] = [func_to_add]
    return iter([class_def])


if PY37:
    MANAGER.register_transform(nodes.Call, inference_tip(infer_pattern_match),
                               _looks_like_pattern_or_match)
Exemple #49
0
def add_transform(manager):
    manager.register_transform(nodes.CallFunc, inference_tip(infer_key_classes),
                               is_foreignkey_in_class)