Skip to content

Commit

Permalink
Additional tests for pylint-dev/astroid#1126
Browse files Browse the repository at this point in the history
  • Loading branch information
david-yz-liu authored and Pierre-Sassoulas committed Aug 15, 2021
1 parent ba459f7 commit 254824e
Show file tree
Hide file tree
Showing 10 changed files with 160 additions and 3 deletions.
32 changes: 30 additions & 2 deletions tests/functional/d/dataclass_with_default_factory.py
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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]
2 changes: 2 additions & 0 deletions tests/functional/d/dataclass_with_default_factory.txt
Original file line number Diff line number Diff line change
@@ -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
11 changes: 11 additions & 0 deletions tests/functional/i/invalid/invalid_name_issue_3405.py
Original file line number Diff line number Diff line change
@@ -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]
9 changes: 9 additions & 0 deletions tests/functional/i/invalid/invalid_name_issue_3405.rc
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[MESSAGES CONTROL]
enable=invalid-name

[BASIC]
attr-rgx=^x$
class-attribute-rgx=^y$

[testoptions]
min_pyver=3.7
1 change: 1 addition & 0 deletions tests/functional/i/invalid/invalid_name_issue_3405.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
invalid-name:11:4:Foo:"Class attribute name ""x"" doesn't conform to '^y$' pattern":HIGH
83 changes: 83 additions & 0 deletions tests/functional/n/no/no_member_dataclasses.py
Original file line number Diff line number Diff line change
@@ -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)
2 changes: 2 additions & 0 deletions tests/functional/n/no/no_member_dataclasses.rc
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[testoptions]
min_pyver=3.7
2 changes: 2 additions & 0 deletions tests/functional/n/no/no_member_dataclasses.txt
Original file line number Diff line number Diff line change
@@ -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
19 changes: 19 additions & 0 deletions tests/functional/t/too/too_many_instance_attributes.py
Original file line number Diff line number Diff line change
@@ -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]

Expand All @@ -24,3 +26,20 @@ def __init__(self):
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
2 changes: 1 addition & 1 deletion tests/functional/t/too/too_many_instance_attributes.txt
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit 254824e

Please sign in to comment.