コード例 #1
0
def with_assigned_stmts(self, node=None, context=None, asspath=None):
    """Infer names and other nodes from a *with* statement.

    This enables only inference for name binding in a *with* statement.
    For instance, in the following code, inferring `func` will return
    the `ContextManager` class, not whatever ``__enter__`` returns.
    We are doing this intentionally, because we consider that the context
    manager result is whatever __enter__ returns and what it is binded
    using the ``as`` keyword.

        class ContextManager(object):
            def __enter__(self):
                return 42
        with ContextManager() as f:
            pass
        # ContextManager().infer() will return ContextManager
        # f.infer() will return 42.

    Arguments:
        self: nodes.With
        node: The target of the assignment, `as (a, b)` in `with foo as (a, b)`.
        context: TODO
        asspath: TODO
    """
    mgr = next(mgr for (mgr, vars) in self.items if vars == node)
    if asspath is None:
        for result in _infer_context_manager(self, mgr, context):
            yield result
    else:
        for result in _infer_context_manager(self, mgr, context):
            # Walk the asspath and get the item at the final index.
            obj = result
            for index in asspath:
                if not hasattr(obj, 'elts'):
                    raise exceptions.InferenceError(
                        'Wrong type ({targets!r}) for {node!r} assignment',
                        node=self,
                        targets=node,
                        assign_path=asspath,
                        context=context)
                try:
                    obj = obj.elts[index]
                except IndexError:
                    util.reraise(
                        exceptions.InferenceError(
                            'Tried to infer a nonexistent target with index {index} '
                            'in {node!r}.',
                            node=self,
                            targets=node,
                            assign_path=asspath,
                            context=context))
            yield obj
    # Explicit StopIteration to return error information, see comment
    # in raise_if_nothing_inferred.
    raise StopIteration(
        dict(node=self, unknown=node, assign_path=asspath, context=context))
コード例 #2
0
ファイル: inference.py プロジェクト: Gilles00/todobackend
def infer_global(self, context=None):
    if context.lookupname is None:
        raise exceptions.InferenceError(node=self, context=context)
    try:
        return bases._infer_stmts(self.root().getattr(context.lookupname),
                                  context)
    except exceptions.AttributeInferenceError as error:
        util.reraise(exceptions.InferenceError(
            error.message, target=self, attribute=context.lookupname,
            context=context))
コード例 #3
0
ファイル: inference.py プロジェクト: PolPasop/ec-cor-survey
def infer_subscript(self, context=None):
    """Inference for subscripts

    We're understanding if the index is a Const
    or a slice, passing the result of inference
    to the value's `getitem` method, which should
    handle each supported index type accordingly.
    """

    found_one = False
    for value in self.value.infer(context):
        if value is util.Uninferable:
            yield util.Uninferable
            return None
        for index in self.slice.infer(context):
            if index is util.Uninferable:
                yield util.Uninferable
                return None

            # Try to deduce the index value.
            index_value = _SUBSCRIPT_SENTINEL
            if value.__class__ == bases.Instance:
                index_value = index
            elif index.__class__ == bases.Instance:
                instance_as_index = helpers.class_instance_as_index(index)
                if instance_as_index:
                    index_value = instance_as_index
            else:
                index_value = index

            if index_value is _SUBSCRIPT_SENTINEL:
                raise exceptions.InferenceError(node=self, context=context)

            try:
                assigned = value.getitem(index_value, context)
            except (
                    exceptions.AstroidTypeError,
                    exceptions.AstroidIndexError,
                    exceptions.AttributeInferenceError,
                    AttributeError,
            ) as exc:
                raise exceptions.InferenceError(node=self,
                                                context=context) from exc

            # Prevent inferring if the inferred subscript
            # is the same as the original subscripted object.
            if self is assigned or assigned is util.Uninferable:
                yield util.Uninferable
                return None
            yield from assigned.infer(context)
            found_one = True

    if found_one:
        return dict(node=self, context=context)
    return None
