diff --git a/jedi/evaluate/representation.py b/jedi/evaluate/representation.py index 81847ae4..4dc35c11 100644 --- a/jedi/evaluate/representation.py +++ b/jedi/evaluate/representation.py @@ -318,9 +318,10 @@ class Class(use_metaclass(CachedMetaClass, pr.IsScope)): return result + list(type_cls.get_defined_names()) def get_subscope_by_name(self, name): - for sub in reversed(self.subscopes): - if sub.name.get_code() == name: - return sub + for s in [self] + self.get_super_classes(): + for sub in reversed(s.subscopes): + if sub.name.get_code() == name: + return sub raise KeyError("Couldn't find subscope.") def is_callable(self): diff --git a/test/static_analysis/attribute_warnings.py b/test/static_analysis/attribute_warnings.py new file mode 100644 index 00000000..73a9f2b3 --- /dev/null +++ b/test/static_analysis/attribute_warnings.py @@ -0,0 +1,24 @@ +""" +Jedi issues warnings for possible errors if ``__getattr__``, +``__getattribute__`` or ``setattr`` are used. +""" + + +class Cls(): + def __getattr__(self, name): + return getattr(str, name) + + +Cls().upper + +#! 6 warning attribute-error +Cls().undefined + + +class Inherited(Cls): + pass + +Inherited().upper + +#! 12 warning attribute-error +Inherited().undefined