forked from VimPlug/jedi
Fix issues with getitem on compiled objects that have annotations, see #1719
This commit is contained in:
@@ -211,7 +211,22 @@ class DirectObjectAccess:
|
|||||||
def py__getitem__all_values(self):
|
def py__getitem__all_values(self):
|
||||||
if isinstance(self._obj, dict):
|
if isinstance(self._obj, dict):
|
||||||
return [self._create_access_path(v) for v in self._obj.values()]
|
return [self._create_access_path(v) for v in self._obj.values()]
|
||||||
return self.py__iter__list()
|
if isinstance(self._obj, (list, tuple)):
|
||||||
|
return [self._create_access_path(v) for v in self._obj]
|
||||||
|
|
||||||
|
if self.is_instance():
|
||||||
|
cls = DirectObjectAccess(self._inference_state, self._obj.__class__)
|
||||||
|
return cls.py__getitem__all_values()
|
||||||
|
|
||||||
|
try:
|
||||||
|
getitem = self._obj.__getitem__
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
annotation = DirectObjectAccess(self._inference_state, getitem).get_return_annotation()
|
||||||
|
if annotation is not None:
|
||||||
|
return [annotation]
|
||||||
|
return None
|
||||||
|
|
||||||
def py__simple_getitem__(self, index):
|
def py__simple_getitem__(self, index):
|
||||||
if type(self._obj) not in ALLOWED_GETITEM_TYPES:
|
if type(self._obj) not in ALLOWED_GETITEM_TYPES:
|
||||||
@@ -221,8 +236,14 @@ class DirectObjectAccess:
|
|||||||
return self._create_access_path(self._obj[index])
|
return self._create_access_path(self._obj[index])
|
||||||
|
|
||||||
def py__iter__list(self):
|
def py__iter__list(self):
|
||||||
if not hasattr(self._obj, '__getitem__'):
|
try:
|
||||||
|
iter_method = self._obj.__iter__
|
||||||
|
except AttributeError:
|
||||||
return None
|
return None
|
||||||
|
else:
|
||||||
|
p = DirectObjectAccess(self._inference_state, iter_method).get_return_annotation()
|
||||||
|
if p is not None:
|
||||||
|
return [p]
|
||||||
|
|
||||||
if type(self._obj) not in ALLOWED_GETITEM_TYPES:
|
if type(self._obj) not in ALLOWED_GETITEM_TYPES:
|
||||||
# Get rid of side effects, we won't call custom `__getitem__`s.
|
# Get rid of side effects, we won't call custom `__getitem__`s.
|
||||||
|
|||||||
@@ -166,7 +166,7 @@ class CompiledValue(Value):
|
|||||||
except AttributeError:
|
except AttributeError:
|
||||||
return super().py__simple_getitem__(index)
|
return super().py__simple_getitem__(index)
|
||||||
if access is None:
|
if access is None:
|
||||||
return NO_VALUES
|
return super().py__simple_getitem__(index)
|
||||||
|
|
||||||
return ValueSet([create_from_access_path(self.inference_state, access)])
|
return ValueSet([create_from_access_path(self.inference_state, access)])
|
||||||
|
|
||||||
|
|||||||
@@ -603,8 +603,11 @@ def test_dict_getitem(code, types):
|
|||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
'code, expected', [
|
'code, expected', [
|
||||||
('DunderCls()[0]', 'int'),
|
('DunderCls()[0]', 'int'),
|
||||||
|
('dunder[0]', 'int'),
|
||||||
('next(DunderCls())', 'float'),
|
('next(DunderCls())', 'float'),
|
||||||
|
('next(dunder)', 'float'),
|
||||||
('for x in DunderCls(): x', 'str'),
|
('for x in DunderCls(): x', 'str'),
|
||||||
|
#('for x in dunder: x', 'str'),
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
def test_dunders(class_is_findable, code, expected):
|
def test_dunders(class_is_findable, code, expected):
|
||||||
@@ -623,6 +626,8 @@ def test_dunders(class_is_findable, code, expected):
|
|||||||
if not class_is_findable:
|
if not class_is_findable:
|
||||||
DunderCls.__name__ = 'asdf'
|
DunderCls.__name__ = 'asdf'
|
||||||
|
|
||||||
|
dunder = DunderCls()
|
||||||
|
|
||||||
n, = jedi.Interpreter(code, [locals()]).infer()
|
n, = jedi.Interpreter(code, [locals()]).infer()
|
||||||
assert n.name == expected
|
assert n.name == expected
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user