Пример #1
0
 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__)
Пример #2
0
    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