Skip to content

Commit 6827dfe

Browse files
DanielNoordcdce8p
andauthored
Make self-cls-assignment check tuple assignment (#5268)
Co-authored-by: Marc Mueller <[email protected]>
1 parent 0a1ebd4 commit 6827dfe

File tree

5 files changed

+23
-20
lines changed

5 files changed

+23
-20
lines changed

ChangeLog

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,8 @@ Release date: TBA
127127

128128
Closes #4426
129129

130+
* ``self-cls-assignment`` now also considers tuple assignment
131+
130132
* Fix ``missing-function-docstring`` not being able to check ``__init__`` and other
131133
magic methods even if the ``no-docstring-rgx`` setting was set to do so
132134

doc/whatsnew/2.12.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,8 @@ Other Changes
112112

113113
Fixes part of #3688
114114

115+
* ``self-cls-assignment`` now also considers tuple assignment
116+
115117
* ``undefined-variable`` now correctly triggers for assignment expressions in if ... else statements
116118
This includes a basic form of control flow inference for if ... else statements using
117119
constant boolean values

pylint/checkers/variables.py

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@
6161
import re
6262
import sys
6363
from functools import lru_cache
64-
from typing import DefaultDict, List, Tuple
64+
from typing import DefaultDict, List, Optional, Set, Tuple
6565

6666
import astroid
6767
from astroid import nodes
@@ -2022,18 +2022,19 @@ def _store_type_annotation_names(self, node):
20222022
return
20232023
self._store_type_annotation_node(node.type_annotation)
20242024

2025-
def _check_self_cls_assign(self, node):
2025+
def _check_self_cls_assign(self, node: nodes.Assign) -> None:
20262026
"""Check that self/cls don't get assigned"""
2027-
assign_names = {
2028-
target.name
2029-
for target in node.targets
2030-
if isinstance(target, nodes.AssignName)
2031-
}
2027+
assign_names: Set[Optional[str]] = set()
2028+
for target in node.targets:
2029+
if isinstance(target, nodes.AssignName):
2030+
assign_names.add(target.name)
2031+
elif isinstance(target, nodes.Tuple):
2032+
assign_names.update(
2033+
elt.name for elt in target.elts if isinstance(elt, nodes.AssignName)
2034+
)
20322035
scope = node.scope()
20332036
nonlocals_with_same_name = any(
2034-
child
2035-
for child in scope.body
2036-
if isinstance(child, nodes.Nonlocal) and assign_names & set(child.names)
2037+
child for child in scope.body if isinstance(child, nodes.Nonlocal)
20372038
)
20382039
if nonlocals_with_same_name:
20392040
scope = node.scope().parent.scope()
@@ -2048,12 +2049,7 @@ def _check_self_cls_assign(self, node):
20482049
if not argument_names:
20492050
return
20502051
self_cls_name = argument_names[0]
2051-
target_assign_names = (
2052-
target.name
2053-
for target in node.targets
2054-
if isinstance(target, nodes.AssignName)
2055-
)
2056-
if self_cls_name in target_assign_names:
2052+
if self_cls_name in assign_names:
20572053
self.add_message("self-cls-assignment", node=node, args=(self_cls_name,))
20582054

20592055
def _check_unpacking(self, inferred, node, targets):

tests/functional/s/self/self_cls_assignment.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ def self_foo(bar_):
1414
def self_foofoo(self, lala):
1515
"""Instance method, should warn for self"""
1616
self = lala # [self-cls-assignment]
17+
self, var = lala, 1 # [self-cls-assignment]
18+
print(var)
1719

1820
@classmethod
1921
def cls_foo(cls):
Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
self-cls-assignment:11:8:Foo.self_foo:Invalid assignment to bar_ in method
2-
self-cls-assignment:16:8:Foo.self_foofoo:Invalid assignment to self in method
3-
self-cls-assignment:21:8:Foo.cls_foo:Invalid assignment to cls in method
4-
self-cls-assignment:44:12:TestNonLocal.function._set_param:Invalid assignment to self in method
1+
self-cls-assignment:11:8:Foo.self_foo:Invalid assignment to bar_ in method:HIGH
2+
self-cls-assignment:16:8:Foo.self_foofoo:Invalid assignment to self in method:HIGH
3+
self-cls-assignment:17:8:Foo.self_foofoo:Invalid assignment to self in method:HIGH
4+
self-cls-assignment:23:8:Foo.cls_foo:Invalid assignment to cls in method:HIGH
5+
self-cls-assignment:46:12:TestNonLocal.function._set_param:Invalid assignment to self in method:HIGH

0 commit comments

Comments
 (0)