diff --git a/jedi/evaluate/compiled/access.py b/jedi/evaluate/compiled/access.py index 3b7109b5..2572c47c 100644 --- a/jedi/evaluate/compiled/access.py +++ b/jedi/evaluate/compiled/access.py @@ -233,6 +233,9 @@ class DirectObjectAccess(object): return self._create_access_path(self._obj[index]) def py__iter__list(self): + if not hasattr(self._obj, '__getitem__'): + return None + if type(self._obj) not in (str, list, tuple, unicode, bytes, bytearray, dict): # Get rid of side effects, we won't call custom `__getitem__`s. return [] diff --git a/jedi/evaluate/compiled/context.py b/jedi/evaluate/compiled/context.py index 4fef8f0b..cb52700f 100644 --- a/jedi/evaluate/compiled/context.py +++ b/jedi/evaluate/compiled/context.py @@ -157,11 +157,15 @@ class CompiledObject(Context): return ContextSet([create_from_access_path(self.evaluator, access)]) - @CheckAttribute() def py__getitem__(self, index_context_set, contextualized_node): + all_access_paths = self.access_handle.py__getitem__all_values() + if all_access_paths is None: + # This means basically that no __getitem__ has been defined on this + # object. + return super(CompiledObject, self).py__getitem__(index_context_set, contextualized_node) return ContextSet( create_from_access_path(self.evaluator, access) - for access in self.access_handle.py__getitem__all_values() + for access in all_access_paths ) def py__iter__(self, contextualized_node=None): @@ -173,7 +177,12 @@ class CompiledObject(Context): for x in super(CompiledObject, self).py__iter__(contextualized_node): yield x - for access in self.access_handle.py__iter__list(): + access_path_list = self.access_handle.py__iter__list() + if access_path_list is None: + # There is no __iter__ method on this object. + return + + for access in access_path_list: yield LazyKnownContext(create_from_access_path(self.evaluator, access)) def py__name__(self): diff --git a/test/test_evaluate/test_compiled.py b/test/test_evaluate/test_compiled.py index f9c2d9d5..b6749b43 100644 --- a/test/test_evaluate/test_compiled.py +++ b/test/test_evaluate/test_compiled.py @@ -92,3 +92,10 @@ def test_dict_values(Script, environment): # It looks like typeshed for Python 2 returns Any. pytest.skip() assert Script('import sys\nsys.modules["alshdb;lasdhf"]').goto_definitions() + + +def test_getitem_on_none(Script): + script = Script('None[1j]') + assert not script.goto_definitions() + issue, = script._evaluator.analysis + assert issue.name == 'type-error-not-subscriptable'