Esempio n. 1
0
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)
Esempio n. 2
0
 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)'))