Skip to content

Commit f420f28

Browse files
committed
Suggest keyword attributes
1 parent 9ba694b commit f420f28

File tree

3 files changed

+20
-20
lines changed

3 files changed

+20
-20
lines changed

doc/user_guide/checkers/features.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -697,7 +697,7 @@ Match Statements checker Messages
697697
:match-class-bind-self (R1905): *Use '%s() as %s' instead*
698698
Match class patterns are faster if the name binding happens for the whole
699699
pattern and any lookup for `__match_args__` can be avoided.
700-
:match-class-positional-attributes (R1906): *Use keyword attributes instead of positional ones*
700+
:match-class-positional-attributes (R1906): *Use keyword attributes instead of positional ones (%s)*
701701
Keyword attributes are more explicit and slightly faster since CPython can
702702
skip the `__match_args__` lookup.
703703

pylint/checkers/match_statements_checker.py

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ class MatchStatementChecker(BaseChecker):
7171
"can be avoided.",
7272
),
7373
"R1906": (
74-
"Use keyword attributes instead of positional ones",
74+
"Use keyword attributes instead of positional ones (%s)",
7575
"match-class-positional-attributes",
7676
"Keyword attributes are more explicit and slightly faster "
7777
"since CPython can skip the `__match_args__` lookup.",
@@ -184,22 +184,6 @@ def visit_matchclass(self, node: nodes.MatchClass) -> None:
184184
attrs: set[str] = set()
185185
dups: set[str] = set()
186186

187-
if node.patterns:
188-
if isinstance(node, nodes.MatchClass) and isinstance(node.cls, nodes.Name):
189-
inferred = safe_infer(node.cls)
190-
if not (
191-
isinstance(inferred, nodes.ClassDef)
192-
and (
193-
inferred.qname() in MATCH_CLASS_SELF_NAMES
194-
or "tuple" in inferred.basenames
195-
)
196-
):
197-
self.add_message(
198-
"match-class-positional-attributes",
199-
node=node,
200-
confidence=INFERENCE,
201-
)
202-
203187
if (
204188
node.patterns
205189
and (match_args := self.get_match_args_for_class(node.cls)) is not None
@@ -213,6 +197,22 @@ def visit_matchclass(self, node: nodes.MatchClass) -> None:
213197
)
214198
return
215199

200+
inferred = safe_infer(node.cls)
201+
if not (
202+
isinstance(inferred, nodes.ClassDef)
203+
and (
204+
inferred.qname() in MATCH_CLASS_SELF_NAMES
205+
or "tuple" in inferred.basenames
206+
)
207+
):
208+
attributes = [f"'{attr}'" for attr in match_args[: len(node.patterns)]]
209+
self.add_message(
210+
"match-class-positional-attributes",
211+
node=node,
212+
args=(", ".join(attributes),),
213+
confidence=INFERENCE,
214+
)
215+
216216
for i in range(len(node.patterns)):
217217
name = match_args[i]
218218
self.check_duplicate_sub_patterns(name, node, attrs=attrs, dups=dups)

tests/functional/m/match_class_pattern.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,5 @@ multiple-class-sub-patterns:49:13:49:29:f2:Multiple sub-patterns for attribute x
99
undefined-variable:55:13:55:23:f2:Undefined variable 'NotDefined':UNDEFINED
1010
match-class-bind-self:60:17:60:18:f3:Use 'int() as y' instead:HIGH
1111
match-class-bind-self:63:17:63:18:f3:Use 'str() as y' instead:HIGH
12-
match-class-positional-attributes:75:13:75:17:f4:Use keyword attributes instead of positional ones:INFERENCE
13-
match-class-positional-attributes:77:13:77:20:f4:Use keyword attributes instead of positional ones:INFERENCE
12+
match-class-positional-attributes:75:13:75:17:f4:Use keyword attributes instead of positional ones ('x'):INFERENCE
13+
match-class-positional-attributes:77:13:77:20:f4:Use keyword attributes instead of positional ones ('x', 'y'):INFERENCE

0 commit comments

Comments
 (0)