def _check_variable_usage(self, node: ast.Name) -> None: context = cast(ast.AST, get_context(node)) blocks = self._block_variables[context][node.id] if all(is_contained_by(node, block) for block in blocks): return self.add_violation( ControlVarUsedAfterBlockViolation(node, text=node.id), )
def _is_decorator( self, node: ast.AST, ) -> bool: parent = walk.get_closest_parent(node, FunctionNodes) if isinstance(parent, FunctionNodes) and parent.decorator_list: return any( node == decorator or walk.is_contained_by(node, decorator) for decorator in parent.decorator_list) return False
def is_decorator(node: ast.AST) -> bool: """ Detects if node is used as a decorator. We use this predicates because decorators can be used miltiple times. Like ``@auth_required(login_url=LOGIN_URL)`` and similar. """ parent = walk.get_closest_parent(node, FunctionNodes) if isinstance(parent, FunctionNodes) and parent.decorator_list: return any(node == decorator or walk.is_contained_by(node, decorator) for decorator in parent.decorator_list) return False
def has_break(node: AnyLoop) -> bool: """Tells whether or not given loop has ``break`` keyword in its body.""" closest_loop = None for sub in ast.walk(node): if _is_nested_loop(node, sub): closest_loop = sub if isinstance(sub, ast.Break): if not closest_loop or not walk.is_contained_by(sub, closest_loop): return True return False
def is_annotation(node: ast.AST) -> bool: """ Detects if node is an annotation. Or a part of it. We use this predicate to allow all types of repetetive function and instance annotations. """ if not isinstance(node, _AnnParts): return False annotated = walk.get_closest_parent(node, (*_AnnNodes, *FunctionNodes)) if isinstance(annotated, FunctionNodes): contains_node = bool( annotated.returns and walk.is_contained_by(node, annotated.returns), ) return node == annotated.returns or contains_node elif isinstance(annotated, _AnnNodes): contains_node = bool( annotated.annotation and walk.is_contained_by(node, annotated.annotation), ) return node == annotated.annotation or contains_node return False
def _is_annotation(self, node: ast.AST) -> bool: typed_assign = walk.get_closest_parent( node, (ast.AnnAssign, ast.arg), ) if isinstance(typed_assign, _AnnNodes) and typed_assign.annotation: is_same_node = node == typed_assign.annotation is_child_annotation = walk.is_contained_by( node, typed_assign.annotation, ) return is_same_node or is_child_annotation return False
def _check_variable_usage(self, node: ast.Name) -> None: context = cast(ast.AST, get_context(node)) blocks = self._block_variables[context][node.id] is_contained_block_var = any( is_contained_by(node, block) for block in blocks) # Restrict the use of block variables with the same name to # the same type of block - either `for` or `with`. is_same_type_block = all( isinstance(block, ForNodes) for block in blocks) or all( isinstance(block, WithNodes) for block in blocks) # Return if not a block variable or a contained block variable. if not blocks or (is_contained_block_var and is_same_type_block): return self.add_violation( ControlVarUsedAfterBlockViolation(node, text=node.id), )