Skip to content

Commit dd26ef5

Browse files
Filter out identical string mutants with different values
As at the status quo, operator_string took the prefix of the node's value, trimming that off the rest to leave an approximation. This worked well enough until some wombat (hi) fed in a regex string consisting only of escape sequences and whitespace. For whatever reason, the node represented that value as r'(rest of text...) which the status quo dutifully trimmed to (rest of text...). As the two text strings didn't match, status quo dutifully let the mutant through despite it being a no-op. This commit adds an additional check to catch the _unmodified_ node value being equal to the mutated node value, skipping those candidate mutants.
1 parent 3a5c501 commit dd26ef5

File tree

2 files changed

+3
-2
lines changed

2 files changed

+3
-2
lines changed

mutmut/node_mutation.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ def operator_string(
3131
) -> Iterable[cst.BaseString]:
3232
if isinstance(node, cst.SimpleString):
3333
value = node.value
34+
old_value = value
3435
prefix = value[
3536
: min([x for x in [value.find('"'), value.find("'")] if x != -1])
3637
]
@@ -52,6 +53,8 @@ def operator_string(
5253
new_value = f"{prefix}{value[0]}{mut_func(value[1:-1])}{value[-1]}"
5354
if new_value == value:
5455
continue
56+
if new_value == old_value:
57+
continue
5558
yield node.with_changes(value=new_value)
5659

5760

tests/test_mutation.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -437,8 +437,6 @@ def parse(self, text: str) -> tuple[Tree[Token], str]:
437437
"def parse(self, text: str) -> tuple[Tree[Token], str]:\n text = re.sub(r'[\\w\\-] [\\w\\-]', text)\n\n return self.parser.parse(text), text",
438438
"def parse(self, text: str) -> tuple[Tree[Token], str]:\n text = re.sub(r'[\\w\\-] [\\w\\-]', dashrepl, )\n\n return self.parser.parse(text), text",
439439
"def parse(self, text: str) -> tuple[Tree[Token], str]:\n text = re.sub(r'XX[\\w\\-] [\\w\\-]XX', dashrepl, text)\n\n return self.parser.parse(text), text",
440-
"def parse(self, text: str) -> tuple[Tree[Token], str]:\n text = re.sub(r'[\\w\\-] [\\w\\-]', dashrepl, text)\n\n return self.parser.parse(text), text",
441-
"def parse(self, text: str) -> tuple[Tree[Token], str]:\n text = re.sub(r'[\\w\\-] [\\w\\-]', dashrepl, text)\n\n return self.parser.parse(text), text",
442440
"def parse(self, text: str) -> tuple[Tree[Token], str]:\n text = re.sub(r'[\\w\\-] [\\w\\-]', dashrepl, text)\n\n return self.parser.parse(None), text"
443441
]
444442
assert sorted(mutants) == sorted(expected)

0 commit comments

Comments
 (0)