예제 #1
0
    def _check_use_implicit_booleaness_not_comparison(
            self, node: nodes.Compare) -> None:
        """Check for left side and right side of the node for empty literals."""
        is_left_empty_literal = utils.is_base_container(
            node.left) or utils.is_empty_dict_literal(node.left)

        # Check both left-hand side and right-hand side for literals
        for operator, comparator in node.ops:
            is_right_empty_literal = utils.is_base_container(
                comparator) or utils.is_empty_dict_literal(comparator)
            # Using Exclusive OR (XOR) to compare between two side.
            # If two sides are both literal, it should be different error.
            if is_right_empty_literal ^ is_left_empty_literal:
                # set target_node to opposite side of literal
                target_node = node.left if is_right_empty_literal else comparator
                literal_node = comparator if is_right_empty_literal else node.left
                # Infer node to check
                target_instance = utils.safe_infer(target_node)
                if target_instance is None:
                    continue
                mother_classes = self.base_names_of_instance(target_instance)
                is_base_comprehension_type = any(t in mother_classes
                                                 for t in ("tuple", "list",
                                                           "dict", "set"))

                # Only time we bypass check is when target_node is not inherited by
                # collection literals and have its own __bool__ implementation.
                if not is_base_comprehension_type and self.instance_has_bool(
                        target_instance):
                    continue

                # No need to check for operator when visiting compare node
                if operator in {"==", "!=", ">=", ">", "<=", "<"}:
                    collection_literal = "{}"
                    if isinstance(literal_node, nodes.List):
                        collection_literal = "[]"
                    if isinstance(literal_node, nodes.Tuple):
                        collection_literal = "()"

                    instance_name = "x"
                    if isinstance(target_node,
                                  nodes.Call) and target_node.func:
                        instance_name = f"{target_node.func.as_string()}(...)"
                    elif isinstance(target_node,
                                    (nodes.Attribute, nodes.Name)):
                        instance_name = target_node.as_string()

                    original_comparison = (
                        f"{instance_name} {operator} {collection_literal}")
                    suggestion = (f"{instance_name}" if operator == "!=" else
                                  f"not {instance_name}")
                    self.add_message(
                        "use-implicit-booleaness-not-comparison",
                        args=(
                            original_comparison,
                            suggestion,
                        ),
                        node=node,
                    )
예제 #2
0
def test_is_empty_literal() -> None:
    list_node = astroid.extract_node("a = []")
    assert utils.is_base_container(list_node.value)
    not_empty_list_node = astroid.extract_node("a = [1,2,3]")
    assert not utils.is_base_container(not_empty_list_node.value)

    tuple_node = astroid.extract_node("a = ()")
    assert utils.is_base_container(tuple_node.value)
    not_empty_tuple_node = astroid.extract_node("a = (1,2)")
    assert not utils.is_base_container(not_empty_tuple_node.value)

    dict_node = astroid.extract_node("a = {}")
    assert utils.is_empty_dict_literal(dict_node.value)
    not_empty_dict_node = astroid.extract_node("a = {1:1}")
    assert not utils.is_empty_dict_literal(not_empty_dict_node.value)

    string_node = astroid.extract_node("a = ''")
    assert utils.is_empty_str_literal(string_node.value)
    not_empty_string_node = astroid.extract_node("a = 'hello'")
    assert not utils.is_empty_str_literal(not_empty_string_node.value)