Skip to content

Commit

Permalink
Fix inference of properties in a class context
Browse files Browse the repository at this point in the history
Ref pylint-dev#940. If we are accessing an attribute and it is found on
type(A).__dict__ *and* it is a data descriptor, then we resolve that
descriptor. For the case of inferring a property which is accessed as a
class attribute, this equates to the property being defined on the
metaclass (which may be anywhere in the class hierarchy).
  • Loading branch information
nelfin committed May 11, 2021
1 parent 92f03f2 commit 2dd4196
Showing 1 changed file with 7 additions and 4 deletions.
11 changes: 7 additions & 4 deletions astroid/scoped_nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -2554,7 +2554,7 @@ def igetattr(self, name, context=None, class_context=True):
context = contextmod.copy_context(context)
context.lookupname = name

metaclass = self.declared_metaclass(context=context)
metaclass = self.metaclass(context=context)
try:
attributes = self.getattr(name, context, class_context=class_context)
# If we have more than one attribute, make sure that those starting from
Expand Down Expand Up @@ -2587,9 +2587,12 @@ def igetattr(self, name, context=None, class_context=True):
yield from function.infer_call_result(
caller=self, context=context
)
# If we have a metaclass, we're accessing this attribute through
# the class itself, which means we can solve the property
elif metaclass:
# If we're in a class context, we need to determine if the property
# was defined in the metaclass (a derived class must be a subclass of
# the metaclass of all its bases), in which case we can resolve the
# property. If not, i.e. the property is defined in some base class
# instead, then we return the property object
elif metaclass and function.parent.scope() is metaclass:
# Resolve a property as long as it is not accessed through
# the class itself.
yield from function.infer_call_result(
Expand Down

0 comments on commit 2dd4196

Please sign in to comment.