def func(ret, *args, **kwargs): rval = ret["response"] and from_pickle(do_unpickle(ret["response"])) reca = ret["recached"] and from_pickle(do_unpickle(ret["recached"])) # recache all indicated objects [clean_object_caches(obj) for obj in reca] if f: return f(rval, *args, **kwargs) else: return rval
def executecode(self, source, environment): """ Remote code execution source - Python code snippet environment - pickled dictionary of environment variables. They are stored in two keys "normal" and "objs" where normal holds a dictionary of normally pickled python objects wheras objs points to a dictionary of database represenations ((app,key),id). The environment's entries will be made available as local variables during the execution. Normal eval results will be returned as-is. For more complex code snippets (run by exec), the _return function is available: All data sent to _return(retval) will be returned from this system whenever the system finishes. Multiple calls to _return will result in a list being return. The return value is pickled and thus allows for returning any pickleable data. """ class Ret(object): "Helper class for holding returns from exec" def __init__(self): self.returns = [] def __call__(self, *args, **kwargs): self.returns.extend(list(args)) def get_returns(self): lr = len(self.returns) val = lr and (lr == 1 and self.returns[0] or self.returns) or None if val not in (None, [], ()): return do_pickle(to_pickle(val)) else: return "" _return = Ret() available_vars = {"_return": _return} if environment: # load environment try: environment = from_pickle(do_unpickle(environment)) available_vars.update(environment) except Exception: logger.log_trace() # try to execute with eval first try: ret = eval(source, {}, available_vars) if ret not in (None, [], ()): ret = _return.get_returns() or do_pickle(to_pickle(ret)) else: ret = "" except Exception: # use exec instead exec source in available_vars ret = _return.get_returns() # get the list of affected objects to recache objs = PROC_MODIFIED_OBJS.values() # we need to include the locations too, to update their content caches objs = objs + list(set([o.location for o in objs if hasattr(o, "location") and o.location])) # print "objs:", objs # print "to_pickle", to_pickle(objs, emptypickle=False, do_pickle=False) if objs not in (None, [], ()): to_recache = do_pickle(to_pickle(objs)) else: to_recache = "" # empty the list without loosing memory reference # PROC_MODIFIED_OBJS[:] = [] PROC_MODIFIED_OBJS.clear() # TODO - is this not messing anything up? return {"response": ret, "recached": to_recache}
def executecode(self, source, environment): """ Remote code execution source - Python code snippet environment - pickled dictionary of environment variables. They are stored in two keys "normal" and "objs" where normal holds a dictionary of normally pickled python objects wheras objs points to a dictionary of database represenations ((app,key),id). The environment's entries will be made available as local variables during the execution. Normal eval results will be returned as-is. For more complex code snippets (run by exec), the _return function is available: All data sent to _return(retval) will be returned from this system whenever the system finishes. Multiple calls to _return will result in a list being return. The return value is pickled and thus allows for returning any pickleable data. """ class Ret(object): "Helper class for holding returns from exec" def __init__(self): self.returns = [] def __call__(self, *args, **kwargs): self.returns.extend(list(args)) def get_returns(self): lr = len(self.returns) val = lr and (lr == 1 and self.returns[0] or self.returns) or None if val not in (None, [], ()): return do_pickle(to_pickle(val)) else: return "" _return = Ret() available_vars = {'_return': _return} if environment: # load environment try: environment = from_pickle(do_unpickle(environment)) available_vars.update(environment) except Exception: logger.log_trace() # try to execute with eval first try: ret = eval(source, {}, available_vars) if ret not in (None, [], ()): ret = _return.get_returns() or do_pickle(to_pickle(ret)) else: ret = "" except Exception: # use exec instead exec source in available_vars ret = _return.get_returns() # get the list of affected objects to recache objs = list(set(PROC_MODIFIED_OBJS)) # we need to include the locations too, to update their content caches objs = objs + list( set([ o.location for o in objs if hasattr(o, "location") and o.location ])) #print "objs:", objs #print "to_pickle", to_pickle(objs, emptypickle=False, do_pickle=False) if objs not in (None, [], ()): to_recache = do_pickle(to_pickle(objs)) else: to_recache = "" # empty the list without loosing memory reference PROC_MODIFIED_OBJS[:] = [] return {'response': ret, 'recached': to_recache}