コード例 #4
0
ファイル: inference.py プロジェクト: Gilles00/todobackend
def infer_subscript(self, context=None):
    """Inference for subscripts

    We're understanding if the index is a Const
    or a slice, passing the result of inference
    to the value's `getitem` method, which should
    handle each supported index type accordingly.
    """

    value = next(self.value.infer(context))
    if value is util.Uninferable:
        yield util.Uninferable
        return

    index = next(self.slice.infer(context))
    if index is util.Uninferable:
        yield util.Uninferable
        return

    # Try to deduce the index value.
    index_value = _SUBSCRIPT_SENTINEL
    if value.__class__ == bases.Instance:
        index_value = index
    else:
        if index.__class__ == bases.Instance:
            instance_as_index = helpers.class_instance_as_index(index)
            if instance_as_index:
                index_value = instance_as_index
        else:
            index_value = index
    if index_value is _SUBSCRIPT_SENTINEL:
        raise exceptions.InferenceError(node=self, context=context)

    try:
        assigned = value.getitem(index_value, context)
    except (exceptions.AstroidTypeError,
            exceptions.AstroidIndexError,
            exceptions.AttributeInferenceError,
            AttributeError) as exc:
        util.reraise(exceptions.InferenceError(node=self, error=exc,
                                               context=context))

    # Prevent inferring if the inferred subscript
    # is the same as the original subscripted object.
    if self is assigned or assigned is util.Uninferable:
        yield util.Uninferable
        return
    for inferred in assigned.infer(context):
        yield inferred

    # Explicit StopIteration to return error information, see comment
    # in raise_if_nothing_inferred.
    raise StopIteration(dict(node=self, context=context))
コード例 #5
0
ファイル: protocols.py プロジェクト: Andrewou2010/webview
def starred_assigned_stmts(self, node=None, context=None, asspath=None):
    stmt = self.statement()
    if not isinstance(stmt, (nodes.Assign, nodes.For)):
        raise exceptions.InferenceError()

    if isinstance(stmt, nodes.Assign):
        value = stmt.value
        lhs = stmt.targets[0]

        if sum(1 for node in lhs.nodes_of_class(nodes.Starred)) > 1:
            # Too many starred arguments in the expression.
            raise exceptions.InferenceError()

        if context is None:
            context = contextmod.InferenceContext()
        try:
            rhs = next(value.infer(context))
        except exceptions.InferenceError:
            yield util.YES
            return
        if rhs is util.YES or not hasattr(rhs, 'elts'):
            # Not interested in inferred values without elts.
            yield util.YES
            return

        elts = collections.deque(rhs.elts[:])
        if len(lhs.elts) > len(rhs.elts):
            # a, *b, c = (1, 2)
            raise exceptions.InferenceError()

        # Unpack iteratively the values from the rhs of the assignment,
        # until the find the starred node. What will remain will
        # be the list of values which the Starred node will represent
        # This is done in two steps, from left to right to remove
        # anything before the starred node and from right to left
        # to remvoe anything after the starred node.

        for index, node in enumerate(lhs.elts):
            if not isinstance(node, nodes.Starred):
                elts.popleft()
                continue
            lhs_elts = collections.deque(reversed(lhs.elts[index:]))
            for node in lhs_elts:
                if not isinstance(node, nodes.Starred):
                    elts.pop()
                    continue
                # We're done
                packed = nodes.List()
                packed.elts = elts
                packed.parent = self
                yield packed
                break
コード例 #6
0
ファイル: inference.py プロジェクト: PolPasop/ec-cor-survey
def infer_import(self, context=None, asname=True):
    """infer an Import node: return the imported module/object"""
    name = context.lookupname
    if name is None:
        raise exceptions.InferenceError(node=self, context=context)

    try:
        if asname:
            yield self.do_import_module(self.real_name(name))
        else:
            yield self.do_import_module(name)
    except exceptions.AstroidBuildingError as exc:
        raise exceptions.InferenceError(node=self, context=context) from exc
コード例 #7
0
ファイル: decorators.py プロジェクト: Andrew59-boop/pitch
def raise_if_nothing_inferred(func, instance, args, kwargs):
    generator = func(*args, **kwargs)

    try:
        yield next(generator)
    except StopIteration as error:
        # generator is empty
        if error.args:
            # pylint: disable=not-a-mapping
            raise exceptions.InferenceError(**error.args[0])
        raise exceptions.InferenceError(
            "StopIteration raised without any error information.")

    yield from generator
