예제 #1
0
def infer_subscript(self, context=None):
    """infer simple subscription such as [1,2,3][0] or (1,2,3)[-1]"""
    if isinstance(self.slice, nodes.Index):
        index = self.slice.value.infer(context).next()
        if index is YES:
            yield YES
            return
        try:
            if hasattr(self.value, "getitem"):
                assigned = self.value.getitem(index.value, context)
                for infered in assigned.infer(context):
                    yield infered
                return
            else:
                has_infer_item = False
                for l in self.value.infer():
                    if l is not YES and hasattr(l, "infer_item"):
                        has_infer_item = True
                        for inferred in l.infer_item(index, context):
                            yield inferred
                if not has_infer_item:
                    raise InferenceError()
        except AttributeError:
            raise InferenceError()
        except (IndexError, TypeError):
            yield YES
            return
    else:
        raise InferenceError()
예제 #2
0
def infer_global(self, context=None):
    if context.lookupname is None:
        raise InferenceError()
    try:
        return _infer_stmts(self.root().getattr(context.lookupname), context)
    except NotFoundError:
        raise InferenceError()
def infer_from(self, context=None, asname=True):
    """infer a From nodes: return the imported module/object"""
    name = context.lookupname
    if name is None:
        raise InferenceError()
    if asname:
        name = self.real_name(name)
    module = self.do_import_module(self.modname)
    try:
        context = copy_context(context)
        context.lookupname = name
        return _infer_stmts(module.getattr(name), context)
    except NotFoundError:
        raise InferenceError(name)
예제 #4
0
    def igetattr(self, name, context=None):
        """inferred getattr"""
        if hasattr(self._proxied,
                   "attr_types") and name in self._proxied.attr_types:
            yield self._proxied.attr_types[name]
            return

        found = False

        try:
            # XXX frame should be self._proxied, or not ?
            get_attr = self.getattr(name, context, lookupclass=False)
            for inferred in bases._infer_stmts(self._wrap_attr(
                    get_attr, context),
                                               context,
                                               frame=self):
                yield inferred
            found = True
        except (NotFoundError, InferenceError):
            pass

        try:
            # fallback to class'igetattr since it has some logic to handle
            # descriptors
            for inferred in self._wrap_attr(
                    self._proxied.igetattr(name, context), context):
                yield inferred
            found = True
        except (NotFoundError, InferenceError):
            pass

        if not found:
            raise InferenceError(name)
예제 #5
0
 def wrapper(*args, **kwargs):
     infered = False
     for node in func(*args, **kwargs):
         infered = True
         yield node
     if not infered:
         raise InferenceError()
예제 #6
0
def _infer_stmts(stmts, context, frame=None):
    """return an iterator on statements inferred by each statement in <stmts>
    """
    stmt = None
    infered = False
    if context is not None:
        name = context.lookupname
        context = context.clone()
    else:
        name = None
        context = InferenceContext()
    for stmt in stmts:
        if stmt is YES:
            yield stmt
            infered = True
            continue
        context.lookupname = stmt._infer_name(frame, name)
        try:
            for infered in stmt.infer(context):
                yield infered
                infered = True
        except UnresolvableName:
            continue
        except InferenceError:
            yield YES
            infered = True
    if not infered:
        raise InferenceError(str(stmt))
예제 #7
0
 def igetattr(self, name, context=None):
     """inferred getattr, need special treatment in class to handle
     descriptors
     """
     # set lookup name since this is necessary to infer on import nodes for
     # instance
     context = copy_context(context)
     context.lookupname = name
     try:
         for infered in _infer_stmts(self.getattr(name, context), context,
                                     frame=self):
             # yield YES object instead of descriptors when necessary
             if not isinstance(infered, Const) and isinstance(infered, Instance):
                 try:
                     infered._proxied.getattr('__get__', context)
                 except NotFoundError:
                     yield infered
                 else:
                     yield YES
             else:
                 yield function_to_method(infered, self)
     except NotFoundError:
         if not name.startswith('__') and self.has_dynamic_getattr(context):
             # class handle some dynamic attributes, return a YES object
             yield YES
         else:
             raise InferenceError(name)
예제 #8
0
 def infer_call_result(self, caller, context=None):
     """infer what a class instance is returning when called"""
     infered = False
     for node in self._proxied.igetattr('__call__', context):
         for res in node.infer_call_result(caller, context):
             infered = True
             yield res
     if not infered:
         raise InferenceError()
예제 #9
0
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 InferenceError()
    if asname:
        yield self.do_import_module(self.real_name(name))
    else:
        yield self.do_import_module(name)
예제 #10
0
def infer_subscript(self, context=None):
    """infer simple subscription such as [1,2,3][0] or (1,2,3)[-1]"""
    if isinstance(self.slice, nodes.Index):
        index = self.slice.value.infer(context).next()
        if index is YES:
            yield YES
            return
        try:
            # suppose it's a Tuple/List node (attribute error else)
            assigned = self.value.getitem(index.value, context)
        except AttributeError:
            raise InferenceError()
        except (IndexError, TypeError):
            yield YES
            return
        for infered in assigned.infer(context):
            yield infered
    else:
        raise InferenceError()
