def eval_conditions(conditions=None, data={}): ''' Evaluates conditions and returns Boolean value. Args: conditions (tuple) for the format of the tuple, see below data (dict) the keys of which can be used in conditions Returns: (boolea) Raises: ValueError if an invalid operator value is specified TypeError if: conditions are not a 3-item tuple the arguments of the condition don't have the same type e.g. ('abc', 'eq', 3) if a boolean operator does not get boolean arguments e.g. (True, 'and', 15) The format of the condition tuple is: (arg1, op, arg2) where: arg1, arg2 can be numerical values, strings or condition tuples op is a valid operator from the operator module If arg is a string, and the string is a key in <data> it is treated as a variable with value data[arg]. Notes: * If no conditions are specified True is returned. * empty or 0 values do *not* evaluate to booleans ''' #CONSIDER: implementing addition/subtraction/multiplication/division if not conditions: return True if isinstance(conditions, str) or isinstance(conditions, unicode): conditions = str2tuple(conditions) if not isinstance(conditions, tuple) or not len(conditions) == 3: raise TypeError('conditions must be a tuple with 3 items.') arg1 = conditions[0] op = conditions[1] arg2 = conditions[2] if arg1 in data: arg1 = data[arg1] elif isinstance(arg1, tuple): arg1 = eval_conditions(arg1, data) if arg2 in data: arg2 = data[arg2] elif isinstance(arg2, tuple): arg2 = eval_conditions(arg2, data) if op in ('lt', 'le', 'eq', 'ne', 'ge', 'gt'): if not (type(arg1) in (float, int) and type(arg2) in (float,int)) and \ type(arg1) != type(arg2): raise TypeError('both arguments must have the same type {}, {}'.\ format(arg1, arg2)) elif op in ('and', 'or'): if not isinstance(arg1, bool) or not isinstance(arg2, bool): raise TypeError('boolean operator {} needs boolean arguments {},'\ ' {}'.format(op, arg1, arg2)) op += '_' else: raise ValueError('operator {} not supported', op) return getattr(operator, op)(arg1, arg2)
def test_str2tuple(self): self.assertEqual(su.str2tuple("('a', 4, [1,2,3])"), ('a', 4, [1,2,3])) self.assertIsNone(su.str2tuple("['a', 4, {1.4,}]")) self.assertIsNone(su.str2tuple('raise SystemExit')) self.assertIsNone(su.str2tuple('(1)'))