コード例 #8
0
ファイル: helpers.py プロジェクト: Andrew59-boop/pitch
def object_len(node, context=None):
    """Infer length of given node object

    :param Union[nodes.ClassDef, nodes.Instance] node:
    :param node: Node to infer length of

    :raises AstroidTypeError: If an invalid node is returned
        from __len__ method or no __len__ method exists
    :raises InferenceError: If the given node cannot be inferred
        or if multiple nodes are inferred
    :rtype int: Integer length of node
    """
    # pylint: disable=import-outside-toplevel; circular import
    from astroid.objects import FrozenSet

    inferred_node = safe_infer(node, context=context)
    if inferred_node is None or inferred_node is util.Uninferable:
        raise exceptions.InferenceError(node=node)
    if isinstance(inferred_node, nodes.Const) and isinstance(
            inferred_node.value, (bytes, str)):
        return len(inferred_node.value)
    if isinstance(inferred_node,
                  (nodes.List, nodes.Set, nodes.Tuple, FrozenSet)):
        return len(inferred_node.elts)
    if isinstance(inferred_node, nodes.Dict):
        return len(inferred_node.items)

    node_type = object_type(inferred_node, context=context)
    if not node_type:
        raise exceptions.InferenceError(node=node)

    try:
        len_call = next(node_type.igetattr("__len__", context=context))
    except exceptions.AttributeInferenceError:
        raise exceptions.AstroidTypeError(
            "object of type '{}' has no len()".format(node_type.pytype()))

    result_of_len = next(len_call.infer_call_result(node, context))
    if (isinstance(result_of_len, nodes.Const)
            and result_of_len.pytype() == "builtins.int"):
        return result_of_len.value
    if isinstance(
            result_of_len,
            bases.Instance) and result_of_len.is_subtype_of("builtins.int"):
        # Fake a result as we don't know the arguments of the instance call.
        return 0
    raise exceptions.AstroidTypeError(
        "'{}' object cannot be interpreted as an integer".format(
            result_of_len))
コード例 #9
0
def raise_if_nothing_inferred(func, instance, args, kwargs):
    inferred = False
    try:
        generator = func(*args, **kwargs)
        while True:
            yield next(generator)
            inferred = True
    except StopIteration as error:
        if not inferred:
            if error.args:
                # pylint: disable=not-a-mapping
                raise exceptions.InferenceError(**error.args[0])
            else:
                raise exceptions.InferenceError(
                    'StopIteration raised without any error information.')
コード例 #10
0
ファイル: inference.py プロジェクト: EdwinYang2000/ex1
def _infer_seq(node, context=None):
    """Infer all values based on _BaseContainer.elts"""
    values = []

    for elt in node.elts:
        if isinstance(elt, nodes.Starred):
            starred = helpers.safe_infer(elt.value, context)
            if starred in (None, util.Uninferable):
                raise exceptions.InferenceError(node=node, context=context)
            if not hasattr(starred, 'elts'):
                raise exceptions.InferenceError(node=node, context=context)
            values.extend(_infer_seq(starred))
        else:
            values.append(elt)
    return values
コード例 #11
0
ファイル: inference.py プロジェクト: Andrewou2010/webview
def infer_import_from(self, context=None, asname=True):
    """infer a ImportFrom node: return the imported module/object"""
    name = context.lookupname
    if name is None:
        raise exceptions.InferenceError()
    if asname:
        name = self.real_name(name)
    module = self.do_import_module()
    try:
        context = contextmod.copy_context(context)
        context.lookupname = name
        stmts = module.getattr(name, ignore_locals=module is self.root())
        return bases._infer_stmts(stmts, context)
    except exceptions.NotFoundError:
        raise exceptions.InferenceError(name)
コード例 #12
0
    def igetattr(self, name, context=None):
        """inferred getattr"""
        if not context:
            context = contextmod.InferenceContext()
        try:
            # avoid recursively inferring the same attr on the same class
            if context.push((self._proxied, name)):
                return

            # XXX frame should be self._proxied, or not ?
            get_attr = self.getattr(name, context, lookupclass=False)
            for stmt in _infer_stmts(self._wrap_attr(get_attr, context),
                                     context,
                                     frame=self):
                yield stmt
        except exceptions.AttributeInferenceError:
            try:
                # fallback to class.igetattr since it has some logic to handle
                # descriptors
                attrs = self._proxied.igetattr(name,
                                               context,
                                               class_context=False)
                for stmt in self._wrap_attr(attrs, context):
                    yield stmt
            except exceptions.AttributeInferenceError as error:
                util.reraise(exceptions.InferenceError(**vars(error)))
