summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Liu <david@cs.toronto.edu>2021-08-15 13:08:45 -0400
committerPierre Sassoulas <pierre.sassoulas@gmail.com>2021-08-16 19:01:54 +0200
commitd277a4fca12e5e72ac439c410e8dfbaddccdfcc1 (patch)
tree9f0f39ca2a223a1460a9f82750122e6bc0415580
parenta874d9a82c39fac368d1283b5d9c9181810f3d3a (diff)
downloadpylint-git-d277a4fca12e5e72ac439c410e8dfbaddccdfcc1.tar.gz
Additional tests for PyCQA/astroid#1126
-rw-r--r--tests/functional/d/dataclass_with_default_factory.py32
-rw-r--r--tests/functional/d/dataclass_with_default_factory.txt2
-rw-r--r--tests/functional/i/invalid/invalid_name_issue_3405.py11
-rw-r--r--tests/functional/i/invalid/invalid_name_issue_3405.rc9
-rw-r--r--tests/functional/i/invalid/invalid_name_issue_3405.txt1
-rw-r--r--tests/functional/n/no/no_member_dataclasses.py83
-rw-r--r--tests/functional/n/no/no_member_dataclasses.rc2
-rw-r--r--tests/functional/n/no/no_member_dataclasses.txt2
-rw-r--r--tests/functional/t/too/too_many_instance_attributes.py19
-rw-r--r--tests/functional/t/too/too_many_instance_attributes.txt2
10 files changed, 160 insertions, 3 deletions
diff --git a/tests/functional/d/dataclass_with_default_factory.py b/tests/functional/d/dataclass_with_default_factory.py
index b01f38977..8f24d5e6e 100644
--- a/tests/functional/d/dataclass_with_default_factory.py
+++ b/tests/functional/d/dataclass_with_default_factory.py
@@ -1,6 +1,9 @@
-"""A test script the confuses pylint."""
-# https://github.com/PyCQA/pylint/issues/2605
+"""Various regression tests for dataclasses."""
+# See issues:
+# - https://github.com/PyCQA/pylint/issues/2605
+# - https://github.com/PyCQA/pylint/issues/2698
from dataclasses import dataclass, field
+import dataclasses as dc
@dataclass
@@ -13,3 +16,28 @@ class Test:
TEST = Test()
TEST.test.append(1)
print(TEST.test[0])
+
+
+@dc.dataclass # Note the use of dc instead of dataclasses
+class Test2:
+ """Test dataclass that uses a renamed import of dataclasses"""
+ int_prop: int = dc.field(default=10)
+ list_prop: list = dc.field(default_factory=list)
+ dict_prop: dict = dc.field(default_factory=dict)
+
+
+TEST2 = Test2()
+for _ in TEST2.list_prop: # This is okay
+ pass
+
+
+TEST2.dict_prop["key"] = "value" # This is okay
+
+
+# Test2.int_prop is inferred as 10, not a Field
+print(Test2.int_prop + 1)
+for _ in Test2.int_prop: # [not-an-iterable]
+ pass
+
+
+Test2.int_prop["key"] = "value" # [unsupported-assignment-operation]
diff --git a/tests/functional/d/dataclass_with_default_factory.txt b/tests/functional/d/dataclass_with_default_factory.txt
new file mode 100644
index 000000000..c33a7d3a4
--- /dev/null
+++ b/tests/functional/d/dataclass_with_default_factory.txt
@@ -0,0 +1,2 @@
+not-an-iterable:39:9::Non-iterable value Test2.int_prop is used in an iterating context:HIGH
+unsupported-assignment-operation:43:0::'Test2.int_prop' does not support item assignment:HIGH
diff --git a/tests/functional/i/invalid/invalid_name_issue_3405.py b/tests/functional/i/invalid/invalid_name_issue_3405.py
new file mode 100644
index 000000000..9b0dd37cd
--- /dev/null
+++ b/tests/functional/i/invalid/invalid_name_issue_3405.py
@@ -0,0 +1,11 @@
+""" Regression test for https://github.com/PyCQA/pylint/issues/3405. """
+
+import dataclasses
+from typing import ClassVar
+
+
+@dataclasses.dataclass
+class Foo:
+ """ClassVar attribute should be matched against class-attribute-rgx, not attr-rgx"""
+ # class-attribute-rgx='^y$'
+ x: ClassVar[int] = 0 # [invalid-name]
diff --git a/tests/functional/i/invalid/invalid_name_issue_3405.rc b/tests/functional/i/invalid/invalid_name_issue_3405.rc
new file mode 100644
index 000000000..c8bdd0efd
--- /dev/null
+++ b/tests/functional/i/invalid/invalid_name_issue_3405.rc
@@ -0,0 +1,9 @@
+[MESSAGES CONTROL]
+enable=invalid-name
+
+[BASIC]
+attr-rgx=^x$
+class-attribute-rgx=^y$
+
+[testoptions]
+min_pyver=3.7
diff --git a/tests/functional/i/invalid/invalid_name_issue_3405.txt b/tests/functional/i/invalid/invalid_name_issue_3405.txt
new file mode 100644
index 000000000..999137e42
--- /dev/null
+++ b/tests/functional/i/invalid/invalid_name_issue_3405.txt
@@ -0,0 +1 @@
+invalid-name:11:4:Foo:"Class attribute name ""x"" doesn't conform to '^y$' pattern":HIGH
diff --git a/tests/functional/n/no/no_member_dataclasses.py b/tests/functional/n/no/no_member_dataclasses.py
new file mode 100644
index 000000000..972da9ad9
--- /dev/null
+++ b/tests/functional/n/no/no_member_dataclasses.py
@@ -0,0 +1,83 @@
+"""Test various regressions for dataclasses and no-member.
+"""
+# pylint: disable=missing-docstring, too-few-public-methods
+from abc import ABCMeta, abstractmethod
+from dataclasses import asdict, dataclass, field
+from typing import Any, Dict
+
+
+# https://github.com/PyCQA/pylint/issues/3754
+@dataclass(frozen=True)
+class DeploymentState(metaclass=ABCMeta):
+ type: str
+
+ @abstractmethod
+ def to_dict(self) -> Dict:
+ """
+ Serializes given DeploymentState instance to Dict.
+ :return:
+ """
+
+
+@dataclass(frozen=True)
+class DeploymentStateEcs(DeploymentState):
+ blue: Any
+ green: Any
+ candidate: Any
+
+ def to_dict(self) -> Dict:
+ return {
+ 'type': self.type, # No error here
+ 'blue': asdict(self.blue),
+ 'green': asdict(self.green),
+ 'candidate': self.candidate.value,
+ }
+
+
+@dataclass(frozen=True)
+class DeploymentStateLambda(DeploymentState):
+ current: Any
+ candidate: Any
+
+ def to_dict(self) -> Dict:
+ return {
+ 'type': self.type, # No error here
+ 'current': asdict(self.current),
+ 'candidate': asdict(self.candidate) if self.candidate else None,
+ }
+
+
+# https://github.com/PyCQA/pylint/issues/2600
+@dataclass
+class TestClass:
+ attr1: str
+ attr2: str
+ dict_prop: Dict[str, str] = field(default_factory=dict)
+
+ def some_func(self) -> None:
+ for key, value in self.dict_prop.items(): # No error here
+ print(key)
+ print(value)
+
+
+class TestClass2: # not a dataclass, field inferred to a Field
+ attr1: str
+ attr2: str
+ dict_prop: Dict[str, str] = field(default_factory=dict)
+
+ def some_func(self) -> None:
+ for key, value in self.dict_prop.items(): # [no-member]
+ print(key)
+ print(value)
+
+
+@dataclass
+class TestClass3:
+ attr1: str
+ attr2: str
+ dict_prop = field(default_factory=dict) # No type annotation, not treated as field
+
+ def some_func(self) -> None:
+ for key, value in self.dict_prop.items(): # [no-member]
+ print(key)
+ print(value)
diff --git a/tests/functional/n/no/no_member_dataclasses.rc b/tests/functional/n/no/no_member_dataclasses.rc
new file mode 100644
index 000000000..a17bb22da
--- /dev/null
+++ b/tests/functional/n/no/no_member_dataclasses.rc
@@ -0,0 +1,2 @@
+[testoptions]
+min_pyver=3.7
diff --git a/tests/functional/n/no/no_member_dataclasses.txt b/tests/functional/n/no/no_member_dataclasses.txt
new file mode 100644
index 000000000..ffa499e71
--- /dev/null
+++ b/tests/functional/n/no/no_member_dataclasses.txt
@@ -0,0 +1,2 @@
+no-member:69:26:TestClass2.some_func:Instance of 'Field' has no 'items' member:INFERENCE
+no-member:81:26:TestClass3.some_func:Instance of 'Field' has no 'items' member:INFERENCE
diff --git a/tests/functional/t/too/too_many_instance_attributes.py b/tests/functional/t/too/too_many_instance_attributes.py
index f6703e0b7..11ddb915a 100644
--- a/tests/functional/t/too/too_many_instance_attributes.py
+++ b/tests/functional/t/too/too_many_instance_attributes.py
@@ -1,4 +1,6 @@
# pylint: disable=missing-docstring, too-few-public-methods, useless-object-inheritance
+from dataclasses import dataclass, InitVar
+
class Aaaa(object): # [too-many-instance-attributes]
@@ -24,3 +26,20 @@ class Aaaa(object): # [too-many-instance-attributes]
self._iiii = 9
self._jjjj = 10
self.tomuch = None
+
+
+# InitVars should not count as instance attributes (see issue #3754)
+# Default max_instance_attributes is 7
+@dataclass
+class Hello:
+ a_1: int
+ a_2: int
+ a_3: int
+ a_4: int
+ a_5: int
+ a_6: int
+ a_7: int
+ a_8: InitVar[int]
+
+ def __post_init__(self, a_8):
+ self.a_1 += a_8
diff --git a/tests/functional/t/too/too_many_instance_attributes.txt b/tests/functional/t/too/too_many_instance_attributes.txt
index 42c85493c..e9be267c0 100644
--- a/tests/functional/t/too/too_many_instance_attributes.txt
+++ b/tests/functional/t/too/too_many_instance_attributes.txt
@@ -1 +1 @@
-too-many-instance-attributes:3:0:Aaaa:Too many instance attributes (21/7)
+too-many-instance-attributes:5:0:Aaaa:Too many instance attributes (21/7):HIGH