diff --git a/jedi/inference/base_value.py b/jedi/inference/base_value.py index 37d17553..4128cffc 100644 --- a/jedi/inference/base_value.py +++ b/jedi/inference/base_value.py @@ -80,7 +80,11 @@ class HelperValueMixin(object): f = finder.NameFinder(self.inference_state, self, name_context, name_or_str, position, analysis_errors=analysis_errors) filters = self._get_value_filters(name_or_str) - return f.find(filters, attribute_lookup=True) + values = f.find(filters, attribute_lookup=True) + if not values: + n = name_or_str.value if isinstance(name_or_str, Name) else name_or_str + values = self.py__getattribute__alternatives(n) + return values def goto(self, name_or_str, name_context=None, analysis_errors=True): """ @@ -226,6 +230,12 @@ class Value(HelperValueMixin, BaseValue): debug.warning("Not possible to return the stop iterations of %s", self) return NO_VALUES + def py__getattribute__alternatives(self, name_or_str): + """ + For now a way to add values in cases like __getattr__. + """ + return NO_VALUES + def get_qualified_names(self): # Returns Optional[Tuple[str, ...]] return None diff --git a/jedi/inference/value/instance.py b/jedi/inference/value/instance.py index 97ec310b..8761de4f 100644 --- a/jedi/inference/value/instance.py +++ b/jedi/inference/value/instance.py @@ -311,17 +311,16 @@ class TreeInstance(AbstractInstanceValue): for signature in init.get_signatures(): yield signature.value - def py__getattribute__(self, name_or_str, *args, **kwargs): - inferred = super(AbstractInstanceValue, self).py__getattribute__( - name_or_str, *args, **kwargs) - if inferred or self.is_stub(): - return inferred + def py__getattribute__alternatives(self, string_name): + ''' + Since nothing was inferred, now check the __getattr__ and + __getattribute__ methods. Stubs don't need to be checked, because + they don't contain any logic. + ''' + if self.is_stub(): + return NO_VALUES - # Since nothing was inferred, now check the __getattr__ and - # __getattribute__ methods. Stubs don't need to be checked, because - # they don't contain any logic. - n = name_or_str.value if isinstance(name_or_str, Name) else name_or_str - name = compiled.create_simple_object(self.inference_state, n) + name = compiled.create_simple_object(self.inference_state, string_name) # This is a little bit special. `__getattribute__` is in Python # executed before `__getattr__`. But: I know no use case, where