예제 #1
0
    def _check_set_elements(
        self,
        node: Union[ast.Set, ast.Dict],
        keys_or_elts: _HashItems,
    ) -> None:
        elements: List[str] = []
        element_values = []

        for set_item in keys_or_elts:
            if set_item is None:
                continue  # happens for `{**a}`

            real_item = unwrap_unary_node(set_item)
            if isinstance(real_item, self._elements_in_sets):
                # Similar look:
                node_repr = source.node_to_string(set_item)
                elements.append(node_repr.strip().strip('(').strip(')'))

            real_item = unwrap_starred_node(real_item)

            # Non-constant nodes raise ValueError,
            # unhashables raise TypeError:
            with suppress(ValueError, TypeError):
                # Similar value:
                element_values.append(
                    safe_eval.literal_eval_with_names(real_item, )
                    if isinstance(
                        real_item,
                        self._elements_to_eval,
                    ) else set_item, )
        self._report_set_elements(node, elements, element_values)
예제 #2
0
    def _check_set_elements(
        self,
        node: Union[ast.Set, ast.Dict],
        keys_or_elts: Sequence[ast.AST],
    ) -> None:
        elements: List[str] = []
        element_values = []

        for set_item in keys_or_elts:
            real_item = unwrap_unary_node(set_item)
            if isinstance(real_item, self._elements_in_sets):
                # Similar look:
                source = astor.to_source(set_item)
                elements.append(source.strip().strip('(').strip(')'))

            real_item = unwrap_starred_node(real_item)

            # Non-constant nodes raise ValueError,
            # unhashables raise TypeError:
            with suppress(ValueError, TypeError):
                # Similar value:
                real_item = safe_eval.literal_eval_with_names(
                    real_item,
                ) if isinstance(
                    real_item, self._elements_to_eval,
                ) else set_item
                element_values.append(real_item)
        self._report_set_elements(node, elements, element_values)
예제 #3
0
    def _check_zero_division(self, op: ast.operator, number: ast.AST) -> None:
        number = unwrap_unary_node(number)

        is_zero_division = (isinstance(op, ast.Div)
                            and isinstance(number, ast.Num) and number.n == 0)
        if is_zero_division:
            self.add_violation(consistency.ZeroDivisionViolation(number))
예제 #4
0
 def _check_set_elements(self, node: ast.Set) -> None:
     elements: List[str] = []
     for set_item in node.elts:
         real_set_item = unwrap_unary_node(set_item)
         if isinstance(real_set_item, self._elements_in_sets):
             source = astor.to_source(set_item)
             elements.append(source.strip().strip('(').strip(')'))
     self._report_set_elements(node, elements)
예제 #5
0
    def _check_condition(self, node: ast.AST, condition: ast.AST) -> None:
        real_node = operators.unwrap_unary_node(condition)
        if isinstance(real_node, ast.NameConstant) and real_node.value is True:
            if isinstance(node, ast.While):
                return  # We should allow `while True:`

        if isinstance(real_node, self._forbidden_nodes):
            self.add_violation(WrongKeywordConditionViolation(condition))
 def _check_explicit_iter_type(
     self,
     node: Union[AnyFor, ast.comprehension],
 ) -> None:
     node_iter = unwrap_unary_node(node.iter)
     is_wrong = isinstance(node_iter, self._forbidden_for_iters)
     is_empty = isinstance(node_iter, ast.Tuple) and not node_iter.elts
     if is_wrong or is_empty:
         self.add_violation(WrongLoopIterTypeViolation(node_iter))
예제 #7
0
def _is_correct_len(sign: ast.cmpop, comparator: ast.AST) -> bool:
    """This is a helper function to tell what calls to ``len()`` are valid."""
    if isinstance(operators.unwrap_unary_node(comparator), ast.Num):
        numeric_value = ast.literal_eval(comparator)
        if numeric_value == 0:
            return False
        if numeric_value == 1:
            return not isinstance(sign, (ast.GtE, ast.Lt))
    return True
예제 #8
0
    def _check_float_keys(self, keys: _HashItems) -> None:
        for dict_key in keys:
            if dict_key is None:
                continue

            real_key = unwrap_unary_node(dict_key)
            is_float_key = (isinstance(real_key, ast.Num)
                            and isinstance(real_key.n, float))
            if is_float_key:
                self.add_violation(FloatKeyViolation(dict_key))
    def _check_argument_default_values(self, node: AnyFunctionDef) -> None:
        for arg in node.args.defaults:
            real_arg = operators.unwrap_unary_node(arg)
            parts = prop_access.parts(real_arg) if isinstance(
                real_arg, ast.Attribute,
            ) else [real_arg]

            for part in parts:
                if not isinstance(part, self._allowed_default_value_types):
                    self.add_violation(ComplexDefaultValueViolation(arg))
                    return
예제 #10
0
    def _check_is_constant_comprare(
        self,
        op: ast.cmpop,
        comparator: ast.expr,
    ) -> None:
        if not isinstance(op, (ast.Is, ast.IsNot)):
            return

        unwrapped = operators.unwrap_unary_node(comparator)
        if isinstance(unwrapped, self._forbidden_for_is):
            self.add_violation(WrongIsCompareViolation(comparator))
예제 #11
0
    def _get_all_names(
        self,
        node: ast.BoolOp,
    ) -> List[str]:
        # We need to make sure that we do not visit
        # one chained `BoolOp` elements twice:
        self._same_nodes.append(node)

        names = []
        for operand in node.values:
            if isinstance(operand, ast.BoolOp):
                names.extend(self._get_all_names(operand))
            else:
                names.append(
                    source.node_to_string(
                        operators.unwrap_unary_node(operand), ), )
        return names
예제 #12
0
    def _get_non_negative_nodes(
        self,
        left: ast.AST,
        right: Optional[ast.AST] = None,
    ):
        non_negative_numbers = []
        for node in filter(None, (left, right)):
            real_node = unwrap_unary_node(node)
            if not isinstance(real_node, ast.Num):
                continue

            if real_node.n not in self._meaningless_operations:
                continue

            if real_node.n == 1 and walk.is_contained(node, ast.USub):
                continue
            non_negative_numbers.append(real_node)
        return non_negative_numbers
예제 #13
0
 def _check_argument_default_values(self, node: AnyFunctionDef) -> None:
     for arg in node.args.defaults:
         real_arg = operators.unwrap_unary_node(arg)
         if not isinstance(real_arg, self._allowed_default_value_types):
             self.add_violation(ComplexDefaultValueViolation(node))
예제 #14
0
 def _check_constant_condition(self, node: AnyIf) -> None:
     real_node = operators.unwrap_unary_node(node.test)
     if isinstance(real_node, self._forbidden_nodes):
         self.add_violation(ConstantConditionViolation(node))
예제 #15
0
 def _is_float_key(self, node: ast.Index) -> bool:
     real_node = operators.unwrap_unary_node(node.value)
     return (
         isinstance(real_node, ast.Num) and
         isinstance(real_node.n, float)
     )