def is_same_slice(
    iterable: str,
    target: str,
    node: ast.Subscript,
) -> bool:
    """Used to tell when slice is identical to some pair of name/index."""
    return (source.node_to_string(node.value) == iterable
            and source.node_to_string(get_slice_expr(node)) == target)
예제 #2
0
    def _check_len_call(self, node: ast.Subscript) -> None:
        node_slice = get_slice_expr(node)
        is_len_call = (isinstance(node_slice, ast.BinOp)
                       and isinstance(node_slice.op, ast.Sub)
                       and self._is_wrong_len(
                           node_slice,
                           source.node_to_string(node.value),
                       ))

        if is_len_call:
            self.add_violation(
                refactoring.ImplicitNegativeIndexViolation(node), )
예제 #3
0
    def _check_slice_assignment(self, node: ast.Subscript) -> None:
        if not isinstance(node.ctx, ast.Store):
            return

        subscript_slice_assignment = isinstance(node.slice, ast.Slice)

        slice_expr = get_slice_expr(node)
        slice_function_assignment = (isinstance(slice_expr, ast.Call)
                                     and functions.given_function_called(
                                         slice_expr, {'slice'}))

        if subscript_slice_assignment or slice_function_assignment:
            self.add_violation(consistency.AssignToSliceViolation(node), )
예제 #4
0
 def _is_valid_final_value(self, format_value: ast.AST) -> bool:
     # Variable lookup is okay and a single attribute is okay
     if isinstance(format_value, (ast.Name, ast.Attribute)):
         return True
     # Function call with empty arguments is okay
     elif isinstance(format_value, ast.Call) and not format_value.args:
         return True
     # Named lookup, Index lookup & Dict key is okay
     elif isinstance(format_value, ast.Subscript):
         return isinstance(
             get_slice_expr(format_value),
             self._valid_format_index,
         )
     return False
예제 #5
0
def get_annotation_complexity(annotation_node: _Annotation) -> int:
    """
    Recursively counts complexity of annotation nodes.

    When annotations are written as strings,
    we additionally parse them to ``ast`` nodes.
    """
    if isinstance(annotation_node, ast.Str):
        # try to parse string-wrapped annotations
        try:
            annotation_node = ast.parse(  # type: ignore
                annotation_node.s, ).body[0].value
        except (SyntaxError, IndexError):
            return 1

    if isinstance(annotation_node, ast.Subscript):
        return 1 + get_annotation_complexity(get_slice_expr(annotation_node))
    elif isinstance(annotation_node, (ast.Tuple, ast.List)):
        return max(
            (get_annotation_complexity(node) for node in annotation_node.elts),
            default=1,
        )
    return 1
예제 #6
0
 def _check_float_key(self, node: ast.Subscript) -> None:
     if self._is_float_key(get_slice_expr(node)):
         self.add_violation(best_practices.FloatKeyViolation(node))