Skip to content

Instantly share code, notes, and snippets.

@dunossauro
Created February 13, 2019 23:46
Show Gist options
  • Save dunossauro/4565861a9f6c6250aa6887fd0657005b to your computer and use it in GitHub Desktop.
Save dunossauro/4565861a9f6c6250aa6887fd0657005b to your computer and use it in GitHub Desktop.
AST mutation
SURVIVED test_soma_0_0_deve_retornar_0: <class '_ast.Sub'>
SURVIVED test_soma_0_0_deve_retornar_0: <class '_ast.Mult'>
PASSED test_soma_0_0_deve_retornar_0: <class '_ast.Div'>. ERROR: division by zero
PASSED test_soma_1_1_deve_retornar_2: <class '_ast.Sub'>. ERROR:
PASSED test_soma_1_1_deve_retornar_2: <class '_ast.Mult'>. ERROR:
PASSED test_soma_1_1_deve_retornar_2: <class '_ast.Div'>. ERROR:
PASSED test_soma__1__1_deve_retornar__2: <class '_ast.Sub'>. ERROR:
PASSED test_soma__1__1_deve_retornar__2: <class '_ast.Mult'>. ERROR:
PASSED test_soma__1__1_deve_retornar__2: <class '_ast.Div'>. ERROR:
from _ast import Add, Sub, Mult, Div
from ast import parse
from inspect import getsource
aor_mutations = [Add, Sub, Mult, Div]
def possible_mutations(op, mutations):
return list(filter(lambda x: not isinstance(op, x), mutations))
def aor(func_to_mutate):
original_code = getsource(func_to_mutate)
ast_module = parse(original_code)
def _aor(func):
default_op = ast_module.body[0].body[0].value.op
ops = possible_mutations(default_op, aor_mutations)
def inner(*args, **kwargs):
for mutation in ops:
ast_module.body[0].body[0].value.op = mutation()
eval(
compile(ast_module, filename="<ast>", mode="exec"),
globals(),
)
try:
func(*args, **kwargs)
print(f'SURVIVED {func.__name__}: {mutation}')
except Exception as e:
print(f'PASSED {func.__name__}: {mutation}. ERROR: {e}')
return inner
return _aor
# =================================================
def soma(x, y):
return x + y
@aor(soma)
def test_soma_0_0_deve_retornar_0(): # NOQA
assert soma(0, 0) == 0
@aor(soma)
def test_soma_1_1_deve_retornar_2(): # NOQA
assert soma(1, 1) == 2
@aor(soma)
def test_soma__1__1_deve_retornar__2(): # NOQA
assert soma(-1, -1) == -2
test_soma_0_0_deve_retornar_0()
test_soma_1_1_deve_retornar_2()
test_soma__1__1_deve_retornar__2()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment