def Eval(Operator, Oprand1, Oprand2=None): WrnExp = None if Operator not in {"==", "!=", ">=", "<=", ">", "<", "in", "not in"} and \ (isinstance(Oprand1, type('')) or isinstance(Oprand2, type(''))): raise BadExpression(ERR_STRING_EXPR % Operator) if Operator in {'in', 'not in'}: if not isinstance(Oprand1, type('')): Oprand1 = IntToStr(Oprand1) if not isinstance(Oprand2, type('')): Oprand2 = IntToStr(Oprand2) TypeDict = { type(0): 0, # For python2 long type type(sys.maxsize + 1): 0, type(''): 1, type(True): 2 } EvalStr = '' if Operator in {"!", "NOT", "not"}: if isinstance(Oprand1, type('')): raise BadExpression(ERR_STRING_EXPR % Operator) EvalStr = 'not Oprand1' elif Operator in {"~"}: if isinstance(Oprand1, type('')): raise BadExpression(ERR_STRING_EXPR % Operator) EvalStr = '~ Oprand1' else: if Operator in {"+", "-"} and (type(True) in { type(Oprand1), type(Oprand2) }): # Boolean in '+'/'-' will be evaluated but raise warning WrnExp = WrnExpression(WRN_BOOL_EXPR) elif type('') in {type(Oprand1), type(Oprand2) } and not isinstance(Oprand1, type(Oprand2)): # == between string and number/boolean will always return False, != return True if Operator == "==": WrnExp = WrnExpression(WRN_EQCMP_STR_OTHERS) WrnExp.result = False raise WrnExp elif Operator == "!=": WrnExp = WrnExpression(WRN_NECMP_STR_OTHERS) WrnExp.result = True raise WrnExp else: raise BadExpression(ERR_RELCMP_STR_OTHERS % Operator) elif TypeDict[type(Oprand1)] != TypeDict[type(Oprand2)]: if Operator in {"==", "!=", ">=", "<=", ">", "<"} and set( (TypeDict[type(Oprand1)], TypeDict[type(Oprand2)])) == set( (TypeDict[type(True)], TypeDict[type(0)])): # comparison between number and boolean is allowed pass elif Operator in {'&', '|', '^', "and", "or"} and set( (TypeDict[type(Oprand1)], TypeDict[type(Oprand2)])) == set( (TypeDict[type(True)], TypeDict[type(0)])): # bitwise and logical operation between number and boolean is allowed pass else: raise BadExpression(ERR_EXPR_TYPE) if isinstance(Oprand1, type('')) and isinstance(Oprand2, type('')): if (Oprand1.startswith('L"') and not Oprand2.startswith('L"')) or \ (not Oprand1.startswith('L"') and Oprand2.startswith('L"')): raise BadExpression(ERR_STRING_CMP % (Oprand1, Operator, Oprand2)) if 'in' in Operator and isinstance(Oprand2, type('')): Oprand2 = Oprand2.split() EvalStr = 'Oprand1 ' + Operator + ' Oprand2' # Local symbols used by built in eval function Dict = {'Oprand1': Oprand1, 'Oprand2': Oprand2} try: Val = eval(EvalStr, {}, Dict) except Exception as Excpt: raise BadExpression(str(Excpt)) if Operator in {'and', 'or'}: if Val: Val = True else: Val = False if WrnExp: WrnExp.result = Val raise WrnExp return Val
def Eval(Operator, Oprand1, Oprand2 = None): WrnExp = None if Operator not in {"==", "!=", ">=", "<=", ">", "<", "in", "not in"} and \ (isinstance(Oprand1, type('')) or isinstance(Oprand2, type(''))): raise BadExpression(ERR_STRING_EXPR % Operator) if Operator in {'in', 'not in'}: if not isinstance(Oprand1, type('')): Oprand1 = IntToStr(Oprand1) if not isinstance(Oprand2, type('')): Oprand2 = IntToStr(Oprand2) TypeDict = { type(0) : 0, # For python2 long type type(sys.maxsize + 1) : 0, type('') : 1, type(True) : 2 } EvalStr = '' if Operator in {"!", "NOT", "not"}: if isinstance(Oprand1, type('')): raise BadExpression(ERR_STRING_EXPR % Operator) EvalStr = 'not Oprand1' elif Operator in {"~"}: if isinstance(Oprand1, type('')): raise BadExpression(ERR_STRING_EXPR % Operator) EvalStr = '~ Oprand1' else: if Operator in {"+", "-"} and (type(True) in {type(Oprand1), type(Oprand2)}): # Boolean in '+'/'-' will be evaluated but raise warning WrnExp = WrnExpression(WRN_BOOL_EXPR) elif type('') in {type(Oprand1), type(Oprand2)} and not isinstance(Oprand1, type(Oprand2)): # == between string and number/boolean will always return False, != return True if Operator == "==": WrnExp = WrnExpression(WRN_EQCMP_STR_OTHERS) WrnExp.result = False raise WrnExp elif Operator == "!=": WrnExp = WrnExpression(WRN_NECMP_STR_OTHERS) WrnExp.result = True raise WrnExp else: raise BadExpression(ERR_RELCMP_STR_OTHERS % Operator) elif TypeDict[type(Oprand1)] != TypeDict[type(Oprand2)]: if Operator in {"==", "!=", ">=", "<=", ">", "<"} and set((TypeDict[type(Oprand1)], TypeDict[type(Oprand2)])) == set((TypeDict[type(True)], TypeDict[type(0)])): # comparison between number and boolean is allowed pass elif Operator in {'&', '|', '^', "and", "or"} and set((TypeDict[type(Oprand1)], TypeDict[type(Oprand2)])) == set((TypeDict[type(True)], TypeDict[type(0)])): # bitwise and logical operation between number and boolean is allowed pass else: raise BadExpression(ERR_EXPR_TYPE) if isinstance(Oprand1, type('')) and isinstance(Oprand2, type('')): if ((Oprand1.startswith('L"') or Oprand1.startswith("L'")) and (not Oprand2.startswith('L"')) and (not Oprand2.startswith("L'"))) or \ (((not Oprand1.startswith('L"')) and (not Oprand1.startswith("L'"))) and (Oprand2.startswith('L"') or Oprand2.startswith("L'"))): raise BadExpression(ERR_STRING_CMP % (Oprand1, Operator, Oprand2)) if 'in' in Operator and isinstance(Oprand2, type('')): Oprand2 = Oprand2.split() EvalStr = 'Oprand1 ' + Operator + ' Oprand2' # Local symbols used by built in eval function Dict = { 'Oprand1' : Oprand1, 'Oprand2' : Oprand2 } try: Val = eval(EvalStr, {}, Dict) except Exception as Excpt: raise BadExpression(str(Excpt)) if Operator in {'and', 'or'}: if Val: Val = True else: Val = False if WrnExp: WrnExp.result = Val raise WrnExp return Val