How to suppress warning "Access to protected member" in pycharm method?

Question:

I have some class

class A(object):
    def __init__(self, data):
        self._data = data
    def _equals(self, other):
        return self._data == other._data

Pycharm doesn’t like that I access other._data because it is private.

“Access to protected member”

This doesn’t make sense to me, because the access is made from within the class.

How do I either suppress this warning, or write correct code?

Asked By: Gulzar

||

Answers:

If you really need it, like namedlist‘s ._asdict(), the answer is Can I get PyCharm to suppress a particular warning on a single line?:

class A(object):
    def __init__(self, data):
        self._data = data
    def _equals(self, other):
        # noinspection PyProtectedMember
        return self._data == other._data
Answered By: Polv

Python 3.5+ answer (Type hints introduced):

from __future__ import annotations


class A(object):
    def __init__(self, data):
        self._data = data

    def _equals(self, other: A):
        return self._data == other._data

Using type hints as suggested by @Giacomo Alzetta, and allowing to type hint the class itself using from __future__ import annotations.

No need to hack PyCharm anymore or write ugly comments.


As also noted by @jonrsharpe, python 2 also supports type hints via docstrings.
I will not post this here as I support Python 2 losing support.

Answered By: Gulzar

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
Answered By: MestreLion
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.