The comments in OP's question have a lot of great insight about the warning, proper fixes and best practices, most were unfortunately not mentioned by the current answers. So here it goes:
About the warning itself, OP says:
This doesn't make sense to me, because the access is made from within the class.
No, it is not. other
can be any class, not necessarily A
. So even if you only pass A
instances as other
, there's nothing in the code that indicates or enforces that.
Indication can be done with type hints, as explained by Gulzar's answer.
And there are some approaches for enforcing this:
- Force
other
's type to be A
(or a subclass): if not isinstance(other, A): return False
. This is the arguably the preferred way, but it does defeat Python's duck-typing.
- If instead of a regular method
_equals()
you're using one of the predefined "rich comparison" special methods such as __eq__()
, __lt__()
, __gt__()
, you can return a special value to give a chance to other
's class reflection method to handle the call: if not isinstance(other, A): return NotImplemented
- If you want to preserve duck-typing to allow unknown classes, and you're not using a private attribute such as
_data
(otherwise you'll still get the warning), you could use a try
-block to handle a missing attribute:
try:
return self.data == other.data
except AttributeError: # other has no .data
return False