def _setup_db_record(self): super(FunctionProcess, self)._setup_db_record() add_source_info(self.calc, self._func) # Save the name of the function self.calc._set_attr(PROCESS_LABEL_ATTR, self._func.__name__)
def wrapped_function(*args, **kwargs): """ This wrapper function is the actual function that is called. """ from django.db import transaction # Note: if you pass a lambda function, the name will be <lambda>; moreover # if you define a function f, and then do "h=f", h.__name__ will # still return 'f'! function_name = func.__name__ if not function_name.endswith('_inline'): raise ValueError( "The function name that is wrapped must end " "with '_inline', while its name is '{}'".format(function_name)) if args: print args raise ValueError("Arguments of inline function should be " "passed as key=value") # Check the input values for k, v in kwargs.iteritems(): if not isinstance(v, Data): raise TypeError("Input data to a wrapped inline calculation " "must be Data nodes") # kwargs should always be strings, no need to check # if not isinstance(k, basestring): # raise TypeError("") # Create the calculation (unstored) c = InlineCalculation() # Add data input nodes as links for k, v in kwargs.iteritems(): c.add_link_from(v, label=k) # Try to get the source code add_source_info(c, func) # Run the wrapped function retval = func(**kwargs) # Check the output values if not isinstance(retval, dict): raise TypeError("The wrapped function did not return a dictionary") for k, v in retval.iteritems(): if not isinstance(k, basestring): raise TypeError("One of the key of the dictionary returned by " "the wrapped function is not a string: " "'{}'".format(k)) if not isinstance(v, Data): raise TypeError("One of the values (for key '{}') of the " "dictionary returned by the wrapped function " "is not a Data node".format(k)) if v.is_stored: raise ModificationNotAllowed( "One of the values (for key '{}') of the " "dictionary returned by the wrapped function " "is already stored! Note that this node (and " "any other side effect of the function) are " "not going to be undone!".format(k)) # Add link to output data nodes for k, v in retval.iteritems(): v.add_link_from(c, label=k, link_type=LinkType.RETURN) with transaction.atomic(): # I call store_all for the Inline calculation; # this will store also the inputs, if needed. c.store_all(with_transaction=False) # As c is already stored, I just call store (and not store_all) # on each output for v in retval.itervalues(): v.store(with_transaction=False) # Return the calculation and the return values return c, retval