diff --git a/jedi/evaluate/compiled/access.py b/jedi/evaluate/compiled/access.py index 811b43d2..69c9f08f 100644 --- a/jedi/evaluate/compiled/access.py +++ b/jedi/evaluate/compiled/access.py @@ -275,17 +275,18 @@ class DirectObjectAccess(object): return False def is_allowed_getattr(self, name): + # TODO this API is ugly. try: attr, is_get_descriptor = getattr_static(self._obj, name) except AttributeError: - raise + return False, False else: if is_get_descriptor \ and not type(attr) in ALLOWED_DESCRIPTOR_ACCESS: # In case of descriptors that have get methods we cannot return # it's value, because that would mean code execution. - return False - return True + return True, True + return True, False def getattr(self, name, default=_sentinel): try: diff --git a/jedi/evaluate/compiled/context.py b/jedi/evaluate/compiled/context.py index 2b492b10..b48bf062 100644 --- a/jedi/evaluate/compiled/context.py +++ b/jedi/evaluate/compiled/context.py @@ -310,12 +310,13 @@ class CompiledObjectFilter(AbstractFilter): """ To remove quite a few access calls we introduced the callback here. """ - try: - if not allowed_getattr_callback(): - return [self._get_cached_name(name, is_empty=True)] - except AttributeError: + has_attribute, is_descriptor = allowed_getattr_callback() + if not has_attribute: return [] + if is_descriptor: + return [self._get_cached_name(name, is_empty=True)] + if self._is_instance and name not in dir_callback(): return [] return [self._get_cached_name(name)]