Beispiel #1
0
    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), )
Beispiel #2
0
 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
Beispiel #3
0
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
Beispiel #4
0
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
Beispiel #5
0
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
Beispiel #6
0
    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
Beispiel #7
0
    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), )