From 3207eb6960db1423cc124a88498aaf62654f91d8 Mon Sep 17 00:00:00 2001 From: sobolevn Date: Thu, 19 Dec 2024 11:05:37 +0300 Subject: [PATCH] `WPS230`: Allow any number of attributes in `@dataclass`, closes #2448 --- CHANGELOG.md | 1 + .../test_classes/test_public_attrs_count.py | 24 +++++++++++++++++++ .../violations/complexity.py | 2 ++ .../visitors/ast/complexity/classes.py | 3 +++ 4 files changed, 30 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index fbc0ba9fa..79c94e083 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -86,6 +86,7 @@ Semantic versioning in our case means: - Allows underscores (`_`) with exactly 3 digits after it in `WPS303`, #3120 - Allows class / instance attribute shadowing in `@dataclass`es for `WPS601`, #1926 +- Allows any number of instance attributes on `@dataclass`es in `WPS230`, #2448 - Adds new rule to forbid `lambda` assigns to special attributes, #1733 - Adds new rule to check problematic function params, #1343 - Adds new rule to detect duplicate conditions in `if`s and `elif`s, #2241 diff --git a/tests/test_visitors/test_ast/test_complexity/test_classes/test_public_attrs_count.py b/tests/test_visitors/test_ast/test_complexity/test_classes/test_public_attrs_count.py index b141b6e25..55db83cc4 100644 --- a/tests/test_visitors/test_ast/test_complexity/test_classes/test_public_attrs_count.py +++ b/tests/test_visitors/test_ast/test_complexity/test_classes/test_public_attrs_count.py @@ -16,6 +16,26 @@ def other(self): {1} """ +dataclass_template = """ +@dataclass +class Test: + def __init__(self): + {0} + + def other(self): + {1} +""" + +not_a_dataclass_template = """ +@not_a_dataclass +class Test: + def __init__(self): + {0} + + def other(self): + {1} +""" + module_template = """ {0} {1} @@ -32,6 +52,8 @@ def some(): 'code', [ class_template, + dataclass_template, + not_a_dataclass_template, module_template, function_template, ], @@ -78,6 +100,7 @@ def test_correct_attributes( 'code', [ class_template, + not_a_dataclass_template, ], ) @pytest.mark.parametrize( @@ -112,6 +135,7 @@ def test_wrong_attributes_count( @pytest.mark.parametrize( 'code', [ + dataclass_template, module_template, function_template, ], diff --git a/wemake_python_styleguide/violations/complexity.py b/wemake_python_styleguide/violations/complexity.py index c93da9b99..f6c8b8365 100644 --- a/wemake_python_styleguide/violations/complexity.py +++ b/wemake_python_styleguide/violations/complexity.py @@ -1007,6 +1007,8 @@ class TooManyPublicAttributesViolation(ASTViolation): https://en.wikipedia.org/wiki/Coupling_(computer_programming) .. versionadded:: 0.12.0 + .. versionchanged:: 1.0.0 + Any amount of attributes are allowed on ``@dataclasses``. """ diff --git a/wemake_python_styleguide/visitors/ast/complexity/classes.py b/wemake_python_styleguide/visitors/ast/complexity/classes.py index 76331b78b..bc405f7d5 100644 --- a/wemake_python_styleguide/visitors/ast/complexity/classes.py +++ b/wemake_python_styleguide/visitors/ast/complexity/classes.py @@ -53,6 +53,9 @@ def _check_base_classes(self, node: ast.ClassDef) -> None: ) def _check_public_attributes(self, node: ast.ClassDef) -> None: + if classes.is_dataclass(node): + return # dataclasses can have any amount of attributes + _, instance_attributes = classes.get_attributes( node, include_annotated=False,