def visit_withitem(self, node: ast.withitem) -> None: """Checks that we cannot create explicit unused context variables.""" if node.optional_vars: self._check_assign_unused( cast(ast.AST, nodes.get_parent(node)), name_nodes.get_variables_from_node(node.optional_vars), is_local=True, ) self.generic_visit(node)
def check_attribute_names(self, node: ast.ClassDef) -> None: class_attributes, _ = classes.get_attributes( node, include_annotated=True, ) for assign in class_attributes: for target in get_assign_targets(assign): for attr_name in name_nodes.get_variables_from_node(target): self._ensure_case(assign, attr_name)
def _check_consistent_variable_return(self, node: ast.Return) -> None: if not node.value or not self._is_named_return(node): return previous_node = self._get_previous_stmt(node) if not isinstance(previous_node, AssignNodes): return return_names = name_nodes.get_variables_from_node(node.value) previous_names = list(name_nodes.flat_variable_names([previous_node])) self._check_for_violations(node, return_names, previous_names)
def visit_any_for(self, node: AnyFor) -> None: """Checks that we cannot create explicit unused loops.""" target_names = name_nodes.get_variables_from_node(node.target) is_target_no_op_variable = (len(target_names) == 1 and access.is_unused(target_names[0])) if not is_target_no_op_variable: # see issue 1406 self._check_assign_unused( node, target_names, is_local=True, ) self.generic_visit(node)
def _check_reassignment( self, node: AnyAssign, names: List[str], ) -> None: if not node.value: return var_values = name_nodes.get_variables_from_node(node.value) for var_name, var_value in itertools.zip_longest(names, var_values): if var_name == var_value: self.add_violation( ReassigningVariableToItselfViolation(node, text=var_name), )
def visit_any_for(self, node: AnyFor) -> None: """ Checks that we cannot create explicit unused loops. Raises: UnusedVariableIsDefinedViolation """ self._check_assign_unused( node, name_nodes.get_variables_from_node(node.target), is_local=True, ) self.generic_visit(node)
def _almost_swapped(self, assigns: Sequence[ast.Assign]) -> None: previous_var: Set[Optional[str]] = set() for assign in assigns: current_var = { first(name_nodes.flat_variable_names([assign])), first(name_nodes.get_variables_from_node(assign.value)), } if not all(map(bool, current_var)): previous_var.clear() continue if current_var == previous_var: self.add_violation(AlmostSwappedViolation(assign)) if len(previous_var & current_var) == 1: current_var ^= previous_var previous_var = current_var
def _check_reassignment( self, node: AnyAssign, names: List[str], ) -> None: if not node.value: return if isinstance(nodes.get_context(node), ast.ClassDef): return # This is not a variable, but a class property var_values = name_nodes.get_variables_from_node(node.value) for var_name, var_value in itertools.zip_longest(names, var_values): if var_name == var_value: self.add_violation( best_practices.ReassigningVariableToItselfViolation( node, text=var_name, ), )
def _check_reassignment( self, node: AnyAssign, names: List[str], ) -> None: if not node.value: return if self._is_reassignment_edge_case(node): return var_values = name_nodes.get_variables_from_node(node.value) if len(names) <= 1 < len(var_values): # It means that we have something like `x = (y, z)` # or even `x = (x, y)`, which is also fine. See #1807 return for var_name, var_value in itertools.zip_longest(names, var_values): if var_name == var_value: self.add_violation( best_practices.ReassigningVariableToItselfViolation( node, text=var_name, ), )
def extract_names(node: ast.AST) -> Set[str]: """Extracts unique set of names from a given node.""" return set(name_nodes.get_variables_from_node(node))
def _extract_names(node: ast.AST) -> Set[str]: return set(get_variables_from_node(node))