def exec_If(self, node, scope): ''' In our implementation, we try to evaluate the if condition. If the value is known, then we execute the appropriate branch. Otherwise, we choose randomly a branch. ''' from random import randint test_typez = self.eval_code(node.test,scope) if isinstance(test_typez,Typez): if test_typez.value is not None: if (not is_none(test_typez)) and test_typez.value!="" and test_typez.value!=0 and not (test_typez.scope['__class__']==self.extern_scope['bool'] and not test_typez.value): for _node in node.body: self.eval_code(_node, scope) else: for _node in node.orelse: self.eval_code(_node, scope) else: self.nondet=True bit = randint(0,1) if bit: for _node in node.body: self.eval_code(_node, scope) else: for _node in node.orelse: self.eval_code(_node, scope) else: self.warn(node, symbol = 'evaluation of condition failed', message = 'could not evaluate if condition')
def _exec_fun(self, fun_type, args, keywords, scope, create_scope = True, node = None): """ executes function with given args in the given scope. When create_scope is True, it creates new scope for the function executing with parameter scope as its parent. Otherwise, it executes function in the given scope. """ #if we dont know the fun_type, return any_type if fun_type.kind=='any': return any_type from random import randint if fun_type == self.extern_scope['inf_hasattr']: a=args[0] b=args[1] if b.value is not None: res = a.resolve(b.value) if res is None: return Typez(kind='const', value = False, __class__ = self.extern_scope['bool']) else: return Typez(kind='const', value = True, __class__ = self.extern_scope['bool']) self.nondet=True bit = randint(0,1) if bit: return Typez(kind='const', value = True, __class__ = self.extern_scope['bool']) else: return Typez(kind='const', value = False, __class__ = self.extern_scope['bool']) if fun_type == self.extern_scope['inf_random']: self.nondet=True bit = randint(0,1) if bit: return Typez(kind='const', value = 1, __class__ = self.extern_scope['num']) else: return Typez(kind='const', value = 0, __class__ = self.extern_scope['num']) if fun_type == self.extern_scope['inf_equal']: a=args[0] b=args[1] if a.value is not None and b.value is not None: left = a.value right = b.value if isinstance(a.value, bool): if a.value: left = 1 else: left = 0 if isinstance(b.value, bool): if b.value: right = 1 else: right = 0 if left==right: return Typez(kind='const', value = True, __class__ = self.extern_scope['bool']) else: return Typez(kind='const', value = False, __class__ = self.extern_scope['bool']) else: self.nondet=True bit = randint(0,1) if bit: return Typez(kind='const', value = True, __class__ = self.extern_scope['bool']) else: return Typez(kind='const', value = False, __class__ = self.extern_scope['bool']) if fun_type == self.extern_scope['inf_is']: #we truly determine only if the statement is in form - smth is None if is_none(args[1]): if is_none(args[0]): return Typez(kind='const', value = True, __class__ = self.extern_scope['bool']) else: return Typez(kind='const', value = False, __class__ = self.extern_scope['bool']) else: self.nondet=True bit = randint(0,1) if bit: return Typez(kind='const', value = True, __class__ = self.extern_scope['bool']) else: return Typez(kind='const', value = False, __class__ = self.extern_scope['bool']) if fun_type == self.extern_scope['isinstance']: if isinstance(args[0],Typez) and isinstance(args[1],Typez): instance = args[0] clazz = args[1] res = instance.resolve_class(clazz) if not res is None: return Typez(kind='const', value = True, __class__ = self.extern_scope['bool']) else: return Typez(kind='const', value = False, __class__ = self.extern_scope['bool']) else: self.warn(node, symbol = 'isinstance error', message = 'isinstance bad arguments') if fun_type == self.extern_scope['inf_setattr']: attr = args[1] if isinstance(attr, Typez) and isinstance(attr.value, str): attr = attr.value if isinstance(attr, str): args[0].scope[attr] = args[2] if create_scope: fun_scope = Scope(parent = scope) else: fun_scope = scope def_args = fun_type.node.args.args def_default_args = fun_type.node.args.defaults def_args_names = [arg.arg for arg in def_args] count_given_args = len(args)+len(keywords) if count_given_args > len(def_args) or count_given_args+len(def_default_args)< len(def_args): symbol = not_none(safe_resolve(node, 'func.attr'), safe_resolve(node, 'func.id')) self.warn(node, symbol = symbol, message = 'bad number of arguments (%d given, %d expected)'%(len(args), len(def_args))) for keyword in keywords: if not keyword in def_args_names: symbol = not_none(safe_resolve(node, 'func.attr'), safe_resolve(node, 'func.id')) self.warn(node, symbol = symbol, message = 'unexpected keyword argument %s'%(keyword)) for i,arg in enumerate(def_args): if i<len(args): if arg.arg in keywords: symbol = not_none(safe_resolve(node, 'func.attr'), safe_resolve(node, 'func.id')) self.warn(node, symbol = symbol, message = 'multiple arguments for keyword argument %s'%(arg.arg)) fun_scope[arg.arg] = args[i] else: found=False for j,key in enumerate(keywords): if key==arg.arg: found=True fun_scope[arg.arg]=keywords[key] if not found: lengthFromEnd = len(def_args)-i if len(def_default_args) >= lengthFromEnd: fun_scope[arg.arg]=self.eval_code(def_default_args[-lengthFromEnd],scope) else: fun_scope[arg.arg] = any_type try: for _node in fun_type.node.body: self.eval_code(_node, fun_scope) except ReturnException as e: res=e.res if isinstance(res, Typez) and "__class__" in res.scope and (res.scope["__class__"] == self.extern_scope['ProblemException']): error = res.scope["error"] message = res.scope["message"] #symbol = res.scope["symbol"] symbol = None for key,val in scope.items(): if val==error: symbol = key #when error is caused by constant, symbol is its type if symbol is None: if hasattr(error.scope['__class__'].node, 'name'): symbol = error.scope['__class__'].node.name else: #default symbol symbol = 'Type error' if is_none(message): #default message because it is very often used message_value = "unsupported operand type" else: message_value = message.value self.warn(node, message_value, symbol) return any_type if isinstance(res, Typez) and "__class__" in res.scope and (res.scope["__class__"] == self.extern_scope['TypeContainer']): gen_type=res.scope["T"] result = Typez(kind='const',__class__ = gen_type) return result return res if fun_type.kind == 'classdef': return args[0]