Ejemplo n.º 1
0
 def _eval_atom(self, atom):
     """
     Basically to process ``atom`` nodes. The parser sometimes doesn't
     generate the node (because it has just one child). In that case an atom
     might be a name or a literal as well.
     """
     if isinstance(atom, pr.Name):
         # This is the first global lookup.
         stmt = atom.get_definition()
         scope = stmt.get_parent_until(pr.IsScope, include_current=True)
         if isinstance(stmt, pr.CompFor):
             stmt = stmt.get_parent_until((pr.ClassOrFunc, pr.ExprStmt))
         if stmt.type != 'expr_stmt':
             # We only need to adjust the start_pos for statements, because
             # there the name cannot be used.
             stmt = atom
         return self.find_types(scope, atom, stmt.start_pos, search_global=True)
     elif isinstance(atom, pr.Literal):
         return [compiled.create(self, atom.eval())]
     else:
         c = atom.children
         # Parentheses without commas are not tuples.
         if c[0] == '(' and not len(c) == 2 \
                 and not(pr.is_node(c[1], 'testlist_comp')
                         and len(c[1].children) > 1):
             return self.eval_element(c[1])
         try:
             comp_for = c[1].children[1]
         except (IndexError, AttributeError):
             pass
         else:
             if isinstance(comp_for, pr.CompFor):
                 return [iterable.Comprehension.from_atom(self, atom)]
         return [iterable.Array(self, atom)]
Ejemplo n.º 2
0
    def _eval_atom(self, atom):
        """
        Basically to process ``atom`` nodes. The parser sometimes doesn't
        generate the node (because it has just one child). In that case an atom
        might be a name or a literal as well.
        """
        if isinstance(atom, tree.Name):
            # This is the first global lookup.
            stmt = atom.get_definition()
            scope = stmt.get_parent_until(tree.IsScope, include_current=True)
            if isinstance(scope, (tree.Function, er.FunctionExecution)):
                # Adjust scope: If the name is not in the suite, it's a param
                # default or annotation and will be resolved as part of the
                # parent scope.
                colon = scope.children.index(':')
                if atom.start_pos < scope.children[colon + 1].start_pos:
                    scope = scope.get_parent_scope()
            if isinstance(stmt, tree.CompFor):
                stmt = stmt.get_parent_until((tree.ClassOrFunc, tree.ExprStmt))
            if stmt.type != 'expr_stmt':
                # We only need to adjust the start_pos for statements, because
                # there the name cannot be used.
                stmt = atom
            return self.find_types(scope,
                                   atom,
                                   stmt.start_pos,
                                   search_global=True)
        elif isinstance(atom, tree.Literal):
            return set([compiled.create(self, atom.eval())])
        else:
            c = atom.children
            if c[0].type == 'string':
                # Will be one string.
                types = self._eval_atom(c[0])
                for string in c[1:]:
                    right = self._eval_atom(string)
                    types = precedence.calculate(self, types, '+', right)
                return types
            # Parentheses without commas are not tuples.
            elif c[0] == '(' and not len(c) == 2 \
                    and not(tree.is_node(c[1], 'testlist_comp')
                            and len(c[1].children) > 1):
                return self.eval_element(c[1])

            try:
                comp_for = c[1].children[1]
            except (IndexError, AttributeError):
                pass
            else:
                if comp_for == ':':
                    # Dict comprehensions have a colon at the 3rd index.
                    try:
                        comp_for = c[1].children[3]
                    except IndexError:
                        pass

                if comp_for.type == 'comp_for':
                    return set([iterable.Comprehension.from_atom(self, atom)])
            return set([iterable.Array(self, atom)])
Ejemplo n.º 3
0
def builtins_reversed(evaluator, obj, params):
    objects = tuple(_follow_param(evaluator, params, 0))
    if objects:
        # unpack the iterator values
        objects = tuple(iterable.get_iterator_types(objects))
        if objects:
            rev = reversed(objects)
            # Repack iterator values and then run it the normal way. This is
            # necessary, because `reversed` is a function and autocompletion
            # would fail in certain cases like `reversed(x).__iter__` if we
            # just returned the result directly.
            stmts = [FakeStatement([r]) for r in rev]
            objects = (iterable.Array(evaluator, FakeArray(stmts, objects[0].parent)),)
    return [er.Instance(evaluator, obj, objects)]
Ejemplo n.º 4
0
    def eval_call_path(self, path, scope, position):
        """
        Follows a path generated by `pr.StatementElement.generate_call_path()`.
        """
        current = next(path)

        if isinstance(current, pr.Array):
            types = [iterable.Array(self, current)]
        else:
            if isinstance(current, pr.NamePart):
                # This is the first global lookup.
                types = self.find_types(scope, current, position=position,
                                        search_global=True)
            else:
                # for pr.Literal
                types = [compiled.create(self, current.value)]
            types = imports.follow_imports(self, types)

        return self.follow_path(path, types, scope)