@@ -160,6 +160,25 @@ def _will_be_released_automatically(node: nodes.Call) -> bool:
160
160
return func .qname () in callables_taking_care_of_exit
161
161
162
162
163
+ def _is_part_of_assignment_target (node : nodes .NodeNG ) -> bool :
164
+ """Check whether use of a variable is happening as part of the left-hand
165
+ side of an assignment.
166
+
167
+ This requires recursive checking, because destructuring assignment can have
168
+ arbitrarily nested tuples and lists to unpack.
169
+ """
170
+ if isinstance (node .parent , nodes .Assign ):
171
+ return node in node .parent .targets
172
+
173
+ if isinstance (node .parent , nodes .AugAssign ):
174
+ return node == node .parent .target
175
+
176
+ if isinstance (node .parent , (nodes .Tuple , nodes .List )):
177
+ return _is_part_of_assignment_target (node .parent )
178
+
179
+ return False
180
+
181
+
163
182
class ConsiderUsingWithStack (NamedTuple ):
164
183
"""Stack for objects that may potentially trigger a R1732 message
165
184
if they are not used in a ``with`` block later on.
@@ -1917,15 +1936,13 @@ def _check_unnecessary_dict_index_lookup(
1917
1936
1918
1937
value = subscript .slice
1919
1938
1920
- if isinstance (node , nodes .For ) and (
1921
- isinstance (subscript .parent , nodes .Assign )
1922
- and subscript in subscript .parent .targets
1923
- or isinstance (subscript .parent , nodes .AugAssign )
1924
- and subscript == subscript .parent .target
1939
+ if isinstance (node , nodes .For ) and _is_part_of_assignment_target (
1940
+ subscript
1925
1941
):
1926
1942
# Ignore this subscript if it is the target of an assignment
1927
1943
# Early termination; after reassignment dict index lookup will be necessary
1928
1944
return
1945
+
1929
1946
if isinstance (subscript .parent , nodes .Delete ):
1930
1947
# Ignore this subscript if it's used with the delete keyword
1931
1948
return
@@ -2017,11 +2034,8 @@ def _check_unnecessary_list_index_lookup(
2017
2034
)
2018
2035
for child in children :
2019
2036
for subscript in child .nodes_of_class (nodes .Subscript ):
2020
- if isinstance (node , nodes .For ) and (
2021
- isinstance (subscript .parent , nodes .Assign )
2022
- and subscript in subscript .parent .targets
2023
- or isinstance (subscript .parent , nodes .AugAssign )
2024
- and subscript == subscript .parent .target
2037
+ if isinstance (node , nodes .For ) and _is_part_of_assignment_target (
2038
+ subscript
2025
2039
):
2026
2040
# Ignore this subscript if it is the target of an assignment
2027
2041
# Early termination; after reassignment index lookup will be necessary
0 commit comments