Pylint: False Positive on E1101 no-member with property + inheritance + Generic

Created on 12 Jun 2020  路  5Comments  路  Source: PyCQA/pylint

Before I begin, I just want to say Pylint is awesome. When I update from Python 3.6.5 to Python 3.8.2, it helped me figure out which built-in libraries had their API's changed (ex: time.clock's removal).

However, when I updated from 3.6.5 to 3.8.2, I discovered a Pylint bug as well. I would like to report a false positive on E1101, no-member.

I have found that when using a certain combination of:

  • typing.Generic
  • property
  • Two subclassing's

That pylint erroneously reports no-member.

Steps to reproduce

In the below code, you can see:

  • base_property is a property
  • BaseClass is a subclass of Generic
  • base_property is type hinted with a TypeVar
  • BaseClass is subclassed twice --> GrandchildClass

    • One subclassing, and the false positive doesn't happen

#!/usr/bin/env python3

"""Testing pylint raising of no-member."""


from typing import TypeVar, Generic


TFloatInt = TypeVar("TFloatInt", int, float)


class BaseClass(Generic[TFloatInt]):

    @property
    def base_property(self) -> TFloatInt:
        return 1


class ChildClass(BaseClass[TFloatInt]):
    """A docstring."""


class GrandchildClass(BaseClass[int]):

    def grandchild_method(self) -> int:
        return self.base_property  # E1101: Instance of 'GrandchildClass' has no 'base_property' member (no-member)


if __name__ == "__main__":
    grandchild = GrandchildClass()
    print(grandchild.grandchild_method())

Pylint output:

/path/to/my_module.py:27:15: E1101: Instance of 'GrandchildClass' has no 'base_property' member (no-member)

At runtime, this code works fine.

Expected behavior

I believe the above code sample should not raise a no-member.

Note: this behavior depends on the Python version:

  • Does not happen for Python 3.6.5
  • Does happen for Python 3.8.2

pylint --version output

pylint 2.5.3
astroid 2.4.2
Python 3.8.2 (default, Jun 11 2020, 17:42:03)
[Clang 10.0.1 (clang-1001.0.46.4)]
bug topic-inference

All 5 comments

Happens with the collections.abc objects too, as they are aliased by the typing module.

from typing import MutableMapping


class test(MutableMapping[str, int]):
    def __init__(self):
        self._data = {}

    def __getitem__(self, key):
        return self._data[key]

    def __setitem__(self, key, value):
        self._data[key] = value

    def __delitem__(self, key):
        del self._data[key]

    def __iter__(self):
        return iter(self._data)

    def __len__(self):
        return len(self._data)


a = test()
a.keys()

Results in:

test.py:26:0: E1101: Instance of 'test' has no 'keys' member (no-member)

This might be the same issue:

from typing import MutableMapping

d = {"a": 0}

if isinstance(d, MutableMapping):
    print("It is!")

results in:

W1116: Second argument of isinstance is not a type (isinstance-second-argument-not-valid-type)

It seems like these generic types like MutableMapping are not being recognized correctly.

Could be related to #3131

Yes, I think that is very likely. I tried to implement a solution in Astroid, but while I figured out why it didn't work, it wasn't clear to me how Astroid's internals are supposed to operate. If someone with a better understanding of Astroid's internals could answer these questions, I could continue with the PR.

For my repro above, I believe this issue no longer happens in pylint 2.7. Still happens for @xrogaan's repro though.

Was this page helpful?
0 / 5 - 0 ratings