<commit_before>"""This module contains mutation operators which replace one
relational operator with another.

For each relational operator we generate a series of classes, one for
each *other* operator. These generated classes mutate nodes by
replaces the first operator with the second.

The generated classes are named `Replace<from-op>With<to-op>` where
`from-op` is the relational operator being replaced and `to-op` is the
replacement operator.
"""

import ast
from itertools import permutations

from .operator import Operator


RELATIONAL_OPERATORS = {ast.Eq, ast.NotEq, ast.Lt, ast.LtE, ast.Gt, ast.GtE,
                        ast.Is, ast.IsNot, ast.In, ast.NotIn}

# There are a number of potential replacements which we avoid because
# they almost always produce equivalent mutants. This is a set of
# (FROM-OP, TO-OP) tuples which we don't want to generate.
SKIP = {
    (ast.NotEq, ast.IsNot),
}


def relational_operator_pairs():
    return filter(
        lambda x: x not in SKIP,
        permutations(RELATIONAL_OPERATORS, 2))


def _create_operator(from_op, to_op):  # pylint:disable=redefined-outer-name
    """Create an operator which replaces `from_op` with `to_op`.
<commit_msg>Skip Eq to Is replacement<commit_after>"""This module contains mutation operators which replace one
relational operator with another.

For each relational operator we generate a series of classes, one for
each *other* operator. These generated classes mutate nodes by
replaces the first operator with the second.

The generated classes are named `Replace<from-op>With<to-op>` where
`from-op` is the relational operator being replaced and `to-op` is the
replacement operator.
"""

import ast
from itertools import permutations

from .operator import Operator


RELATIONAL_OPERATORS = {ast.Eq, ast.NotEq, ast.Lt, ast.LtE, ast.Gt, ast.GtE,
                        ast.Is, ast.IsNot, ast.In, ast.NotIn}

# There are a number of potential replacements which we avoid because
# they almost always produce equivalent mutants. This is a set of
# (FROM-OP, TO-OP) tuples which we don't want to generate.
SKIP = {
    (ast.Eq, ast.Is),
    (ast.NotEq, ast.IsNot),
}


def relational_operator_pairs():
    return filter(
        lambda x: x not in SKIP,
        permutations(RELATIONAL_OPERATORS, 2))


def _create_operator(from_op, to_op):  # pylint:disable=redefined-outer-name
    """Create an operator which replaces `from_op` with `to_op`.

{'fraction_non_alphanumeric': 0.08463434675431389, 'fraction_numerical': 0.0008216926869350862, 'mean_word_length': 3.9391480730223125, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6198746', 'n_tokens_mistral': 756, 'n_tokens_neox': 713, 'n_words': 284}