예제 #11
0
 def igetattr(self, name, context=None):
     """inferred getattr"""
     # set lookup name since this is necessary to infer on import nodes for
     # instance
     context = copy_context(context)
     context.lookupname = name
     try:
         return _infer_stmts(self.getattr(name, context), context, frame=self)
     except NotFoundError:
         raise InferenceError(name)
예제 #12
0
 def do_import_module(self, modname):
     """return the ast for a module whose name is <modname> imported by <self>
     """
     # handle special case where we are on a package node importing a module
     # using the same name as the package, which may end in an infinite loop
     # on relative imports
     # XXX: no more needed ?
     mymodule = self.root()
     level = getattr(self, 'level', None)  # Import as no level
     # XXX we should investigate deeper if we really want to check
     # importing itself: modname and mymodule.name be relative or absolute
     if mymodule.relative_to_absolute_name(modname, level) == mymodule.name:
         # FIXME: we used to raise InferenceError here, but why ?
         return mymodule
     try:
         return mymodule.import_module(modname, level=level)
     except ASTNGBuildingException:
         raise InferenceError(modname)
     except SyntaxError, ex:
         raise InferenceError(str(ex))
예제 #13
0
def infer_subscript(self, context=None):
    """infer simple subscription such as [1,2,3][0] or (1,2,3)[-1]"""
    value = self.value.infer(context).next()
    if value is YES:
        yield YES
        return

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

    if isinstance(index, nodes.Const):
        try:
            assigned = value.getitem(index.value, context)
        except AttributeError:
            raise InferenceError()
        except (IndexError, TypeError):
            yield YES
            return
        for infered in assigned.infer(context):
            yield infered
    else:
        raise InferenceError()
예제 #14
0
 def igetattr(self, name, context=None):
     """inferred getattr"""
     try:
         # XXX frame should be self._proxied, or not ?
         get_attr = self.getattr(name, context, lookupclass=False)
         return _infer_stmts(self._wrap_attr(get_attr, context),
                             context,
                             frame=self)
     except NotFoundError:
         try:
             # fallback to class'igetattr since it has some logic to handle
             # descriptors
             return self._wrap_attr(self._proxied.igetattr(name, context),
                                    context)
         except NotFoundError:
             raise InferenceError(name)
예제 #15
0
 def interfaces(self, herited=True, handler_func=_iface_hdlr):
     """return an iterator on interfaces implemented by the given
     class node
     """
     # FIXME: what if __implements__ = (MyIFace, MyParent.__implements__)...
     try:
         implements = Instance(self).getattr('__implements__')[0]
     except NotFoundError:
         return
     if not herited and not implements.frame() is self:
         return
     found = set()
     missing = False
     for iface in unpack_infer(implements):
         if iface is YES:
             missing = True
             continue
         if not iface in found and handler_func(iface):
             found.add(iface)
             yield iface
     if missing:
         raise InferenceError()
예제 #16
0
def infer_arguments(self, context=None):
    name = context.lookupname
    if name is None:
        raise InferenceError()
    return _arguments_infer_argname(self, name, context)
예제 #17
0
 def infer(self, context=None):
     """we don't know how to resolve a statement by default"""
     # this method is overridden by most concrete classes
     raise InferenceError(self.__class__.__name__)
예제 #18
0
 def infer_argument(self, funcnode, name, context):
     """infer a function argument value according to the call context"""
     # 1. search in named keywords
     try:
         return self.nargs[name].infer(context)
     except KeyError:
         # Function.args.args can be None in astng (means that we don't have
         # information on argnames)
         argindex = funcnode.args.find_argname(name)[0]
         if argindex is not None:
             # 2. first argument of instance/class method
             if argindex == 0 and funcnode.type in ('method',
                                                    'classmethod'):
                 if context.boundnode is not None:
                     boundnode = context.boundnode
                 else:
                     # XXX can do better ?
                     boundnode = funcnode.parent.frame()
                 if funcnode.type == 'method':
                     if not isinstance(boundnode, Instance):
                         boundnode = Instance(boundnode)
                     return iter((boundnode, ))
                 if funcnode.type == 'classmethod':
                     return iter((boundnode, ))
             # 2. search arg index
             try:
                 return self.args[argindex].infer(context)
             except IndexError:
                 pass
             # 3. search in *args (.starargs)
             if self.starargs is not None:
                 its = []
                 for infered in self.starargs.infer(context):
                     if infered is YES:
                         its.append((YES, ))
                         continue
                     try:
                         its.append(
                             infered.getitem(argindex,
                                             context).infer(context))
                     except (InferenceError, AttributeError):
                         its.append((YES, ))
                     except (IndexError, TypeError):
                         continue
                 if its:
                     return chain(*its)
     # 4. XXX search in **kwargs (.dstarargs)
     if self.dstarargs is not None:
         its = []
         for infered in self.dstarargs.infer(context):
             if infered is YES:
                 its.append((YES, ))
                 continue
             try:
                 its.append(infered.getitem(name, context).infer(context))
             except (InferenceError, AttributeError):
                 its.append((YES, ))
             except (IndexError, TypeError):
                 continue
         if its:
             return chain(*its)
     # 5. */** argument, (Tuple or Dict)
     if name == funcnode.args.vararg:
         return iter((nodes.const_factory(())))
     if name == funcnode.args.kwarg:
         return iter((nodes.const_factory({})))
     # 6. return default value if any
     try:
         return funcnode.args.default_value(name).infer(context)
     except NoDefault:
         raise InferenceError(name)