Invalid mutations involving positional-only and keyword-only arguments
qthequartermasterman opened this issue · 2 comments
I have an odd false-positive surviving mutant (when using the standard pytest runner) involving positional-only and keyword-only arguments.
Consider this function, with two positional-only arguments:
def foo(a, b, /, **kwargs):
print(a, b, kwargs)
foo(1, 2, c=3) # 1 2 {'c': 3}
mutmut
tried one mutation which is syntactically invalid (but somehow was still marked as survived???)
def foo_mutated(a, b, *, **kwargs): # SyntaxError
print(a, b, kwargs)
Ideally, mutmut
wouldn't generate this mutation because it's a SyntaxError.
However, it is only a syntax error if the *
and **kwargs
are adjacent (i.e. no explicitly named parameters). Consider this:
def foo_with_c(a, b, /, c, **kwargs):
print(a, b, c, kwargs)
foo_with_c(1, 2, c=3) # 1 2 3 {}
def foo_mutated_with_c(a, b, *, c, **kwargs):
print(a, b, c, kwargs)
foo_mutated_with_c(1, 2, c=3) # 1 2 3 {}
This mutation is syntactically valid, and thus should be tried. Consequently, simply avoiding replacing /
with *
in function signatures is not sufficient.
If there is not an obvious way to only generate the syntactically correct mutants, is there a way to guarantee that mutants with syntax errors are not marked as survived?
Yea I guess we should load the resulting file with the ast standard library and if it's invalid just mark it as killed. This should be super fast and just a clean win.