forked from VimPlug/jedi
Use a different function signature instead of a separate goto_stubs function
This commit is contained in:
@@ -9,6 +9,7 @@ import warnings
|
|||||||
from parso.python.tree import search_ancestor
|
from parso.python.tree import search_ancestor
|
||||||
|
|
||||||
from jedi import settings
|
from jedi import settings
|
||||||
|
from jedi import debug
|
||||||
from jedi.evaluate.utils import unite
|
from jedi.evaluate.utils import unite
|
||||||
from jedi.cache import memoize_method
|
from jedi.cache import memoize_method
|
||||||
from jedi.evaluate import imports
|
from jedi.evaluate import imports
|
||||||
@@ -16,8 +17,8 @@ from jedi.evaluate import compiled
|
|||||||
from jedi.evaluate.imports import ImportName
|
from jedi.evaluate.imports import ImportName
|
||||||
from jedi.evaluate.context import FunctionExecutionContext
|
from jedi.evaluate.context import FunctionExecutionContext
|
||||||
from jedi.evaluate.gradual.typeshed import StubModuleContext
|
from jedi.evaluate.gradual.typeshed import StubModuleContext
|
||||||
from jedi.evaluate.gradual.conversion import name_to_stub, \
|
from jedi.evaluate.gradual.conversion import try_stub_to_actual_names, \
|
||||||
stub_to_actual_context_set, try_stubs_to_actual_context_set
|
stub_to_actual_context_set, try_stubs_to_actual_context_set, actual_to_stub_names
|
||||||
from jedi.api.keywords import KeywordName
|
from jedi.api.keywords import KeywordName
|
||||||
|
|
||||||
|
|
||||||
@@ -280,26 +281,30 @@ class BaseDefinition(object):
|
|||||||
return False
|
return False
|
||||||
return all(c.is_stub() for c in self._name.infer())
|
return all(c.is_stub() for c in self._name.infer())
|
||||||
|
|
||||||
def goto_stubs(self):
|
def goto_assignments(self, **kwargs): # Python 2...
|
||||||
|
return self._goto_assignments(**kwargs)
|
||||||
|
|
||||||
|
def _goto_assignments(self, only_stubs=False, prefer_stubs=False):
|
||||||
|
assert not (only_stubs and prefer_stubs)
|
||||||
|
|
||||||
if not self._name.is_context_name:
|
if not self._name.is_context_name:
|
||||||
return []
|
return []
|
||||||
|
|
||||||
if self.is_stub():
|
names = self._name.goto()
|
||||||
return [self]
|
if only_stubs or prefer_stubs:
|
||||||
|
names = actual_to_stub_names(names, fallback_to_actual=prefer_stubs)
|
||||||
return [
|
else:
|
||||||
Definition(self._evaluator, stub_def.name)
|
names = try_stub_to_actual_names(names, prefer_stub_to_compiled=True)
|
||||||
for stub_def in name_to_stub(self._name)
|
|
||||||
]
|
|
||||||
|
|
||||||
def goto_assignments(self):
|
|
||||||
if not self._name.is_context_name:
|
|
||||||
return []
|
|
||||||
|
|
||||||
return [self if n == self._name else Definition(self._evaluator, n)
|
return [self if n == self._name else Definition(self._evaluator, n)
|
||||||
for n in self._name.goto()]
|
for n in names]
|
||||||
|
|
||||||
|
def infer(self, **kwargs): # Python 2...
|
||||||
|
return self._infer(**kwargs)
|
||||||
|
|
||||||
|
def _infer(self, only_stubs=False, prefer_stubs=False):
|
||||||
|
assert not (only_stubs and prefer_stubs)
|
||||||
|
|
||||||
def infer(self):
|
|
||||||
if not self._name.is_context_name:
|
if not self._name.is_context_name:
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ from jedi.evaluate.context.iterable import CompForContext
|
|||||||
from jedi.evaluate.syntax_tree import eval_trailer, eval_expr_stmt, \
|
from jedi.evaluate.syntax_tree import eval_trailer, eval_expr_stmt, \
|
||||||
eval_node, check_tuple_assignments
|
eval_node, check_tuple_assignments
|
||||||
from jedi.evaluate.gradual.conversion import try_stub_to_actual_names, \
|
from jedi.evaluate.gradual.conversion import try_stub_to_actual_names, \
|
||||||
try_stubs_to_actual_context_set
|
actual_to_stub_names, try_stubs_to_actual_context_set
|
||||||
|
|
||||||
|
|
||||||
def _execute(context, arguments):
|
def _execute(context, arguments):
|
||||||
@@ -322,11 +322,6 @@ class Evaluator(object):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
def goto(self, context, name):
|
def goto(self, context, name):
|
||||||
names = self._goto(context, name)
|
|
||||||
names = try_stub_to_actual_names(names, prefer_stub_to_compiled=True)
|
|
||||||
return names
|
|
||||||
|
|
||||||
def _goto(self, context, name):
|
|
||||||
definition = name.get_definition(import_name_always=True)
|
definition = name.get_definition(import_name_always=True)
|
||||||
if definition is not None:
|
if definition is not None:
|
||||||
type_ = definition.type
|
type_ = definition.type
|
||||||
|
|||||||
@@ -263,6 +263,10 @@ class CompiledName(AbstractNameDefinition):
|
|||||||
self.parent_context = parent_context
|
self.parent_context = parent_context
|
||||||
self.string_name = name
|
self.string_name = name
|
||||||
|
|
||||||
|
def _get_qualified_names(self):
|
||||||
|
parent_qualified_names = self.parent_context.get_qualified_names()
|
||||||
|
return parent_qualified_names + (self.string_name,)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
try:
|
try:
|
||||||
name = self.parent_context.name # __name__ is not defined all the time
|
name = self.parent_context.name # __name__ is not defined all the time
|
||||||
|
|||||||
@@ -104,8 +104,36 @@ def _load_stub_module(module):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def name_to_stub(name):
|
@to_list
|
||||||
return ContextSet.from_sets(to_stub(c) for c in name.infer())
|
def actual_to_stub_names(names, fallback_to_actual=False):
|
||||||
|
for name in names:
|
||||||
|
module = name.get_root_context()
|
||||||
|
if module.is_stub():
|
||||||
|
yield name
|
||||||
|
continue
|
||||||
|
|
||||||
|
name_list = name.get_qualified_names()
|
||||||
|
stubs = NO_CONTEXTS
|
||||||
|
if name_list is not None:
|
||||||
|
stub_module = _load_stub_module(module)
|
||||||
|
if stub_module is not None:
|
||||||
|
stubs = ContextSet({stub_module})
|
||||||
|
for name in name_list[:-1]:
|
||||||
|
stubs = stubs.py__getattribute__(name)
|
||||||
|
if stubs and name_list:
|
||||||
|
new_names = stubs.py__getattribute__(name_list[-1], is_goto=True)
|
||||||
|
for new_name in new_names:
|
||||||
|
yield new_name
|
||||||
|
if new_names:
|
||||||
|
continue
|
||||||
|
elif stubs:
|
||||||
|
for c in stubs:
|
||||||
|
yield c.name
|
||||||
|
continue
|
||||||
|
if fallback_to_actual:
|
||||||
|
# This is the part where if we haven't found anything, just return
|
||||||
|
# the stub name.
|
||||||
|
yield name
|
||||||
|
|
||||||
|
|
||||||
def to_stub(context):
|
def to_stub(context):
|
||||||
|
|||||||
@@ -27,8 +27,18 @@ class AbstractNameDefinition(object):
|
|||||||
# name will always result on itself.
|
# name will always result on itself.
|
||||||
return {self}
|
return {self}
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def get_qualified_names(self, include_module_names=False):
|
def get_qualified_names(self, include_module_names=False):
|
||||||
|
qualified_names = self._get_qualified_names()
|
||||||
|
if qualified_names is None or not include_module_names:
|
||||||
|
return qualified_names
|
||||||
|
|
||||||
|
module_names = self.get_root_context().string_names
|
||||||
|
if module_names is None:
|
||||||
|
return None
|
||||||
|
return module_names + qualified_names
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def _get_qualified_names(self):
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
def get_root_context(self):
|
def get_root_context(self):
|
||||||
@@ -56,21 +66,20 @@ class AbstractTreeName(AbstractNameDefinition):
|
|||||||
def get_qualified_names(self, include_module_names=False):
|
def get_qualified_names(self, include_module_names=False):
|
||||||
import_node = search_ancestor(self.tree_name, 'import_name', 'import_from')
|
import_node = search_ancestor(self.tree_name, 'import_name', 'import_from')
|
||||||
if import_node is not None:
|
if import_node is not None:
|
||||||
|
if include_module_names:
|
||||||
return tuple(n.value for n in import_node.get_path_for_name(self.tree_name))
|
return tuple(n.value for n in import_node.get_path_for_name(self.tree_name))
|
||||||
|
else:
|
||||||
|
return ()
|
||||||
|
return super(AbstractTreeName, self).get_qualified_names(include_module_names)
|
||||||
|
|
||||||
|
def _get_qualified_names(self):
|
||||||
parent_names = self.parent_context.get_qualified_names()
|
parent_names = self.parent_context.get_qualified_names()
|
||||||
if parent_names is None:
|
if parent_names is None:
|
||||||
return None
|
return None
|
||||||
parent_names += (self.tree_name.value,)
|
return parent_names + (self.tree_name.value,)
|
||||||
if include_module_names:
|
|
||||||
module_names = self.get_root_context().string_names
|
|
||||||
if module_names is None:
|
|
||||||
return None
|
|
||||||
return module_names + parent_names
|
|
||||||
return parent_names
|
|
||||||
|
|
||||||
def goto(self):
|
def goto(self, **kwargs):
|
||||||
return self.parent_context.evaluator.goto(self.parent_context, self.tree_name)
|
return self.parent_context.evaluator.goto(self.parent_context, self.tree_name, **kwargs)
|
||||||
|
|
||||||
def is_import(self):
|
def is_import(self):
|
||||||
imp = search_ancestor(self.tree_name, 'import_from', 'import_name')
|
imp = search_ancestor(self.tree_name, 'import_from', 'import_name')
|
||||||
@@ -89,15 +98,8 @@ class ContextNameMixin(object):
|
|||||||
def infer(self):
|
def infer(self):
|
||||||
return ContextSet([self._context])
|
return ContextSet([self._context])
|
||||||
|
|
||||||
def get_qualified_names(self, include_module_names=False):
|
def _get_qualified_names(self):
|
||||||
qualified_names = self._context.get_qualified_names()
|
return self._context.get_qualified_names()
|
||||||
if qualified_names is None or not include_module_names:
|
|
||||||
return qualified_names
|
|
||||||
|
|
||||||
module_names = self.get_root_context().string_names
|
|
||||||
if module_names is None:
|
|
||||||
return None
|
|
||||||
return module_names + qualified_names
|
|
||||||
|
|
||||||
def get_root_context(self):
|
def get_root_context(self):
|
||||||
if self.parent_context is None: # A module
|
if self.parent_context is None: # A module
|
||||||
@@ -115,8 +117,7 @@ class ContextName(ContextNameMixin, AbstractTreeName):
|
|||||||
self._context = context
|
self._context = context
|
||||||
|
|
||||||
def goto(self):
|
def goto(self):
|
||||||
from jedi.evaluate.gradual.conversion import try_stub_to_actual_names
|
return ContextSet([self._context.name])
|
||||||
return try_stub_to_actual_names([self._context.name])
|
|
||||||
|
|
||||||
|
|
||||||
class TreeNameDefinition(AbstractTreeName):
|
class TreeNameDefinition(AbstractTreeName):
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ def test_keyword_attributes(Script):
|
|||||||
assert def_.complete == ''
|
assert def_.complete == ''
|
||||||
assert def_.is_keyword is True
|
assert def_.is_keyword is True
|
||||||
assert def_.is_stub() is False
|
assert def_.is_stub() is False
|
||||||
assert def_.goto_stubs() == []
|
assert def_.goto_assignments(only_stubs=True) == []
|
||||||
assert def_.goto_assignments() == []
|
assert def_.goto_assignments() == []
|
||||||
assert def_.infer() == []
|
assert def_.infer() == []
|
||||||
assert def_.parent() is None
|
assert def_.parent() is None
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ def test_keywords_variable(Script):
|
|||||||
for seq in Script(code).goto_definitions():
|
for seq in Script(code).goto_definitions():
|
||||||
assert seq.name == 'Sequence'
|
assert seq.name == 'Sequence'
|
||||||
# This points towards the typeshed implementation
|
# This points towards the typeshed implementation
|
||||||
stub_seq, = seq.goto_stubs()
|
stub_seq, = seq.goto_assignments(only_stubs=True)
|
||||||
assert typeshed.TYPESHED_PATH in stub_seq.module_path
|
assert typeshed.TYPESHED_PATH in stub_seq.module_path
|
||||||
|
|
||||||
|
|
||||||
@@ -156,12 +156,12 @@ def test_math_is_stub(Script, code, full_name):
|
|||||||
wanted = os.path.join('typeshed', 'stdlib', '2and3', 'math.pyi')
|
wanted = os.path.join('typeshed', 'stdlib', '2and3', 'math.pyi')
|
||||||
assert cos.module_path.endswith(wanted)
|
assert cos.module_path.endswith(wanted)
|
||||||
assert cos.is_stub() is True
|
assert cos.is_stub() is True
|
||||||
assert cos.goto_stubs() == [cos]
|
assert cos.goto_assignments(only_stubs=True) == [cos]
|
||||||
assert cos.full_name == full_name
|
assert cos.full_name == full_name
|
||||||
|
|
||||||
cos, = s.goto_assignments()
|
cos, = s.goto_assignments()
|
||||||
assert cos.module_path.endswith(wanted)
|
assert cos.module_path.endswith(wanted)
|
||||||
assert cos.goto_stubs() == [cos]
|
assert cos.goto_assignments(only_stubs=True) == [cos]
|
||||||
assert cos.is_stub() is True
|
assert cos.is_stub() is True
|
||||||
assert cos.full_name == full_name
|
assert cos.full_name == full_name
|
||||||
|
|
||||||
@@ -171,7 +171,7 @@ def test_goto_stubs(Script):
|
|||||||
os_module, = s.goto_definitions()
|
os_module, = s.goto_definitions()
|
||||||
assert os_module.full_name == 'os'
|
assert os_module.full_name == 'os'
|
||||||
assert os_module.is_stub() is False
|
assert os_module.is_stub() is False
|
||||||
stub, = os_module.goto_stubs()
|
stub, = os_module.goto_assignments(only_stubs=True)
|
||||||
assert stub.is_stub() is True
|
assert stub.is_stub() is True
|
||||||
|
|
||||||
os_module, = s.goto_assignments()
|
os_module, = s.goto_assignments()
|
||||||
@@ -202,7 +202,7 @@ def test_goto_stubs_on_itself(Script, code, type_):
|
|||||||
def_, = s.goto_definitions()
|
def_, = s.goto_definitions()
|
||||||
else:
|
else:
|
||||||
def_, = s.goto_assignments(follow_imports=True)
|
def_, = s.goto_assignments(follow_imports=True)
|
||||||
stub, = def_.goto_stubs()
|
stub, = def_.goto_assignments(only_stubs=True)
|
||||||
|
|
||||||
script_on_source = Script(
|
script_on_source = Script(
|
||||||
path=def_.module_path,
|
path=def_.module_path,
|
||||||
@@ -213,7 +213,7 @@ def test_goto_stubs_on_itself(Script, code, type_):
|
|||||||
definition, = script_on_source.goto_definitions()
|
definition, = script_on_source.goto_definitions()
|
||||||
else:
|
else:
|
||||||
definition, = script_on_source.goto_assignments()
|
definition, = script_on_source.goto_assignments()
|
||||||
same_stub, = definition.goto_stubs()
|
same_stub, = definition.goto_assignments(only_stubs=True)
|
||||||
_assert_is_same(same_stub, stub)
|
_assert_is_same(same_stub, stub)
|
||||||
_assert_is_same(definition, def_)
|
_assert_is_same(definition, def_)
|
||||||
assert same_stub.module_path != def_.module_path
|
assert same_stub.module_path != def_.module_path
|
||||||
|
|||||||
Reference in New Issue
Block a user