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):
|
||||
if isinstance(self._obj, dict):
|
||||
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):
|
||||
if type(self._obj) not in ALLOWED_GETITEM_TYPES:
|
||||
@@ -221,8 +236,14 @@ class DirectObjectAccess:
|
||||
return self._create_access_path(self._obj[index])
|
||||
|
||||
def py__iter__list(self):
|
||||
if not hasattr(self._obj, '__getitem__'):
|
||||
try:
|
||||
iter_method = self._obj.__iter__
|
||||
except AttributeError:
|
||||
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:
|
||||
# Get rid of side effects, we won't call custom `__getitem__`s.
|
||||
|
||||
@@ -166,7 +166,7 @@ class CompiledValue(Value):
|
||||
except AttributeError:
|
||||
return super().py__simple_getitem__(index)
|
||||
if access is None:
|
||||
return NO_VALUES
|
||||
return super().py__simple_getitem__(index)
|
||||
|
||||
return ValueSet([create_from_access_path(self.inference_state, access)])
|
||||
|
||||
|
||||
@@ -603,8 +603,11 @@ def test_dict_getitem(code, types):
|
||||
@pytest.mark.parametrize(
|
||||
'code, expected', [
|
||||
('DunderCls()[0]', 'int'),
|
||||
('dunder[0]', 'int'),
|
||||
('next(DunderCls())', 'float'),
|
||||
('next(dunder)', 'float'),
|
||||
('for x in DunderCls(): x', 'str'),
|
||||
#('for x in dunder: x', 'str'),
|
||||
]
|
||||
)
|
||||
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:
|
||||
DunderCls.__name__ = 'asdf'
|
||||
|
||||
dunder = DunderCls()
|
||||
|
||||
n, = jedi.Interpreter(code, [locals()]).infer()
|
||||
assert n.name == expected
|
||||
|
||||
|
||||
Reference in New Issue
Block a user