コード例 #13
0
            def infer_call_result(self,
                                  caller,
                                  context=None,
                                  context_lookup=None):
                if len(caller.args) != 2:
                    raise exceptions.InferenceError(
                        "Invalid arguments for descriptor binding",
                        target=self,
                        context=context)

                context = contextmod.copy_context(context)
                cls = next(caller.args[0].infer(context=context))

                # Rebuild the original value, but with the parent set as the
                # class where it will be bound.
                new_func = func.__class__(name=func.name,
                                          doc=func.doc,
                                          lineno=func.lineno,
                                          col_offset=func.col_offset,
                                          parent=cls)
                # pylint: disable=no-member
                new_func.postinit(func.args, func.body, func.decorators,
                                  func.returns)

                # Build a proper bound method that points to our newly built function.
                proxy = bases.UnboundMethod(new_func)
                yield bases.BoundMethod(proxy=proxy, bound=cls)
コード例 #14
0
def _query_stmt(stmt, context, frame=None):
    queried = False
    if context is not None:
        name = context.lookupname
        context = context.clone()
    else:
        name = None
        context = contextmod.InferenenceContext()

    res = []

    if stmt is util.Uninferable:
        assert False
    context.lookupname = stmt._query_name(frame, name)
    try:
        res.extend(stmt.query(context=context))
        queried = True
    except exceptions.NameInferenceError:
        assert False
        # continue
    except exceptions.InferenceError:
        assert False
        # yield util.Uninferable
        # queried = True
        # continue

    if not queried:
        raise exceptions.InferenceError(
            "query failed for all members of {stmt!r}.",
            stmts=stmt,
            frame=frame,
            context=context,
        )
    return res
コード例 #15
0
 def infer_call_result(self, caller=None, context=None):
     nonlocal func_setter
     if caller and len(caller.args) != 2:
         raise exceptions.InferenceError(
             "fset() needs two arguments", target=self, context=context
         )
     yield from func_setter.infer_call_result(caller=caller, context=context)
コード例 #16
0
def _infer_stmts(stmts, context, frame=None):
    """Return an iterator on statements inferred by each statement in *stmts*."""
    stmt = None
    inferred = False
    if context is not None:
        name = context.lookupname
        context = context.clone()
    else:
        name = None
        context = contextmod.InferenceContext()

    for stmt in stmts:
        if stmt is util.YES:
            yield stmt
            inferred = True
            continue
        context.lookupname = stmt._infer_name(frame, name)
        try:
            for inferred in stmt.infer(context=context):
                yield inferred
                inferred = True
        except exceptions.UnresolvableName:
            continue
        except exceptions.InferenceError:
            yield util.YES
            inferred = True
    if not inferred:
        raise exceptions.InferenceError(str(stmt))
コード例 #17
0
def _infer_stmts(stmts, context, frame=None):
    """Return an iterator on statements inferred by each statement in *stmts*."""
    stmt = None
    inferred = False
    if context is not None:
        name = context.lookupname
        context = context.clone()
    else:
        name = None
        context = contextmod.InferenceContext()

    for stmt in stmts:
        if stmt is util.Uninferable:
            yield stmt
            inferred = True
            continue
        context.lookupname = stmt._infer_name(frame, name)
        try:
            for inferred in stmt.infer(context=context):
                yield inferred
                inferred = True
        except exceptions.NameInferenceError:
            continue
        except exceptions.InferenceError:
            yield util.Uninferable
            inferred = True
    if not inferred:
        raise exceptions.InferenceError(
            'Inference failed for all members of {stmts!r}.',
            stmts=stmts,
            frame=frame,
            context=context)
コード例 #18
0
def raise_if_nothing_inferred(func, instance, args, kwargs):
    inferred = False
    for node in func(*args, **kwargs):
        inferred = True
        yield node
    if not inferred:
        raise exceptions.InferenceError()
コード例 #19
0
 def infer_call_result(self, caller, context=None):
     if len(caller.args) > 2 or len(caller.args) < 1:
         raise exceptions.InferenceError(
             "Invalid arguments for descriptor binding",
             target=self,
             context=context,
         )
