mirror of
https://github.com/davidhalter/jedi.git
synced 2025-12-06 05:54:25 +08:00
Deal better with instance conversions for stubs
This commit is contained in:
@@ -9,6 +9,7 @@ from parso.python.parser import Parser
|
||||
from parso.python import tree
|
||||
|
||||
from jedi._compatibility import u
|
||||
from jedi.evaluate.base_context import NO_CONTEXTS
|
||||
from jedi.evaluate.syntax_tree import eval_atom
|
||||
from jedi.evaluate.helpers import evaluate_call_of_leaf
|
||||
from jedi.evaluate.compiled import get_string_context_set
|
||||
@@ -146,15 +147,22 @@ def evaluate_goto_definition(evaluator, context, leaf, prefer_stubs=False):
|
||||
return evaluator.goto_definitions(context, leaf)
|
||||
|
||||
parent = leaf.parent
|
||||
definitions = NO_CONTEXTS
|
||||
if parent.type == 'atom':
|
||||
return context.eval_node(leaf.parent)
|
||||
definitions = context.eval_node(leaf.parent)
|
||||
elif parent.type == 'trailer':
|
||||
return evaluate_call_of_leaf(context, leaf)
|
||||
definitions = evaluate_call_of_leaf(context, leaf)
|
||||
elif isinstance(leaf, tree.Literal):
|
||||
return eval_atom(context, leaf)
|
||||
elif leaf.type in ('fstring_string', 'fstring_start', 'fstring_end'):
|
||||
return get_string_context_set(evaluator)
|
||||
return []
|
||||
if prefer_stubs:
|
||||
return definitions
|
||||
from jedi.evaluate.gradual.conversion import try_stubs_to_actual_context_set
|
||||
return try_stubs_to_actual_context_set(
|
||||
definitions,
|
||||
prefer_stub_to_compiled=True,
|
||||
)
|
||||
|
||||
|
||||
CallSignatureDetails = namedtuple(
|
||||
|
||||
@@ -9,8 +9,19 @@ def stub_to_actual_context_set(stub_context, ignore_compiled=False):
|
||||
if not stub_module.is_stub():
|
||||
return ContextSet([stub_context])
|
||||
|
||||
was_instance = stub_context.is_instance()
|
||||
if was_instance:
|
||||
stub_context = stub_context.py__class__()
|
||||
|
||||
qualified_names = stub_context.get_qualified_names()
|
||||
return _infer_from_stub(stub_module, qualified_names, ignore_compiled)
|
||||
contexts = _infer_from_stub(stub_module, qualified_names, ignore_compiled)
|
||||
if was_instance:
|
||||
contexts = ContextSet.from_sets(
|
||||
c.execute_evaluated()
|
||||
for c in contexts
|
||||
if c.is_class()
|
||||
)
|
||||
return contexts
|
||||
|
||||
|
||||
def _infer_from_stub(stub_module, qualified_names, ignore_compiled):
|
||||
@@ -83,6 +94,10 @@ def _to_stub(context):
|
||||
if context.is_stub():
|
||||
return ContextSet([context])
|
||||
|
||||
was_instance = context.is_instance()
|
||||
if was_instance:
|
||||
context = context.py__class__()
|
||||
|
||||
qualified_names = context.get_qualified_names()
|
||||
stub_module = _load_stub_module(context.get_root_context())
|
||||
if stub_module is None or qualified_names is None:
|
||||
@@ -91,4 +106,11 @@ def _to_stub(context):
|
||||
stub_contexts = ContextSet([stub_module])
|
||||
for name in qualified_names:
|
||||
stub_contexts = stub_contexts.py__getattribute__(name)
|
||||
|
||||
if was_instance:
|
||||
stub_contexts = ContextSet.from_sets(
|
||||
c.execute_evaluated()
|
||||
for c in stub_contexts
|
||||
if c.is_class()
|
||||
)
|
||||
return stub_contexts
|
||||
|
||||
@@ -60,10 +60,11 @@ def test_function(Script, environment):
|
||||
|
||||
def test_keywords_variable(Script):
|
||||
code = 'import keyword; keyword.kwlist'
|
||||
def_, = Script(code).goto_definitions()
|
||||
assert def_.name == 'Sequence'
|
||||
seq1, seq2 = Script(code).goto_definitions()
|
||||
assert seq1.name, seq2.name == 'Sequence'
|
||||
# This points towards the typeshed implementation
|
||||
assert typeshed.TYPESHED_PATH in def_.module_path
|
||||
stub_seq, = seq1.goto_stubs()
|
||||
assert typeshed.TYPESHED_PATH in stub_seq.module_path
|
||||
|
||||
|
||||
def test_class(Script):
|
||||
@@ -187,6 +188,7 @@ def _assert_is_same(d1, d2):
|
||||
'code', [
|
||||
'import os; os.walk',
|
||||
'from collections import Counter; Counter',
|
||||
'from collections import Counter; Counter()',
|
||||
'from collections import Counter; Counter.most_common',
|
||||
])
|
||||
def test_goto_stubs_on_itself(Script, code, type_):
|
||||
|
||||
Reference in New Issue
Block a user