Ejemplo n.º 1
0
    def make_fakestatement(self, lhs, rhs, call=False):
        """
        Make a fake statement object that represents ``lhs = rhs``.

        :type call: bool
        :arg  call: When `call` is true, make a fake statement that represents
                   ``lhs = rhs()``.

        :rtype: :class:`parsing_representation.Statement`
        """
        submodule = self.scope._sub_module
        lhsname = pr.Name(module=submodule,
                          names=[(lhs, (0, 0))],
                          start_pos=(0, 0),
                          end_pos=(None, None))
        rhsname = pr.Name(module=submodule,
                          names=[(rhs, (0, 0))],
                          start_pos=(0, 0),
                          end_pos=(None, None))
        token_list = [
            lhsname,
            token.Token.from_tuple((tokenize.OP, '=', (0, 0))), rhsname
        ]
        if call:
            token_list.extend([
                token.Token.from_tuple((tokenize.OP, '(', (0, 0))),
                token.Token.from_tuple((tokenize.OP, ')', (0, 0))),
            ])
        return pr.Statement(module=submodule,
                            token_list=token_list,
                            start_pos=(0, 0),
                            end_pos=(None, None))
Ejemplo n.º 2
0
    def make_fakeimport(self, module, variable=None, alias=None):
        """
        Make a fake import object.

        The following statements are created depending on what parameters
        are given:

        - only `module`: ``import <module>``
        - `module` and `variable`: ``from <module> import <variable>``
        - all: ``from <module> import <variable> as <alias>``

        :type   module: str
        :arg    module: ``<module>`` part in ``from <module> import ...``
        :type variable: str
        :arg  variable: ``<variable>`` part in ``from ... import <variable>``
        :type    alias: str
        :arg     alias: ``<alias>`` part in ``... import ... as <alias>``.

        :rtype: :class:`parsing_representation.Import`
        """
        submodule = self.scope._sub_module
        if variable:
            varname = pr.Name(module=submodule,
                              names=[(variable, (-1, 0))],
                              start_pos=(-1, 0),
                              end_pos=(None, None))
        else:
            varname = None
        modname = pr.Name(module=submodule,
                          names=[(module, (-1, 0))],
                          start_pos=(-1, 0),
                          end_pos=(None, None))
        if alias:
            aliasname = pr.Name(module=submodule,
                                names=[(alias, (-1, 0))],
                                start_pos=(-1, 0),
                                end_pos=(None, None))
        else:
            aliasname = None
        if varname:
            fakeimport = pr.Import(module=submodule,
                                   namespace=varname,
                                   from_ns=modname,
                                   alias=aliasname,
                                   start_pos=(-1, 0),
                                   end_pos=(None, None))
        else:
            fakeimport = pr.Import(module=submodule,
                                   namespace=modname,
                                   alias=aliasname,
                                   start_pos=(-1, 0),
                                   end_pos=(None, None))
        return fakeimport
Ejemplo n.º 3
0
    def _parse_class(self):
        """
        The parser for a text class. Process the tokens, which follow a
        class definition.

        :return: Return a Scope representation of the tokens.
        :rtype: Class
        """
        first_pos = self._gen.current.start_pos
        cname = next(self._gen)
        if cname.type != tokenize.NAME:
            debug.warning("class: syntax err, token is not a name@%s (%s: %s)",
                          cname.start_pos[0], tokenize.tok_name[cname.type],
                          cname.string)
            return None

        cname = pr.Name(self.module, [(cname.string, cname.start_pos)],
                        cname.start_pos, cname.end_pos)

        super = []
        _next = next(self._gen)
        if _next.string == '(':
            super = self._parse_parentheses()
            _next = next(self._gen)

        if _next.string != ':':
            debug.warning("class syntax: %s@%s", cname, _next.start_pos[0])
            return None

        return pr.Class(self.module, cname, super, first_pos)
Ejemplo n.º 4
0
    def _parse_dot_name(self, pre_used_token=None):
        """
        The dot name parser parses a name, variable or function and returns
        their names.

        :return: tuple of Name, next_token
        """
        def append(el):
            names.append(el)
            self.module.temp_used_names.append(el[0])

        names = []
        tok = next(self._gen) if pre_used_token is None else pre_used_token

        if tok.type != tokenize.NAME and tok.string != '*':
            return None, tok

        first_pos = tok.start_pos
        append((tok.string, first_pos))
        while True:
            end_pos = tok.end_pos
            tok = next(self._gen)
            if tok.string != '.':
                break
            tok = next(self._gen)
            if tok.type != tokenize.NAME:
                break
            append((tok.string, tok.start_pos))

        n = pr.Name(self.module, names, first_pos, end_pos) if names else None
        return n, tok
Ejemplo n.º 5
0
    def _parse_class(self):
        """
        The parser for a text class. Process the tokens, which follow a
        class definition.

        :return: Return a Scope representation of the tokens.
        :rtype: Class
        """
        first_pos = self.start_pos
        token_type, cname = self.next()
        if token_type != tokenize.NAME:
            debug.warning(
                "class: syntax err, token is not a name@%s (%s: %s)" %
                (self.start_pos[0], tokenize.tok_name[token_type], cname))
            return None

        cname = pr.Name(self.module, [(cname, self.start_pos)], self.start_pos,
                        self.end_pos)

        super = []
        token_type, _next = self.next()
        if _next == '(':
            super = self._parse_parentheses()
            token_type, _next = self.next()

        if _next != ':':
            debug.warning("class syntax: %s@%s" % (cname, self.start_pos[0]))
            return None

        # because of 2 line class initializations
        scope = pr.Class(self.module, cname, super, first_pos)
        if self.user_scope and scope != self.user_scope \
                and self.user_position > first_pos:
            self.user_scope = scope
        return scope
Ejemplo n.º 6
0
def keyword_names(*args, **kwargs):
    kwds = []
    for k in keywords(*args, **kwargs):
        start = k.start_pos
        end = start[0], start[1] + len(k.name)
        kwds.append(pr.Name(k.parent, [(k.name, start)], start, end, k))
    return kwds
Ejemplo n.º 7
0
    def get_defined_names(self, on_import_stmt=False):
        names = []
        for scope in self.follow():
            if scope is ImportPath.GlobalNamespace:
                if self._is_relative_import() == 0:
                    names += self._get_module_names()

                if self.file_path is not None:
                    path = os.path.abspath(self.file_path)
                    for i in range(self.import_stmt.relative_count - 1):
                        path = os.path.dirname(path)
                    names += self._get_module_names([path])

                    if self._is_relative_import():
                        rel_path = self._get_relative_path() + '/__init__.py'
                        if os.path.exists(rel_path):
                            m = load_module(rel_path)
                            names += m.get_defined_names()
            else:
                if on_import_stmt and isinstance(scope, pr.Module) \
                        and scope.path.endswith('__init__.py'):
                    pkg_path = os.path.dirname(scope.path)
                    paths = self._namespace_packages(pkg_path,
                                                     self.import_path)
                    names += self._get_module_names([pkg_path] + paths)
                if self.is_just_from:
                    # In the case of an import like `from x.` we don't need to
                    # add all the variables.
                    if [
                            'os'
                    ] == self.import_path and not self._is_relative_import():
                        # os.path is a hardcoded exception, because it's a
                        # ``sys.modules`` modification.
                        p = (0, 0)
                        names.append(
                            pr.Name(self.GlobalNamespace, [('path', p)], p, p,
                                    self.import_stmt))
                    continue
                from jedi.evaluate import finder
                for s, scope_names in finder.get_names_of_scope(
                        self._evaluator, scope, include_builtin=False):
                    for n in scope_names:
                        if self.import_stmt.from_ns is None \
                                or self.is_partial_import:
                            # from_ns must be defined to access module
                            # values plus a partial import means that there
                            # is something after the import, which
                            # automatically implies that there must not be
                            # any non-module scope.
                            continue
                        names.append(n)
        return names
Ejemplo n.º 8
0
 def _get_nested_import(self, parent):
     """
     See documentation of `self._is_nested_import`.
     Generates an Import statement, that can be used to fake nested imports.
     """
     i = self.import_stmt
     # This is not an existing Import statement. Therefore, set position to
     # 0 (0 is not a valid line number).
     zero = (0, 0)
     names = i.namespace.names[1:]
     n = pr.Name(i._sub_module, names, zero, zero, self.import_stmt)
     new = pr.Import(i._sub_module, zero, zero, n)
     new.parent = parent
     debug.dbg('Generated a nested import: %s' % new)
     return new
Ejemplo n.º 9
0
 def get_defined_names(self):
     """
     Returns a list of names that define a generator, which can return the
     content of a generator.
     """
     names = []
     none_pos = (0, 0)
     executes_generator = ('__next__', 'send')
     for n in ('close', 'throw') + executes_generator:
         name = pr.Name(builtin.Builtin.scope, [(n, none_pos)], none_pos,
                        none_pos)
         if n in executes_generator:
             name.parent = self
         else:
             name.parent = builtin.Builtin.scope
         names.append(name)
     debug.dbg('generator names', names)
     return names