コード例 #20
0
def _infer_context_manager(self, mgr, context):
    inferred = next(mgr.infer(context=context))
    if isinstance(inferred, bases.Generator):
        # Check if it is decorated with contextlib.contextmanager.
        func = inferred.parent
        if not func.decorators:
            raise exceptions.InferenceError(
                "No decorators found on inferred generator %s", node=func
            )

        for decorator_node in func.decorators.nodes:
            decorator = next(decorator_node.infer(context))
            if isinstance(decorator, nodes.FunctionDef):
                if decorator.qname() == _CONTEXTLIB_MGR:
                    break
        else:
            # It doesn't interest us.
            raise exceptions.InferenceError(node=func)

        # Get the first yield point. If it has multiple yields,
        # then a RuntimeError will be raised.

        possible_yield_points = func.nodes_of_class(nodes.Yield)
        # Ignore yields in nested functions
        yield_point = next(
            (node for node in possible_yield_points if node.scope() == func), None
        )
        if yield_point:
            if not yield_point.value:
                const = nodes.Const(None)
                const.parent = yield_point
                const.lineno = yield_point.lineno
                yield const
            else:
                yield from yield_point.value.infer(context=context)
    elif isinstance(inferred, bases.Instance):
        try:
            enter = next(inferred.igetattr("__enter__", context=context))
        except (exceptions.InferenceError, exceptions.AttributeInferenceError):
            raise exceptions.InferenceError(node=inferred)
        if not isinstance(enter, bases.BoundMethod):
            raise exceptions.InferenceError(node=enter)
        if not context.callcontext:
            context.callcontext = contextmod.CallContext(args=[inferred])
        yield from enter.infer_call_result(self, context)
    else:
        raise exceptions.InferenceError(node=mgr)
コード例 #21
0
ファイル: inference.py プロジェクト: Andrewou2010/webview
def infer_import(self, context=None, asname=True):
    """infer an Import node: return the imported module/object"""
    name = context.lookupname
    if name is None:
        raise exceptions.InferenceError()
    if asname:
        yield self.do_import_module(self.real_name(name))
    else:
        yield self.do_import_module(name)
コード例 #22
0
ファイル: inference.py プロジェクト: EdwinYang2000/ex1
def _infer_map(node, context):
    """Infer all values based on Dict.items"""
    values = {}
    for name, value in node.items:
        if isinstance(name, nodes.DictUnpack):
            double_starred = helpers.safe_infer(value, context)
            if double_starred in (None, util.Uninferable):
                raise exceptions.InferenceError
            if not isinstance(double_starred, nodes.Dict):
                raise exceptions.InferenceError(node=node, context=context)
            values.update(_infer_map(double_starred, context))
        else:
            key = helpers.safe_infer(name, context=context)
            value = helpers.safe_infer(value, context=context)
            if key is None or value is None:
                raise exceptions.InferenceError(node=node, context=context)
            values[key] = value
    return values
コード例 #23
0
ファイル: objectmodel.py プロジェクト: Andrew59-boop/pitch
            def infer_call_result(self, caller=None, context=None):
                nonlocal func
                if caller and len(caller.args) != 1:
                    raise exceptions.InferenceError(
                        "fget() needs a single argument",
                        target=self,
                        context=context)

                yield from func.function.infer_call_result(caller=caller,
                                                           context=context)
コード例 #24
0
ファイル: inference.py プロジェクト: PolPasop/ec-cor-survey
def _infer_map(node, context):
    """Infer all values based on Dict.items"""
    values = {}
    for name, value in node.items:
        if isinstance(name, nodes.DictUnpack):
            double_starred = helpers.safe_infer(value, context)
            if not double_starred:
                raise exceptions.InferenceError
            if not isinstance(double_starred, nodes.Dict):
                raise exceptions.InferenceError(node=node, context=context)
            unpack_items = _infer_map(double_starred, context)
            values = _update_with_replacement(values, unpack_items)
        else:
            key = helpers.safe_infer(name, context=context)
            value = helpers.safe_infer(value, context=context)
            if any(not elem for elem in (key, value)):
                raise exceptions.InferenceError(node=node, context=context)
            values = _update_with_replacement(values, {key: value})
    return values
