Skip to content
Snippets Groups Projects

Draft: Resolve "Short circuiting and lazy evaluation"

Open Ivan Kondov requested to merge 49-short-circuiting-and-lazy-evaluation into master
1 file
+ 51
13
Compare changes
  • Side-by-side
  • Inline
@@ -60,17 +60,17 @@ def dummies_right(func, args):
def log_eval(func):
"""a logger indicating when a func property is eventually evaluated"""
def decorator(obj):
func_ret, pars = func(obj)
def logged_func(obj):
ret_func, pars = func(obj)
logger = get_logger(__name__)
obj_repr = repr(obj)
def newfunc_ret(*args, **kwargs):
ret = func_ret(*args, **kwargs)
logger.debug(' evaluated %s: %s', obj_repr, ret)
return ret
return newfunc_ret, pars
return decorator
def new_ret_func(*args, **kwargs):
ret_val = ret_func(*args, **kwargs)
logger.debug(' evaluated %s: %s', obj_repr, ret_val)
return ret_val
return new_ret_func, pars
return logged_func
def print_func(self):
@@ -120,7 +120,7 @@ def type_func(self):
'datatype': get_datatype_name(datatype)}
if (isinstance_m(par, ['GeneralReference']) and isinstance_m(par.ref, ['ObjectImport'])
and callable(get_object_import(par.ref)) or not numeric):
return (lambda: typemap['Table']([dct]), tuple())
return lambda: typemap['Table']([dct]), tuple()
assert numeric
def retfunc(val):
@@ -620,7 +620,7 @@ def func_reduce_func(self, func):
def get_func_reduce_val(*args):
iargs = iter(args)
fargs = [list(islice(iargs, pl)) for pl in pars_lens]
return func([f(*a) for f, a in zip(funcs, fargs)])
return func(f(*a) for f, a in zip(funcs, fargs))
return get_func_reduce_val, tuple(chain.from_iterable(pars))
@@ -643,7 +643,7 @@ def in_func(self):
iargs = iter(args)
eargs = list(islice(iargs, elem_pars_len))
pargs = [list(islice(iargs, pl)) for pl in pars_lens]
return elem_func(*eargs) in [f(*a) for f, a in zip(funcs, pargs)]
return elem_func(*eargs) in (f(*a) for f, a in zip(funcs, pargs))
return get_in_val, tuple(chain.from_iterable(elem_pars+pars))
@@ -706,6 +706,44 @@ def binary_operation_func(self, operator):
return binop_func(func, ops)
def or_func(self):
"""return a 2-tuple containing a function and a list of parameters"""
funcs = [op.func[0] for op in self.operands]
pars = [op.func[1] for op in self.operands]
plens = [len(p) for p in pars]
def get_or_val(*args):
null = False
iter_args = iter(args)
for func, plen in zip(funcs, plens):
op_val = func(*list(islice(iter_args, plen)))
if op_val:
return True
if op_val is None:
null = True
return False if not null else None
return get_or_val, tuple(chain.from_iterable(pars))
def and_func(self):
"""return a 2-tuple containing a function and a list of parameters"""
funcs = [op.func[0] for op in self.operands]
pars = [op.func[1] for op in self.operands]
plens = [len(p) for p in pars]
def get_and_val(*args):
null = False
iter_args = iter(args)
for func, plen in zip(funcs, plens):
op_val = func(*list(islice(iter_args, plen)))
if op_val is None:
null = True
elif not op_val:
return False
return True if not null else None
return get_and_val, tuple(chain.from_iterable(pars))
def not_func(self, operator):
"""return a 2-tuple containing a function and a list of parameters"""
if self.not_:
@@ -954,8 +992,8 @@ def add_func_properties(metamodel):
'Expression': expression_func,
'Operand': operand_func,
'BooleanOperand': operand_func,
'And': partial(binary_operation_func, operator='and'),
'Or': partial(binary_operation_func, operator='or'),
'And': and_func,
'Or': or_func,
'Not': partial(not_func, operator=not_),
'Comparison': comparison_func,
'Real': real_func,
Loading