diff --git a/jedi/api/__init__.py b/jedi/api/__init__.py index 56d8cbf3..c6c3c48a 100644 --- a/jedi/api/__init__.py +++ b/jedi/api/__init__.py @@ -255,7 +255,7 @@ class Script(object): context = self._evaluator.create_context(self._get_module(), leaf) definitions = helpers.evaluate_goto_definition(self._evaluator, context, leaf) # We don't want stubs here we want the actual contexts, if possible. - definitions = try_stubs_to_actual_context_set(definitions) + definitions = try_stubs_to_actual_context_set(definitions, prefer_stub_to_compiled=True) names = [s.name for s in definitions] defs = [classes.Definition(self._evaluator, name) for name in names] @@ -308,7 +308,7 @@ class Script(object): return isinstance(name, imports.SubModuleName) names = filter_follow_imports(names, check) - names = try_stubs_to_actual_names(names) + names = try_stubs_to_actual_names(names, prefer_stub_to_compiled=True) defs = [classes.Definition(self._evaluator, d) for d in set(names)] return helpers.sorted_definitions(defs) diff --git a/jedi/evaluate/base_context.py b/jedi/evaluate/base_context.py index d2a28098..ee6cae36 100644 --- a/jedi/evaluate/base_context.py +++ b/jedi/evaluate/base_context.py @@ -111,10 +111,6 @@ class Context(HelperContextMixin, BaseContext): To be defined by subclasses. """ tree_node = None - stub_context = None - - def is_stub(self): - return False @property def api_type(self): @@ -158,6 +154,12 @@ class Context(HelperContextMixin, BaseContext): def is_module(self): return False + def is_stub(self): + return False + + def is_compiled(self): + return False + def py__bool__(self): """ Since Wrapper is a super class for classes, functions and modules, diff --git a/jedi/evaluate/compiled/context.py b/jedi/evaluate/compiled/context.py index bf1238c8..4ce4b0b2 100644 --- a/jedi/evaluate/compiled/context.py +++ b/jedi/evaluate/compiled/context.py @@ -99,6 +99,9 @@ class CompiledObject(Context): def is_class(self): return self.access_handle.is_class() + def is_compiled(self): + return True + def py__doc__(self, include_call_signature=False): return self.access_handle.py__doc__() diff --git a/jedi/evaluate/gradual/stub_context.py b/jedi/evaluate/gradual/stub_context.py index e0620988..4b16dbcc 100644 --- a/jedi/evaluate/gradual/stub_context.py +++ b/jedi/evaluate/gradual/stub_context.py @@ -277,6 +277,8 @@ def _add_stub_if_possible(parent_context, actual_context, stub_contexts): def with_stub_context_if_possible(actual_context): + return ContextSet([actual_context]) + # XXX if actual_context.tree_node.type == 'lambdef': return ContextSet([actual_context]) assert actual_context.tree_node.type in ('classdef', 'funcdef') @@ -338,7 +340,7 @@ def stub_to_actual_context_set(stub_context): return non_stubs -def try_stubs_to_actual_context_set(stub_contexts): +def try_stubs_to_actual_context_set(stub_contexts, prefer_stub_to_compiled=False): return ContextSet.from_sets( stub_to_actual_context_set(stub_context) or ContextSet(stub_context) for stub_context in stub_contexts @@ -346,7 +348,7 @@ def try_stubs_to_actual_context_set(stub_contexts): @to_list -def try_stubs_to_actual_names(names): +def try_stubs_to_actual_names(names, prefer_stub_to_compiled=False): for name in names: parent_context = name.parent_context if name.tree_name is None: @@ -356,12 +358,24 @@ def try_stubs_to_actual_names(names): yield name continue - for n in goto_non_stub(parent_context, name.tree_name): - yield n + contexts = stub_to_actual_context_set(parent_context) + if prefer_stub_to_compiled: + # We don't really care about + contexts = ContextSet([c for c in contexts if not c.is_compiled()]) + + new_names = contexts.py__getattribute__(name.tree_name, is_goto=True) + + if new_names: + for n in new_names: + yield n + else: + yield name def stubify(parent_context, context): if parent_context.is_stub(): + return ContextSet([context]) + # XXX return ContextSet( c.stub_context for c in stub_to_actual_context_set(context)