R
Rittersporn
My humble attempt to model pre/postconditions with
decorators It's also my first experiment
with decorators.
If you have any ideas or thoughts on how to
improve the code snippet, I'll be happy to
learn more.
Enjoy
def condition(pretext,posttext=""):
precode=compile(pretext or "True","","eval")
postcode=compile(posttext or "True","","eval")
# function -> decorated(function)
def decorate_condition(function):
# FIXME: Does not work with wrapped functions
argcount=function.func_code.co_argcount
var=function.func_code.co_varnames[0:argcount]
# arguments -> closure(assertion)
def evaluate_condition(*args,**kargs):
# FIXME: check if "var" always contains ordered list of arguments
# map arguments and
args_seq=[(argname,args[pos]) for pos,argname in enumerate(var)]
# key-arguments to value
kargs_seq=[(k,v) for k,v in kargs.itervalues()]
environment=args_seq+kargs_seq
# precondition
assert eval(precode,{},dict(environment)),pretext
tmp=function(*args,**kargs)
environment2=environment+[('result',tmp)]
# postcondition
assert eval(postcode,{},dict(environment2)),posttext
return tmp
return evaluate_condition
return decorate_condition
@condition("number>0 and number<2","result>=0")
def sqrt(number):
import math
return math.sqrt(number)
@condition("list(seq) is not None","sum(seq)==result")
def my_sum(seq):
tmp=0
for element in seq:
tmp+=element
return tmp
print sqrt(1.2)
print my_sum([1,2,3])
decorators It's also my first experiment
with decorators.
If you have any ideas or thoughts on how to
improve the code snippet, I'll be happy to
learn more.
Enjoy
def condition(pretext,posttext=""):
precode=compile(pretext or "True","","eval")
postcode=compile(posttext or "True","","eval")
# function -> decorated(function)
def decorate_condition(function):
# FIXME: Does not work with wrapped functions
argcount=function.func_code.co_argcount
var=function.func_code.co_varnames[0:argcount]
# arguments -> closure(assertion)
def evaluate_condition(*args,**kargs):
# FIXME: check if "var" always contains ordered list of arguments
# map arguments and
args_seq=[(argname,args[pos]) for pos,argname in enumerate(var)]
# key-arguments to value
kargs_seq=[(k,v) for k,v in kargs.itervalues()]
environment=args_seq+kargs_seq
# precondition
assert eval(precode,{},dict(environment)),pretext
tmp=function(*args,**kargs)
environment2=environment+[('result',tmp)]
# postcondition
assert eval(postcode,{},dict(environment2)),posttext
return tmp
return evaluate_condition
return decorate_condition
@condition("number>0 and number<2","result>=0")
def sqrt(number):
import math
return math.sqrt(number)
@condition("list(seq) is not None","sum(seq)==result")
def my_sum(seq):
tmp=0
for element in seq:
tmp+=element
return tmp
print sqrt(1.2)
print my_sum([1,2,3])