Exemple #1
0
def get_on_import_stmt(evaluator,
                       user_context,
                       user_stmt,
                       is_like_search=False):
    """
    Resolve the user statement, if it is an import. Only resolve the
    parts until the user position.
    """
    import_names = user_stmt.get_all_import_names()
    kill_count = -1
    cur_name_part = None
    for i in import_names:
        if user_stmt.alias == i:
            continue
        for name_part in i.names:
            if name_part.end_pos >= user_context.position:
                if not cur_name_part:
                    cur_name_part = name_part
                kill_count += 1

    context = user_context.get_context()
    just_from = next(context) == 'from'

    i = imports.ImportPath(evaluator,
                           user_stmt,
                           is_like_search,
                           kill_count=kill_count,
                           direct_resolve=True,
                           is_just_from=just_from)
    return i, cur_name_part
Exemple #2
0
def usages_add_import_modules(evaluator, definitions, search_name):
    """ Adds the modules of the imports """
    new = set()
    for d in definitions:
        if isinstance(d.parent, pr.Import):
            s = imports.ImportPath(evaluator, d.parent, direct_resolve=True)
            with common.ignored(IndexError):
                new.add(s.follow(is_goto=True)[0])
    return set(definitions) | new
Exemple #3
0
 def _follow_statements_imports(self):
     # imports completion is very complicated and needs to be treated
     # separately in Completion.
     if self._definition.isinstance(
             pr.Import) and self._definition.alias is None:
         i = imports.ImportPath(self._evaluator, self._definition, True)
         import_path = i.import_path + (unicode(self._name), )
         return imports.get_importer(self._evaluator, import_path,
                                     i._importer.module).follow(
                                         self._evaluator)
     return super(Completion, self)._follow_statements_imports()
Exemple #4
0
 def follow_inexistent_imports(defs):
     """ Imports can be generated, e.g. following
     `multiprocessing.dummy` generates an import dummy in the
     multiprocessing module. The Import doesn't exist -> follow.
     """
     definitions = set(defs)
     for d in defs:
         if isinstance(d.parent, pr.Import) \
                 and d.start_pos == (0, 0):
             i = imports.ImportPath(self._evaluator, d.parent).follow(is_goto=True)
             definitions.remove(d)
             definitions |= follow_inexistent_imports(i)
     return definitions
Exemple #5
0
    def type(self):
        """
        The type of the completion objects. Follows imports. For a further
        description, look at :attr:`jedi.api.classes.BaseDefinition.type`.
        """
        if isinstance(self._definition, pr.Import):
            i = imports.ImportPath(self._evaluator, self._definition)
            if len(i.import_path) <= 1:
                return 'module'

            followed = self.follow_definition()
            if followed:
                # Caveat: Only follows the first one, ignore the other ones.
                # This is ok, since people are almost never interested in
                # variations.
                return followed[0].type
        return super(Completion, self).type
Exemple #6
0
    def docstring(self, raw=False, fast=True):
        """
        :param fast: Don't follow imports that are only one level deep like
            ``import foo``, but follow ``from foo import bar``. This makes
            sense for speed reasons. Completing `import a` is slow if you use
            the ``foo.documentation(fast=False)`` on every object, because it
            parses all libraries starting with ``a``.
        """
        definition = self._definition
        if isinstance(self._definition, pr.Import):
            i = imports.ImportPath(self._evaluator, self._definition)
            if len(i.import_path) > 1 or not fast:
                followed = self._follow_statements_imports()
                if followed:
                    # TODO: Use all of the followed objects as input to Documentation.
                    definition = followed[0]

        if raw:
            return _Help(definition).raw()
        else:
            return _Help(definition).full()
Exemple #7
0
def usages(evaluator, definitions, search_name, mods):
    def compare_array(definitions):
        """ `definitions` are being compared by module/start_pos, because
        sometimes the id's of the objects change (e.g. executions).
        """
        result = []
        for d in definitions:
            module = d.get_parent_until()
            result.append((module, d.start_pos))
        return result

    def check_call(call):
        result = []
        follow = []  # There might be multiple search_name's in one call_path
        call_path = list(call.generate_call_path())
        for i, name in enumerate(call_path):
            # name is `pr.NamePart`.
            if name == search_name:
                follow.append(call_path[:i + 1])

        for f in follow:
            follow_res, search = evaluator.goto(call.parent, f)
            # names can change (getattr stuff), therefore filter names that
            # don't match `search_name`.

            # TODO add something like that in the future - for now usages are
            # completely broken anyway.
            #follow_res = [r for r in follow_res if str(r) == search]
            #print search.start_pos,search_name.start_pos
            #print follow_res, search, search_name, [(r, r.start_pos) for r in follow_res]
            follow_res = usages_add_import_modules(evaluator, follow_res, search)

            compare_follow_res = compare_array(follow_res)
            # compare to see if they match
            if any(r in compare_definitions for r in compare_follow_res):
                scope = call.parent
                result.append(Usage(evaluator, search, scope))

        return result

    if not definitions:
        return set()

    compare_definitions = compare_array(definitions)
    mods |= set([d.get_parent_until() for d in definitions])
    names = []
    for m in imports.get_modules_containing_name(mods, str(search_name)):
        try:
            stmts = m.used_names[search_name]
        except KeyError:
            continue
        for stmt in stmts:
            if isinstance(stmt, pr.Import):
                count = 0
                imps = []
                for i in stmt.get_all_import_names():
                    for name_part in i.names:
                        count += 1
                        if name_part == search_name:
                            imps.append((count, name_part))

                for used_count, name_part in imps:
                    i = imports.ImportPath(evaluator, stmt, kill_count=count - used_count,
                                           direct_resolve=True)
                    f = i.follow(is_goto=True)
                    if set(f) & set(definitions):
                        names.append(Usage(evaluator, name_part, stmt))
            else:
                for call in helpers.scan_statement_for_calls(stmt, search_name, assignment_details=True):
                    names += check_call(call)
    return names