コード例 #25
0
def raise_if_nothing_inferred(func, instance, args, kwargs):
    """All generators wrapped with raise_if_nothing_inferred *must*
    explicitly raise StopIteration with information to create an
    appropriate structured InferenceError.
    """
    inferred = False
    try:
        generator = func(*args, **kwargs)
        while True:
            yield next(generator)
            inferred = True
    except StopIteration as error:
        if not inferred:
            if error.args:
                # pylint: disable=not-a-mapping
                raise exceptions.InferenceError(**error.args[0])
            else:
                raise exceptions.InferenceError(
                    'StopIteration raised without any error information.')
コード例 #26
0
ファイル: helpers.py プロジェクト: wogsland/astroid
def object_len(node, context=None):
    """Infer length of given node object

    :param Union[nodes.ClassDef, nodes.Instance] node:
    :param node: Node to infer length of

    :raises AstroidTypeError: If an invalid node is returned
        from __len__ method or no __len__ method exists
    :raises InferenceError: If the given node cannot be inferred
        or if multiple nodes are inferred
    :rtype int: Integer length of node
    """
    from astroid.objects import FrozenSet
    inferred_node = safe_infer(node, context=context)
    if inferred_node is None or inferred_node is util.Uninferable:
        raise exceptions.InferenceError(node=node)
    if (isinstance(inferred_node, nodes.Const)
            and isinstance(inferred_node.value, (bytes, str))):
        return len(inferred_node.value)
    if isinstance(inferred_node,
                  (nodes.List, nodes.Set, nodes.Tuple, FrozenSet)):
        return len(inferred_node.elts)
    if isinstance(inferred_node, nodes.Dict):
        return len(inferred_node.items)
    try:
        node_type = object_type(inferred_node, context=context)
        len_call = next(node_type.igetattr("__len__", context=context))
    except exceptions.AttributeInferenceError:
        raise exceptions.AstroidTypeError(
            "object of type '{}' has no len()".format(len_call.pytype()))

    try:
        result_of_len = next(len_call.infer_call_result(node, context))
        # Remove StopIteration catch when #507 is fixed
    except StopIteration:
        raise exceptions.InferenceError(node=node)
    if (isinstance(result_of_len, nodes.Const)
            and result_of_len.pytype() == "builtins.int"):
        return result_of_len.value
    else:
        raise exceptions.AstroidTypeError(
            "'{}' object cannot be interpreted as an integer".format(
                result_of_len))
コード例 #27
0
def infer_import_from(self, context=None, asname=True):
    """infer a ImportFrom node: return the imported module/object"""
    name = context.lookupname
    if name is None:
        raise exceptions.InferenceError(node=self, context=context)
    if asname:
        name = self.real_name(name)

    try:
        module = se# -*- coding: utf-8 -*-
コード例 #28
0
 def infer_call_result(self, caller, context=None):
     """infer what a class instance is returning when called"""
     inferred = False
     for node in self._proxied.igetattr('__call__', context):
         if node is util.YES or not node.callable():
             continue
         for res in node.infer_call_result(caller, context):
             inferred = True
             yield res
     if not inferred:
         raise exceptions.InferenceError()
コード例 #29
0
ファイル: inference.py プロジェクト: PolPasop/ec-cor-survey
def _infer_sequence_helper(node, context=None):
    """Infer all values based on _BaseContainer.elts"""
    values = []

    for elt in node.elts:
        if isinstance(elt, nodes.Starred):
            starred = helpers.safe_infer(elt.value, context)
            if not starred:
                raise exceptions.InferenceError(node=node, context=context)
            if not hasattr(starred, "elts"):
                raise exceptions.InferenceError(node=node, context=context)
            values.extend(_infer_sequence_helper(starred))
        elif isinstance(elt, nodes.NamedExpr):
            value = helpers.safe_infer(elt.value, context)
            if not value:
                raise exceptions.InferenceError(node=node, context=context)
            values.append(value)
        else:
            values.append(elt)
    return values
コード例 #30
0
def named_expr_assigned_stmts(self, node, context=None, assign_path=None):
    """Infer names and other nodes from an assignment expression"""
    if self.target == node:
        yield from self.value.infer(context=context)
    else:
        raise exceptions.InferenceError(
            "Cannot infer NamedExpr node {node!r}",
            node=self,
            assign_path=assign_path,
            context=context,
        )