@@ -78,6 +78,119 @@ def visit_ClassDef(self, ast_node: ast.ClassDef) -> None:
7878 self .validate_class_name_length (ast_node )
7979 self .generic_visit (ast_node )
8080
81+ def visit_ListComp (self , ast_node : ast .ListComp ) -> None :
82+ for comprehension in ast_node .generators :
83+ self ._validate_comprehension_target (comprehension .target )
84+ self .generic_visit (ast_node )
85+
86+ def visit_SetComp (self , ast_node : ast .SetComp ) -> None :
87+ for comprehension in ast_node .generators :
88+ self ._validate_comprehension_target (comprehension .target )
89+ self .generic_visit (ast_node )
90+
91+ def visit_DictComp (self , ast_node : ast .DictComp ) -> None :
92+ for comprehension in ast_node .generators :
93+ self ._validate_comprehension_target (comprehension .target )
94+ self .generic_visit (ast_node )
95+
96+ def visit_Lambda (self , ast_node : ast .Lambda ) -> None :
97+ self ._validate_function_args (ast_node .args )
98+ self .generic_visit (ast_node )
99+
100+ def visit_With (self , ast_node : ast .With ) -> None :
101+ for item in ast_node .items :
102+ if item .optional_vars is not None :
103+ self ._validate_with_target (item .optional_vars )
104+ self .generic_visit (ast_node )
105+
106+ def visit_ExceptHandler (self , ast_node : ast .ExceptHandler ) -> None :
107+ if ast_node .name is not None :
108+ self ._validate_except_target (ast_node )
109+ self .generic_visit (ast_node )
110+
111+ def visit_GeneratorExp (self , ast_node : ast .GeneratorExp ) -> None :
112+ for comprehension in ast_node .generators :
113+ self ._validate_comprehension_target (comprehension .target )
114+ self .generic_visit (ast_node )
115+
116+ def _validate_function_args (self , arguments_node : ast .arguments ) -> None :
117+ # Process all argument types
118+ for argument in arguments_node .posonlyargs :
119+ self ._validate_argument_name_length (argument )
120+ for argument in arguments_node .args :
121+ self ._validate_argument_name_length (argument )
122+ for argument in arguments_node .kwonlyargs :
123+ self ._validate_argument_name_length (argument )
124+
125+ if arguments_node .vararg is not None :
126+ self ._validate_argument_name_length (arguments_node .vararg )
127+ if arguments_node .kwarg is not None :
128+ self ._validate_argument_name_length (arguments_node .kwarg )
129+
130+ def _validate_argument_name_length (self , argument : ast .arg ) -> None :
131+ if argument .arg in {"self" , "cls" }:
132+ return
133+ if check_is_ignored_name (argument .arg ):
134+ return
135+ if check_is_whitelisted_annotation (argument .annotation ):
136+ return
137+
138+ if len (argument .arg ) < MIN_NAME_LENGTH :
139+ self .violations .append (
140+ Violation (
141+ line_number = argument .lineno ,
142+ column_number = argument .col_offset ,
143+ violation_code = ViolationCodes .ARGUMENT_NAME_LENGTH ,
144+ )
145+ )
146+
147+ def _validate_comprehension_target (self , comprehension_target : ast .expr ) -> None :
148+ if isinstance (comprehension_target , ast .Name ):
149+ # For comprehension targets, we'll treat them as variables
150+ if not check_is_ignored_name (comprehension_target .id ) and len (comprehension_target .id ) < MIN_NAME_LENGTH :
151+ self .violations .append (
152+ Violation (
153+ line_number = comprehension_target .lineno ,
154+ column_number = comprehension_target .col_offset ,
155+ violation_code = ViolationCodes .VARIABLE_NAME_LENGTH ,
156+ )
157+ )
158+ elif isinstance (comprehension_target , ast .Tuple ):
159+ # Handle tuple unpacking in comprehensions like [(a, b) for a, b in pairs]
160+ for elt in comprehension_target .elts :
161+ self ._validate_comprehension_target (elt )
162+
163+ def _validate_with_target (self , target_node : ast .expr ) -> None :
164+ if isinstance (target_node , ast .Name ):
165+ # For with targets, we'll treat them as variables
166+ if not check_is_ignored_name (target_node .id ) and len (target_node .id ) < MIN_NAME_LENGTH :
167+ self .violations .append (
168+ Violation (
169+ line_number = target_node .lineno ,
170+ column_number = target_node .col_offset ,
171+ violation_code = ViolationCodes .VARIABLE_NAME_LENGTH ,
172+ )
173+ )
174+ elif isinstance (target_node , ast .Tuple ):
175+ # Handle tuple unpacking in with statements like with open(f1) as f1, open(f2) as f2:
176+ for elt in target_node .elts :
177+ self ._validate_with_target (elt )
178+
179+ def _validate_except_target (self , ast_node : ast .ExceptHandler ) -> None :
180+ # For except targets, we'll treat them as variables
181+ if (
182+ ast_node .name is not None
183+ and not check_is_ignored_name (ast_node .name )
184+ and len (ast_node .name ) < MIN_NAME_LENGTH
185+ ):
186+ self .violations .append (
187+ Violation (
188+ line_number = ast_node .lineno ,
189+ column_number = 0 , # ast.ExceptHandler doesn't have col_offset
190+ violation_code = ViolationCodes .VARIABLE_NAME_LENGTH ,
191+ )
192+ )
193+
81194 def validate_name_length (self , identifier : str , ast_node : ast .stmt , parent_class : ast .ClassDef | None ) -> None :
82195 if check_is_ignored_name (identifier ):
83196 return
0 commit comments