Skip to content

Commit

Permalink
More name mangling. Avoids mutant names triggering name-based magic i…
Browse files Browse the repository at this point in the history
…n for example pytest.
  • Loading branch information
boxed committed Oct 22, 2024
1 parent e9012a9 commit b4b553d
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 29 deletions.
5 changes: 5 additions & 0 deletions mutmut/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -738,6 +738,8 @@ def mangle_function_name(*, name, class_name):
if class_name:
assert CLASS_NAME_SEPARATOR not in class_name
prefix = f'x{CLASS_NAME_SEPARATOR}{class_name}{CLASS_NAME_SEPARATOR}'
else:
prefix = 'x_'
return f'{prefix}{name}'


Expand All @@ -752,6 +754,9 @@ def orig_function_and_class_names_from_key(mutant_name):
if CLASS_NAME_SEPARATOR in r:
class_name = r[r.index(CLASS_NAME_SEPARATOR) + 1: r.rindex(CLASS_NAME_SEPARATOR)]
r = r[r.rindex(CLASS_NAME_SEPARATOR) + 1:]
else:
assert r.startswith('x_')
r = r[2:]
return r, class_name


Expand Down
26 changes: 13 additions & 13 deletions tests/test_mutation.py
Original file line number Diff line number Diff line change
Expand Up @@ -194,11 +194,11 @@ def test_function_with_annotation():
source = "def capitalize(s : str):\n return s[0].upper() + s[1:] if s else s\n".strip()
mutants = mutants_for_source(source)
assert mutants == [
'def capitalize__mutmut_1(s : str):\n return s[1].upper() + s[1:] if s else s',
'def capitalize__mutmut_2(s : str):\n return s[None].upper() + s[1:] if s else s',
'def capitalize__mutmut_3(s : str):\n return s[0].upper() - s[1:] if s else s',
'def capitalize__mutmut_4(s : str):\n return s[0].upper() + s[2:] if s else s',
'def capitalize__mutmut_5(s : str):\n return s[0].upper() + s[None] if s else s'
'def x_capitalize__mutmut_1(s : str):\n return s[1].upper() + s[1:] if s else s',
'def x_capitalize__mutmut_2(s : str):\n return s[None].upper() + s[1:] if s else s',
'def x_capitalize__mutmut_3(s : str):\n return s[0].upper() - s[1:] if s else s',
'def x_capitalize__mutmut_4(s : str):\n return s[0].upper() + s[2:] if s else s',
'def x_capitalize__mutmut_5(s : str):\n return s[0].upper() + s[None] if s else s'
]


Expand All @@ -221,12 +221,12 @@ def foo():
'''
mutants = mutants_for_source(source)
assert mutants == [
'\ndef foo__mutmut_1(): \n dict(a=None, c=d)\n',
'\ndef foo__mutmut_2(): \n dict(aXX=b, c=d)\n',
'\ndef foo__mutmut_3(): \n dict(a=b, c=None)\n',
'\ndef foo__mutmut_4(): \n dict(a=b, cXX=d)\n',
'\ndef foo__mutmut_5(): \n dict( c=d)\n',
'\ndef foo__mutmut_6(): \n dict(a=b,)\n',
'\ndef x_foo__mutmut_1(): \n dict(a=None, c=d)\n',
'\ndef x_foo__mutmut_2(): \n dict(aXX=b, c=d)\n',
'\ndef x_foo__mutmut_3(): \n dict(a=b, c=None)\n',
'\ndef x_foo__mutmut_4(): \n dict(a=b, cXX=d)\n',
'\ndef x_foo__mutmut_5(): \n dict( c=d)\n',
'\ndef x_foo__mutmut_6(): \n dict(a=b,)\n',
]


Expand Down Expand Up @@ -300,11 +300,11 @@ def foo():

def test_orig_function_name_from_key():
assert orig_function_and_class_names_from_key(f'_{CLASS_NAME_SEPARATOR}Foo{CLASS_NAME_SEPARATOR}bar__mutmut_1') == ('bar', 'Foo')
assert orig_function_and_class_names_from_key('bar__mutmut_1') == ('bar', None)
assert orig_function_and_class_names_from_key('x_bar__mutmut_1') == ('bar', None)


def test_mangle_function_name():
assert mangle_function_name(name='bar', class_name=None) == 'bar'
assert mangle_function_name(name='bar', class_name=None) == 'x_bar'
assert mangle_function_name(name='bar', class_name='Foo') == f'x{CLASS_NAME_SEPARATOR}Foo{CLASS_NAME_SEPARATOR}bar'


Expand Down
32 changes: 16 additions & 16 deletions tests/test_mutmut3.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,25 +18,25 @@ def foo(a, b, c):
a + 1
def foo__mutmut_orig(a, b, c):
def x_foo__mutmut_orig(a, b, c):
return a + b * c
def foo__mutmut_1(a, b, c):
def x_foo__mutmut_1(a, b, c):
return a - b * c
def foo__mutmut_2(a, b, c):
def x_foo__mutmut_2(a, b, c):
return a + b / c
foo__mutmut_mutants = {
'foo__mutmut_1': foo__mutmut_1,
'foo__mutmut_2': foo__mutmut_2
x_foo__mutmut_mutants = {
'x_foo__mutmut_1': x_foo__mutmut_1,
'x_foo__mutmut_2': x_foo__mutmut_2
}
def foo(*args, **kwargs):
return _mutmut_trampoline(foo__mutmut_orig, foo__mutmut_mutants, *args, **kwargs)
return _mutmut_trampoline(x_foo__mutmut_orig, x_foo__mutmut_mutants, *args, **kwargs)
foo.__signature__ = _mutmut_signature(foo__mutmut_orig)
foo__mutmut_orig.__name__ = 'foo'
foo.__signature__ = _mutmut_signature(x_foo__mutmut_orig)
x_foo__mutmut_orig.__name__ = 'x_foo'
"""
Expand All @@ -55,21 +55,21 @@ def foo(a: List[int]) -> int:

expected = trampoline_impl + """
def foo__mutmut_orig(a: List[int]) -> int:
def x_foo__mutmut_orig(a: List[int]) -> int:
return 1
def foo__mutmut_1(a: List[int]) -> int:
def x_foo__mutmut_1(a: List[int]) -> int:
return 2
foo__mutmut_mutants = {
'foo__mutmut_1': foo__mutmut_1
x_foo__mutmut_mutants = {
'x_foo__mutmut_1': x_foo__mutmut_1
}
def foo(*args, **kwargs):
return _mutmut_trampoline(foo__mutmut_orig, foo__mutmut_mutants, *args, **kwargs)
return _mutmut_trampoline(x_foo__mutmut_orig, x_foo__mutmut_mutants, *args, **kwargs)
foo.__signature__ = _mutmut_signature(foo__mutmut_orig)
foo__mutmut_orig.__name__ = 'foo'
foo.__signature__ = _mutmut_signature(x_foo__mutmut_orig)
x_foo__mutmut_orig.__name__ = 'x_foo'
"""
Expand Down

0 comments on commit b4b553d

Please sign in to comment.