@@ -21,6 +21,35 @@ def visit_Name(self, name_node: ast.Name) -> None:
2121 return dict (variable_usage )
2222
2323
24+ def collect_assignment_stores (function_node : ast .AST ) -> set [str ]:
25+ assigned_variable_names : typing .Final [set [str ]] = set ()
26+
27+ def extract_names (expression : ast .expr ) -> typing .Iterable [str ]:
28+ if isinstance (expression , ast .Name ):
29+ yield expression .id
30+ elif isinstance (expression , ast .Tuple ):
31+ for elt in expression .elts :
32+ yield from extract_names (elt )
33+
34+ @typing .final
35+ class AssignmentStoreCollector (ast .NodeVisitor ):
36+ def visit_Assign (self , assign_node : ast .Assign ) -> None :
37+ for target in assign_node .targets :
38+ assigned_variable_names .update (extract_names (target ))
39+ self .generic_visit (assign_node )
40+
41+ def visit_AugAssign (self , aug_assign_node : ast .AugAssign ) -> None :
42+ assigned_variable_names .update (extract_names (aug_assign_node .target ))
43+ self .generic_visit (aug_assign_node )
44+
45+ def visit_AnnAssign (self , ann_assign_node : ast .AnnAssign ) -> None :
46+ assigned_variable_names .update (extract_names (ann_assign_node .target ))
47+ self .generic_visit (ann_assign_node )
48+
49+ AssignmentStoreCollector ().visit (function_node )
50+ return assigned_variable_names
51+
52+
2453@typing .final
2554class TempVarCheck (ast .NodeVisitor ):
2655 def __init__ (self , syntax_tree : ast .AST ) -> None : # noqa: ARG002
@@ -43,12 +72,12 @@ def _check_temporary_variables(self, ast_node: ast.FunctionDef | ast.AsyncFuncti
4372 if variable_name .startswith ("_" ) or variable_name in {"self" , "cls" }:
4473 continue
4574
46- # Flag variables that are assigned once and read once (used exactly twice)
75+ # Flag variables that are assigned once (in assignment) and read once
4776 if (
48- sum (1 for usage in usages if isinstance (usage .ctx , ast .Store )) == 1
49- and sum (1 for usage in usages if isinstance (usage .ctx , ast .Load )) == 1
77+ len ([usage for usage in usages if isinstance (usage .ctx , ast .Store )]) == 1
78+ and len ([usage for usage in usages if isinstance (usage .ctx , ast .Load )]) == 1
79+ and variable_name in collect_assignment_stores (ast_node )
5080 and not found_temporary_variable
51- and usages
5281 ):
5382 # Find the first usage (likely the assignment) to report the violation
5483 first_usage = usages [0 ]
0 commit comments