Pylint: false positive: unsupported-membership-test

Created on 5 Aug 2019  路  5Comments  路  Source: PyCQA/pylint

Steps to reproduce

# pylint: disable=missing-docstring,too-few-public-methods

class MyClass:
    _all = None

    @classmethod
    def all(cls):
        if not cls._all:
            cls._all = find_all()
        return cls._all

    @classmethod
    def exist(cls, number):
        return number in cls.all()

def find_all():
    return [1, 2, 3]


if __name__ == '__main__':
    assert MyClass.exist(2)

Current behavior

************* Module clsmemb
clsmemb.py:14:25: E1135: Value 'cls.all()' doesn't support membership test (unsupported-membership-test)

Expected behavior

--------------------------------------------------------------------
Your code has been rated at 10.00/10 (previous run: 10.00/10, +0.00)

pylint --version output

pylint 2.3.1
astroid 2.2.5
Python 3.7.3 (default, Apr 24 2019, 15:29:51) [MSC v.1915 64 bit (AMD64)]
bug topic-control-flow

Most helpful comment

Also bumped into this. Even simpler example to reproduce:

from typing import Optional, Tuple

prop = None  # type: Optional[Tuple]

exists = prop and 'a' in prop

Out:

violation.py:5:27: E1135: Value 'prop' doesn't support membership test (unsupported-membership-test)

All 5 comments

This looks like an issue that could be solved with better control flow inference, so that pylint could know that all could be either None or some other iterable value.

I'm not sure if it's the same issue or a separate one, but I'm also getting this false positive with subprocess.check_output on pylint 2.3.1 and astroid 2.2.5 (old Python version, though - 3.5.3 on Debian 9):

```$ cat check_pylint_e1135.py
import subprocess

bytes_data = subprocess.check_output(['echo', 'hello']);
text_data = subprocess.check_output(['echo', 'hello'], universal_newlines=True);

print(b'bytes' in bytes_data) # Prints False
print('text' in text_data) # Prints False
'text' in bytes_data # Runtime TypeError
b'bytes' in text_data # Runtime TypeError


$ pylint -E check_pylint_e1135.py
*** Module check_pylint_e1135
check_pylint_e1135.py:6:18: E1135: Value 'bytes_data' doesn't support membership test (unsupported-membership-test)
check_pylint_e1135.py:7:16: E1135: Value 'text_data' doesn't support membership test (unsupported-membership-test)
check_pylint_e1135.py:8:10: E1135: Value 'bytes_data' doesn't support membership test (unsupported-membership-test)
check_pylint_e1135.py:9:12: E1135: Value 'text_data' doesn't support membership test (unsupported-membership-test)
```

Thanks for that report @ncoghlan It's probably a separate issue which we can resolve easier with a brain transform https://github.com/PyCQA/astroid/tree/master/astroid/brain so it's probably better to move the report to a separate issue.

Also bumped into this. Even simpler example to reproduce:

from typing import Optional, Tuple

prop = None  # type: Optional[Tuple]

exists = prop and 'a' in prop

Out:

violation.py:5:27: E1135: Value 'prop' doesn't support membership test (unsupported-membership-test)

Equally adapting the code from the example above also generates a false positive for unsubscriptable-object in both Python 2, and Python 3 on latest version.

Python 2 & Pylint 1.6.5:

from typing import Optional

prop = None  # type: Optional[dict]

if prop and 'a' in prop:
    thing = prop['a']

Python 3 & Pylint 2.5.3:

from typing import Optional

prop: Optional[dict] = None

if prop and 'a' in prop:
    thing = prop['a']
Was this page helpful?
1 / 5 - 1 ratings