Open larsch opened 5 years ago
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):
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']
It might be worth to add that the pylint-issues reported from these minimal examples might be caused by the fixed assignment of None, in which case the type of prop can be inferred as NoneType and hence the warnings are correct.
from secrets import choice
from typing import Optional, Tuple
prop = choice([None, (None, )]) # type: Optional[Tuple]
exists = prop and 'a' in prop
does not produce a pylint issue.
Edit: For those landing here from a search engine: The issue from the initial example can be avoided by initializing _all = []
and avoiding None
if there is no need to distinguish between the two values.
Another example, this time with a loop and TypedDict
:
from typing import Optional, TypedDict
class ADict(TypedDict):
a: int
x: Optional[ADict] = None
while x is None or 'a' in x:
print('test')
# `x` gets assigned in the loop.
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)
I'm having this exact same problem for both unsupported-assignment-operation
and unsupported-membership-test
. Has there been any movement on getting this fixed? Looks to be a pretty old bug/FP
I believe my issue is the same. I'm running into it here:
I get the error from line 7 in this abbreviated code...
class MaintainedModel(Model):
class_label_filters: Optional[List[str]] = None
def __init__(self, *args, **kwargs):
self.label_filters = self.class_label_filters
def update_decorated_fields(self):
if self.label_filters is not None and "name" in self.label_filters:
...
Is there some way I should change my code to prevent the error? Funny thing is, I wasn't getting the error until I made an innocuous refactor of the code (to change global_label_filters to a class attribute (class_label_filters) with a type hint. There are other such variables without the error and the code works as intended...
Another recent example
from pydantic.v1.dataclasses import BaseModel, Field
class Foo(BaseModel):
my_list: list[str] = Field(default_factory=list)
The above started failing after a un-related refactor on pydantic v2 from my_list: list[str] = []
to use default_factory
instead(to avoid a mutable default list)
'my_list' doesn't support membership test (unsupported-membership-test)
The type hints still specify it as a list.
Hi All! I ran into this (or something very similar) yesterday, when I tried to perform lazy initialization on some dicts. Here is a simplified example, I guess it is the same issue.
Example code:
# pylint: disable=C0114, C0115, R0903
####
# Case 1 (no class involved, works).
da: dict[str, str] | None = None # None at the beginning
da = {'a': 'Hello'} # Lazy initialization on demand
if 'a' in da: # OK
print(da['a']) # OK
da['a'] = "Hi" # OK
####
# Case 2 (class involved, error).
class MyClass:
db: dict[str, str] | None = None # None at the beginning
MyClass.db = {'b': 'World'} # Lazy initialization on demand
if 'b' in MyClass.db: # E1135
print(MyClass.db['b']) # E1136
MyClass.db['b'] = 'America' # E1137
####
pylint result:
example.py:20:10: E1135: Value 'MyClass.db' doesn't support membership test (unsupported-membership-test)
example.py:21:10: E1136: Value 'MyClass.db' is unsubscriptable (unsubscriptable-object)
example.py:22:0: E1137: 'MyClass.db' does not support item assignment (unsupported-assignment-operation)
pylint version (running on Ubuntu 22.04 LTS 64-bit):
pylint 3.2.7
astroid 3.2.4
Python 3.10.12 (main, Jul 29 2024, 16:56:48) [GCC 11.4.0]
The two main points of this example are probably:
To answer your question @hepcat72 (I know it's fairly outdated, but may still be relevant to you or to others): The way I see it now, it is a pylint issue, I'd leave the code as is and wait for the pylint fix to arrive.
If this is the same issue (is it?), should we update the title? This is not just about unsupported membership test (E1135) then...
Steps to reproduce
Current behavior
Expected behavior
pylint --version output