1
0
forked from VimPlug/jedi

Fix issue with mixed objects, fixes #1480

This commit is contained in:
Dave Halter
2020-01-25 15:02:55 +01:00
parent 0435e0e85c
commit da2a55c73f
4 changed files with 27 additions and 5 deletions

View File

@@ -315,6 +315,9 @@ class DirectObjectAccess(object):
def is_class(self):
return inspect.isclass(self._obj)
def is_function(self):
return inspect.isfunction(self._obj) or inspect.ismethod(self._obj)
def is_module(self):
return inspect.ismodule(self._obj)

View File

@@ -14,7 +14,6 @@ from jedi.inference import compiled
from jedi.cache import underscore_memoization
from jedi.file_io import FileIO
from jedi.inference.base_value import ValueSet, ValueWrapper, NO_VALUES
from jedi.inference.helpers import SimpleGetItemNotFound
from jedi.inference.value import ModuleValue
from jedi.inference.cache import inference_state_function_cache, \
inference_state_method_cache
@@ -50,6 +49,9 @@ class MixedObject(ValueWrapper):
self.compiled_object = compiled_object
self.access_handle = compiled_object.access_handle
def get_tree_value(self):
return self._wrapped_value
def get_filters(self, *args, **kwargs):
yield MixedObjectFilter(self.inference_state, self)
@@ -76,7 +78,7 @@ class MixedObject(ValueWrapper):
python_object = self.compiled_object.access_handle.access._obj
if type(python_object) in ALLOWED_GETITEM_TYPES:
return self.compiled_object.py__simple_getitem__(index)
raise SimpleGetItemNotFound
return self._wrapped_value.py__simple_getitem__(index)
def _as_context(self):
if self.parent_context is None:
@@ -137,6 +139,17 @@ class MixedName(compiled.CompiledName):
default=None
)
assert len(access_paths)
tree_value = self._parent_value.get_tree_value()
if tree_value.is_instance() or tree_value.is_class():
from jedi.inference.compiled.value import _create_from_name
tree_values = tree_value.py__getattribute__(self.string_name)
compiled_object = _create_from_name(
self._inference_state,
self._parent_value.compiled_object,
self.string_name
)
if compiled_object.is_function():
return ValueSet({MixedObject(compiled_object, v) for v in tree_values})
values = [None]
for access in access_paths:
values = ValueSet.from_sets(access_to_value(v, access) for v in values)
@@ -310,7 +323,6 @@ def _create(inference_state, access_handle, parent_context, *args):
# Python's TypeVar('foo').__module__ will be typing.
return ValueSet({compiled_object})
module_context = parent_context.get_root_context()
tree_values = ValueSet({module_context.create_value(tree_node)})
if tree_node.type == 'classdef':
if not access_handle.is_class():

View File

@@ -95,6 +95,9 @@ class CompiledObject(Value):
def is_class(self):
return self.access_handle.is_class()
def is_function(self):
return self.access_handle.is_function()
def is_module(self):
return self.access_handle.is_module()

View File

@@ -42,10 +42,12 @@ def test_generics_without_definition():
@pytest.mark.parametrize(
'code, expected', [
('Foo.method()', 'int'),
('Foo.method()', 'int'),
('Foo().method()', 'str'),
('Foo.method()', 'str'),
('foo.method()', 'str'),
('Foo().read()', 'str'),
('Foo.read()', 'str'),
('foo.read()', 'str'),
]
)
def test_generics_methods(code, expected, class_findable):
@@ -63,6 +65,8 @@ def test_generics_methods(code, expected, class_findable):
def transform(self) -> int:
return 42
foo = Foo()
defs = jedi.Interpreter(code, [locals()]).infer()
if class_findable:
def_, = defs