Skip to content

Commit

Permalink
Recognize new-style attrs decorators in too-few-public-methods check (#…
Browse files Browse the repository at this point in the history
…9346)

Beginning with attrs 21.1.0, the recommended way to use attrs is through
`import attrs` and using `attrs.define`/`attrs.frozen`, not `import
attr` and `attr.s` or `attr.attrs`. Pylint does understand `attr.attrs`
(#2988), but new-style uses of attrs are not understood to be data class
decorators.

Modify `_is_exempt_from_public_methods` to recognize `attrs.define` and
`attrs.frozen` in a similar way as is currently done with
`dataclasses.dataclass`.

Closes #9345.
  • Loading branch information
akirchhoff-modular authored May 4, 2024
1 parent 3c8be8e commit c032181
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 0 deletions.
4 changes: 4 additions & 0 deletions doc/whatsnew/fragments/9345.false_positive
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Treat `attrs.define` and `attrs.frozen` as dataclass decorators in
`too-few-public-methods` check.

Closes #9345
6 changes: 6 additions & 0 deletions pylint/checkers/design_analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@
SPECIAL_OBJ = re.compile("^_{2}[a-z]+_{2}$")
DATACLASSES_DECORATORS = frozenset({"dataclass", "attrs"})
DATACLASS_IMPORT = "dataclasses"
ATTRS_DECORATORS = frozenset({"define", "frozen"})
ATTRS_IMPORT = "attrs"
TYPING_NAMEDTUPLE = "typing.NamedTuple"
TYPING_TYPEDDICT = "typing.TypedDict"
TYPING_EXTENSIONS_TYPEDDICT = "typing_extensions.TypedDict"
Expand Down Expand Up @@ -214,6 +216,10 @@ def _is_exempt_from_public_methods(node: astroid.ClassDef) -> bool:
or DATACLASS_IMPORT in root_locals
):
return True
if name in ATTRS_DECORATORS and (
root_locals.intersection(ATTRS_DECORATORS) or ATTRS_IMPORT in root_locals
):
return True
return False


Expand Down
27 changes: 27 additions & 0 deletions tests/functional/t/too/too_few_public_methods_37.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
import typing
from dataclasses import dataclass

import attrs # pylint: disable=import-error
from attrs import define, frozen # pylint: disable=import-error


@dataclasses.dataclass
class ScheduledTxSearchModel:
Expand Down Expand Up @@ -40,3 +43,27 @@ class Point:
def to_array(self):
"""Convert to a NumPy array `np.array((x, y, z))`."""
return self.attr1


@define
class AttrsBarePoint:
x: float
y: float


@frozen
class AttrsBareFrozenPoint:
x: float
y: float


@attrs.define
class AttrsQualifiedPoint:
x: float
y: float


@attrs.frozen
class AttrsQualifiedFrozenPoint:
x: float
y: float

0 comments on commit c032181

Please sign in to comment.