Ejemplo n.º 10
0
Archivo: api.py Proyecto: rayleyva/jedi
    def _simple_complete(self, path, like):
        user_stmt = self._user_stmt(True)
        is_simple_path = not path or re.search('^[\w][\w\d.]*$', path)
        if isinstance(user_stmt, pr.Import) or not is_simple_path:
            return super(type(self), self)._simple_complete(path, like)
        else:

            class NamespaceModule:
                def __getattr__(_, name):
                    for n in self.namespaces:
                        try:
                            return n[name]
                        except KeyError:
                            pass
                    raise AttributeError()

                def __dir__(_):
                    return list(
                        set(
                            chain.from_iterable(n.keys()
                                                for n in self.namespaces)))

            paths = path.split('.') if path else []

            namespaces = (NamespaceModule(), builtins)
            for p in paths:
                old, namespaces = namespaces, []
                for n in old:
                    try:
                        namespaces.append(getattr(n, p))
                    except AttributeError:
                        pass

            completions = []
            for n in namespaces:
                for name in dir(n):
                    if name.lower().startswith(like.lower()):
                        scope = self._parser.module
                        n = pr.Name(self._parser.module, [(name, (0, 0))],
                                    (0, 0), (0, 0), scope)
                        completions.append((n, scope))
            return completions
Ejemplo n.º 11
0
    def _parse_function(self):
        """
        The parser for a text functions. Process the tokens, which follow a
        function definition.

        :return: Return a Scope representation of the tokens.
        :rtype: Function
        """
        first_pos = self.start_pos
        token_type, fname = self.next()
        if token_type != tokenize.NAME:
            return None

        fname = pr.Name(self.module, [(fname, self.start_pos)], self.start_pos,
                        self.end_pos)

        token_type, open = self.next()
        if open != '(':
            return None
        params = self._parse_parentheses()

        token_type, colon = self.next()
        annotation = None
        if colon in ['-', '->']:
            # parse annotations
            if colon == '-':
                # The Python 2 tokenizer doesn't understand this
                token_type, colon = self.next()
                if colon != '>':
                    return None
            annotation, colon = self._parse_statement(added_breaks=[':'])

        if colon != ':':
            return None

        # because of 2 line func param definitions
        scope = pr.Function(self.module, fname, params, first_pos, annotation)
        if self.user_scope and scope != self.user_scope \
                and self.user_position > first_pos:
            self.user_scope = scope
        return scope
Ejemplo n.º 12
0
    def _parse_dot_name(self, pre_used_token=None):
        """
        The dot name parser parses a name, variable or function and returns
        their names.

        :return: Tuple of Name, token_type, nexttoken.
        :rtype: tuple(Name, int, str)
        """
        def append(el):
            names.append(el)
            self.module.temp_used_names.append(el[0])

        names = []
        if pre_used_token is None:
            token_type, tok = self.next()
            if token_type != tokenize.NAME and tok != '*':
                return [], token_type, tok
        else:
            token_type, tok = pre_used_token

        if token_type != tokenize.NAME and tok != '*':
            # token maybe a name or star
            return None, token_type, tok

        append((tok, self.start_pos))
        first_pos = self.start_pos
        while True:
            end_pos = self.end_pos
            token_type, tok = self.next()
            if tok != '.':
                break
            token_type, tok = self.next()
            if token_type != tokenize.NAME:
                break
            append((tok, self.start_pos))

        n = pr.Name(self.module, names, first_pos, end_pos) if names else None
        return n, token_type, tok
Ejemplo n.º 13
0
    def _parse_function(self):
        """
        The parser for a text functions. Process the tokens, which follow a
        function definition.

        :return: Return a Scope representation of the tokens.
        :rtype: Function
        """
        first_pos = self._gen.current.start_pos
        tok = next(self._gen)
        if tok.type != tokenize.NAME:
            return None

        fname = pr.Name(self.module, [(tok.string, tok.start_pos)],
                        tok.start_pos, tok.end_pos)

        tok = next(self._gen)
        if tok.string != '(':
            return None
        params = self._parse_parentheses()

        colon = next(self._gen)
        annotation = None
        if colon.string in ('-', '->'):
            # parse annotations
            if colon.string == '-':
                # The Python 2 tokenizer doesn't understand this
                colon = next(self._gen)
                if colon.string != '>':
                    return None
            annotation, colon = self._parse_statement(added_breaks=[':'])

        if colon.string != ':':
            return None

        # because of 2 line func param definitions
        return pr.Function(self.module, fname, params, first_pos, annotation)
Ejemplo n.º 14
0
 def generate_name(name):
     return pr.Name(self.GlobalNamespace, [(name, inf_pos)], inf_pos,
                    inf_pos, self.import_stmt)