mirror of
https://github.com/davidhalter/jedi.git
synced 2025-12-06 14:04:26 +08:00
Some changes to get stubs working better for mixed objects
This commit is contained in:
@@ -19,6 +19,7 @@ from jedi.evaluate.helpers import execute_evaluated
|
|||||||
from jedi.evaluate.compiled.getattr_static import getattr_static
|
from jedi.evaluate.compiled.getattr_static import getattr_static
|
||||||
from jedi.evaluate.compiled.access import compiled_objects_cache
|
from jedi.evaluate.compiled.access import compiled_objects_cache
|
||||||
from jedi.evaluate.compiled.context import create_cached_compiled_object
|
from jedi.evaluate.compiled.context import create_cached_compiled_object
|
||||||
|
from jedi.evaluate.gradual.conversion import to_stub
|
||||||
|
|
||||||
|
|
||||||
class MixedObject(object):
|
class MixedObject(object):
|
||||||
@@ -83,9 +84,7 @@ class MixedName(compiled.CompiledName):
|
|||||||
access_handle = self.parent_context.access_handle
|
access_handle = self.parent_context.access_handle
|
||||||
# TODO use logic from compiled.CompiledObjectFilter
|
# TODO use logic from compiled.CompiledObjectFilter
|
||||||
access_handle = access_handle.getattr(self.string_name, default=None)
|
access_handle = access_handle.getattr(self.string_name, default=None)
|
||||||
return ContextSet([
|
return _create(self._evaluator, access_handle, parent_context=self.parent_context)
|
||||||
_create(self._evaluator, access_handle, parent_context=self.parent_context)
|
|
||||||
])
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def api_type(self):
|
def api_type(self):
|
||||||
@@ -198,7 +197,7 @@ def _create(evaluator, access_handle, parent_context, *args):
|
|||||||
|
|
||||||
result = _find_syntax_node_name(evaluator, access_handle)
|
result = _find_syntax_node_name(evaluator, access_handle)
|
||||||
if result is None:
|
if result is None:
|
||||||
return compiled_object
|
return ContextSet([compiled_object])
|
||||||
|
|
||||||
module_node, tree_node, file_io, code_lines = result
|
module_node, tree_node, file_io, code_lines = result
|
||||||
|
|
||||||
@@ -228,9 +227,11 @@ def _create(evaluator, access_handle, parent_context, *args):
|
|||||||
# Is an instance, not a class.
|
# Is an instance, not a class.
|
||||||
tree_context, = execute_evaluated(tree_context)
|
tree_context, = execute_evaluated(tree_context)
|
||||||
|
|
||||||
return MixedObject(
|
return ContextSet({
|
||||||
|
MixedObject(
|
||||||
evaluator,
|
evaluator,
|
||||||
parent_context,
|
parent_context,
|
||||||
compiled_object,
|
compiled_object,
|
||||||
tree_context=tree_context
|
tree_context=c,
|
||||||
)
|
) for c in to_stub(tree_context) or [tree_context]
|
||||||
|
})
|
||||||
|
|||||||
@@ -102,10 +102,10 @@ def _load_stub_module(module):
|
|||||||
|
|
||||||
|
|
||||||
def name_to_stub(name):
|
def name_to_stub(name):
|
||||||
return ContextSet.from_sets(_to_stub(c) for c in name.infer())
|
return ContextSet.from_sets(to_stub(c) for c in name.infer())
|
||||||
|
|
||||||
|
|
||||||
def _to_stub(context):
|
def to_stub(context):
|
||||||
if context.is_stub():
|
if context.is_stub():
|
||||||
return ContextSet([context])
|
return ContextSet([context])
|
||||||
|
|
||||||
@@ -118,6 +118,13 @@ def _to_stub(context):
|
|||||||
if stub_module is None or qualified_names is None:
|
if stub_module is None or qualified_names is None:
|
||||||
return NO_CONTEXTS
|
return NO_CONTEXTS
|
||||||
|
|
||||||
|
was_bound_method = context.is_bound_method()
|
||||||
|
if was_bound_method:
|
||||||
|
# Infer the object first. We can infer the method later.
|
||||||
|
method_name = qualified_names[-1]
|
||||||
|
qualified_names = qualified_names[:-1]
|
||||||
|
was_instance = True
|
||||||
|
|
||||||
stub_contexts = ContextSet([stub_module])
|
stub_contexts = ContextSet([stub_module])
|
||||||
for name in qualified_names:
|
for name in qualified_names:
|
||||||
stub_contexts = stub_contexts.py__getattribute__(name)
|
stub_contexts = stub_contexts.py__getattribute__(name)
|
||||||
@@ -128,4 +135,8 @@ def _to_stub(context):
|
|||||||
for c in stub_contexts
|
for c in stub_contexts
|
||||||
if c.is_class()
|
if c.is_class()
|
||||||
)
|
)
|
||||||
|
if was_bound_method:
|
||||||
|
# Now that the instance has been properly created, we can simply get
|
||||||
|
# the method.
|
||||||
|
stub_contexts = stub_contexts.py__getattribute__(method_name)
|
||||||
return stub_contexts
|
return stub_contexts
|
||||||
|
|||||||
@@ -358,6 +358,12 @@ def test_name_not_findable():
|
|||||||
assert jedi.Interpreter("X.NOT_FINDA", [locals()]).completions()
|
assert jedi.Interpreter("X.NOT_FINDA", [locals()]).completions()
|
||||||
|
|
||||||
|
|
||||||
|
def test_stubs_working():
|
||||||
|
from multiprocessing import cpu_count
|
||||||
|
defs = jedi.Interpreter("cpu_count()", [locals()]).goto_definitions()
|
||||||
|
assert [d.name for d in defs] == ['int']
|
||||||
|
|
||||||
|
|
||||||
def test_sys_path_docstring(): # Was an issue in #1298
|
def test_sys_path_docstring(): # Was an issue in #1298
|
||||||
import jedi
|
import jedi
|
||||||
s = jedi.Interpreter("from sys import path\npath", line=2, column=4, namespaces=[locals()])
|
s = jedi.Interpreter("from sys import path\npath", line=2, column=4, namespaces=[locals()])
|
||||||
|
|||||||
Reference in New Issue
Block a user