From d04241b482592b45dc6e20005d5ab604c10be337 Mon Sep 17 00:00:00 2001 From: Dave Halter Date: Thu, 23 Apr 2015 02:37:22 +0200 Subject: [PATCH] Goto should not include imports that cannot be followed. --- jedi/api/__init__.py | 14 ++++++++++++-- jedi/evaluate/__init__.py | 6 ++++-- jedi/evaluate/imports.py | 17 +++++++++++------ jedi/evaluate/representation.py | 2 +- jedi/evaluate/sys_path.py | 2 +- 5 files changed, 29 insertions(+), 12 deletions(-) diff --git a/jedi/api/__init__.py b/jedi/api/__init__.py index aa60957b..1572c312 100644 --- a/jedi/api/__init__.py +++ b/jedi/api/__init__.py @@ -429,8 +429,11 @@ class Script(object): user_scope = self._parser.user_scope() definitions = set([user_scope.name]) elif isinstance(user_stmt, pr.Import): - s, name_part = helpers.get_on_import_stmt(self._evaluator, - self._user_context, user_stmt) + s, name = helpers.get_on_import_stmt(self._evaluator, + self._user_context, user_stmt) + + definitions = self._evaluator.goto(name) + """ try: definitions = [s.follow(is_goto=True)[0]] except IndexError: @@ -442,6 +445,7 @@ class Script(object): np = import_name[0] if not user_stmt.is_star_import() and unicode(name_part) == unicode(np): definitions.append(np) + """ else: # The Evaluator.goto function checks for definitions, but since we # use a reverse tokenizer, we have new name_part objects, so we @@ -472,6 +476,12 @@ class Script(object): try: user_stmt = self._parser.user_stmt() definitions = self._goto(add_import_name=True) + if not definitions and isinstance(user_stmt, pr.Import): + # For not defined imports (goto doesn't find something, we take + # the name as a definition. This is enough, because every name + # points to it. + definitions = [user_stmt.name_for_position(self._pos)] + if not definitions: # Without a definition for a name we cannot find references. return [] diff --git a/jedi/evaluate/__init__.py b/jedi/evaluate/__init__.py index 82a243ec..bf84caab 100644 --- a/jedi/evaluate/__init__.py +++ b/jedi/evaluate/__init__.py @@ -305,7 +305,8 @@ class Evaluator(object): s = imports.ImportWrapper(self, name) for n in s.follow(is_goto=True): yield n - yield name + else: + yield name stmt = name.get_definition() par = name.parent @@ -340,7 +341,8 @@ class Evaluator(object): elif isinstance(par, (pr.Param, pr.Function, pr.Class)) and par.name is name: return [name] elif isinstance(stmt, pr.Import): - return imports.ImportWrapper(self, name).follow(is_goto=True) + modules = imports.ImportWrapper(self, name).follow(is_goto=True) + return list(resolve_implicit_imports(modules)) elif par.type == 'dotted_name': # Is a decorator. index = par.children.index(name) if index > 0: diff --git a/jedi/evaluate/imports.py b/jedi/evaluate/imports.py index 71c1ecba..469445c1 100644 --- a/jedi/evaluate/imports.py +++ b/jedi/evaluate/imports.py @@ -104,20 +104,23 @@ class ImportWrapper(pr.Base): if from_import_name is not None: types = list(chain.from_iterable( - self._evaluator.find_types(s, from_import_name, is_goto) + self._evaluator.find_types(s, from_import_name, is_goto=is_goto) for s in types)) if not types: importer = get_importer(self._evaluator, tuple(import_path + [from_import_name]), module, self._import.level) types, _ = importer.follow_file_system() + # goto only accepts `Name` + if is_goto: + types = [s.name for s in types] + else: + # goto only accepts `Name` + if is_goto: + types = [s.name for s in types] - # goto only accepts `Name` - if is_goto and not rest: - types = [s.name for s in types] - """ # follow the rest of the import (not FS -> classes, functions) if rest: @@ -298,7 +301,7 @@ class _Importer(object): @memoize_default(NO_DEFAULT) def follow_file_system(self): if not self.import_path: - return None, [] + return [], [] modules = self._do_import(self.import_path, self.sys_path_with_modifications()) return modules, [] @@ -413,6 +416,8 @@ class _Importer(object): else: debug.dbg('search_module %s in paths %s', module_name, paths) for path in paths: + # At the moment we are only using one path. So this is + # not important to be correct. module_file, module_path, is_pkg = \ find_module(import_parts[-1], [path]) else: diff --git a/jedi/evaluate/representation.py b/jedi/evaluate/representation.py index 35bd9c4f..a07d51b2 100644 --- a/jedi/evaluate/representation.py +++ b/jedi/evaluate/representation.py @@ -775,7 +775,7 @@ class ModuleWrapper(use_metaclass(CachedMetaClass, pr.Module, Wrapper)): return name def py__file__(self): - return self._module.path + return os.path.abspath(self._module.path) def py__package__(self): if self._get_init_directory() is None: diff --git a/jedi/evaluate/sys_path.py b/jedi/evaluate/sys_path.py index 230127f0..c0e21299 100644 --- a/jedi/evaluate/sys_path.py +++ b/jedi/evaluate/sys_path.py @@ -179,7 +179,7 @@ def _get_paths_from_buildout_script(evaluator, buildout_script): cache.save_parser(buildout_script, p) return p.module - cached = cache.load_parser(buildout_script, None) + cached = cache.load_parser(buildout_script) module = cached and cached.module or load(buildout_script) if not module: return