Exemplo n.º 1
0
    def check_config(self, config, c_args, **kwargs):
        """
        Uses the config schema valid_configs to validate config arguments.  A leading '0_' indicates that the argument
        is permitted to be None.

        :param config: a configuration entry
        :param c_args: a tuple of args
        :param kwargs:
        :return:
        """
        vc = valid_configs[config]
        if len(c_args) != vc.nargs:
            raise ValueError(
                'Wrong number of arguments (%d supplied; %d required)' %
                (len(c_args), vc.nargs))
        for i, t in enumerate(vc.argtypes):
            if t.startswith('0_'):
                if c_args[i] is None:
                    continue
                t = t.split('_')[1]
            if t == 'hint':
                if c_args[i] in ('context', 'flowable', 'quantity'):
                    continue
            elif t == 'float':
                if isinstance(c_args[i], float) or isinstance(c_args[i], int):
                    continue
            elif t == 'str':
                if isinstance(c_args[i], str):
                    continue
            elif t == 'direction':
                try:
                    check_direction(c_args[i])
                except KeyError:
                    raise ValueError(
                        'Argument %d [%s] is not a valid direction' %
                        (i, c_args[i]))
                continue
            elif t == 'context':
                # check to ensure t is a recognized locally defined context
                cx = self._archive.tm[c_args[i]]
                if cx is None:
                    raise ValueError(
                        'Argument %d [%s] is not a recognized local context' %
                        (i, c_args[i]))
                continue
            else:
                '''
                if not isinstance(c_args[i], str):
                    raise TypeError('%s [%d:%s]: Configuraton arguments must be strings and not entities' % (config, i,
                                                                                                             c_args[i]))
                '''
                e = self._archive.retrieve_or_fetch_entity(c_args[i])
                if e.entity_type == t:
                    continue
            raise TypeError('Argument %d should be type %s' % (i, t))
        return True
Exemplo n.º 2
0
 def emitters(self, flow, direction=None, context=None, **kwargs):
     self.check_bg()
     if context is not None:
         context = self._index.get_context(context)
     if direction is not None:
         direction = check_direction(direction)
     for x in self._flat.emitters(flow, direction, context):
         yield self._exchange_from_term_ref(x)
Exemplo n.º 3
0
def _create_fragment(flow, direction, uuid=None, parent=None, name=None, comment=None, value=None, balance=False,
                     **kwargs):
    """

    :param flow:
    :param direction:
    :param uuid:
    :param parent:
    :param name:
    :param comment:
    :param value:
    :param balance:
    :param kwargs:
    :return:
    """
    direction = check_direction(direction)
    if name is None:
        name = flow['Name']
    name = kwargs.pop('Name', name)

    if comment is None:
        comment = ''
    comment = kwargs.pop('Comment', comment)
    if parent is None:
        if value is None:
            value = 1.0
        if uuid is None:
            frag = LcFragment.new(name, flow, direction, Comment=comment, exchange_value=value,
                                  **kwargs)
        else:
            frag = LcFragment(uuid, flow, direction, Comment=comment, exchange_value=value, Name=name,
                              **kwargs)
    else:
        if parent.term.is_null:
            parent.to_foreground()
        else:
            parent.unset_background()
        if balance or parent.term.is_subfrag:
            # exchange value set during traversal
            value = None

        if uuid is None:
            frag = LcFragment.new(name, flow, direction, parent=parent, Comment=comment,
                                  exchange_value=value, balance_flow=balance, **kwargs)
        else:
            frag = LcFragment(uuid, flow, direction, parent=parent, Comment=comment, exchange_value=value,
                              balance_flow=balance, Name=name, **kwargs)

        # traverse -- may not need to do this anymore if we switch to live traversals for everything
        # parent.traverse(None)  # in fact, let's skip it

    # this cannot be done internally-- really we need create_fragment_from_exchange to do this
    # if flow.context.elementary:
    #     frag.terminate(flow.context)

    return frag
Exemplo n.º 4
0
 def direction(self, value):
     if value is None:
         # this is the default: should set the direction by the reference.  Only non-none if from_json
         if self.is_process and self.valid:
             rx = self.term_node.reference(self.term_flow)
             value = rx.direction
         else:
             # for fg, invert direction doesn't make sense. for subfragments, direction is ignored
             value = comp_dir(self._parent.direction)
     self._direction = check_direction(value)
Exemplo n.º 5
0
 def remove_reference(self, flow, dirn):
     dirn = check_direction(dirn)
     k = (flow.external_ref, dirn)
     rx = self._reference_entity[k]
     if rx.key in self._exchanges:
         raise DuplicateExchangeError(rx)
     self._reference_entity.pop(k)
     rx.unset_ref(self)
     self.remove_allocation(rx)
     self._exchanges[rx.key] = rx
     if self._alloc_by_quantity is not None:
         self.allocate_by_quantity(self._alloc_by_quantity)
Exemplo n.º 6
0
 def set_reference(self, flow, dirn):
     """
     Exchange must already exist.
     fmr: If the exchange is currently terminated, the termination is removed.
     now: exchanges terminated to non-elementary context are now allowed
     :param flow:
     :param dirn:
     :return:
     """
     # self._strip_term(flow, dirn)
     dirn = check_direction(dirn)
     if (flow.external_ref, dirn) in self._reference_entity:
         # already a reference
         return self._reference_entity[flow.external_ref, dirn]
     else:
         rx = list(self._gen_exchanges(flow, dirn, reference=False))
         if len(rx) == 0:
             raise NoExchangeFound(flow, dirn)
         elif len(rx) > 1:
             raise AmbiguousReferenceError(rx)
         else:
             self._set_reference(rx[0])
             return rx[0]
Exemplo n.º 7
0
    def add_exchange(self, flow, dirn, reference=None, value=None, termination=None, add_dups=False):
        """
        This is used to create Exchanges and ExchangeValues and AllocatedExchanges.

        If the flow+dir+term is already in the exchange set:
            if no reference is specified and/or no value is specified- nothing to do
            otherwise (if reference and value are specified):
                upgrade the exchange to an allocatedExchange and add the new reference exch val
        otherwise:
            if reference is specified, create an AllocatedExchange
            otherwise create an Exchange / ExchangeValue

        :param flow:
        :param dirn:
        :param reference:
        :param value:
        :param termination: None for reference or cutoff flows; a context for elementary flows; a valid external_ref
         for terminated intermediate flows.
        :param add_dups: (False) set to true to handle "duplicate exchange" errors by cumulating their values
        :return:
        """
        dirn = check_direction(dirn)
        if (flow.external_ref, dirn) in self._reference_entity:
            raise AlreadyAReference((flow, dirn))
        _x = hash((self.external_ref, flow.external_ref, dirn, termination))
        if _x in self._exchanges:
            if value is None or value == 0:
                return None
            e = self._exchanges[_x]
            if reference is None:
                if isinstance(value, dict):
                    e.update(value)
                else:
                    try:
                        e.value = value  # this will catch already-set errors
                    except DuplicateExchangeError:
                        if add_dups:
                            e.add_to_value(value)
                        else:
                            print('Duplicate exchange in process %s:\n%s' % (self.external_ref, e))
                            raise
                return e

            else:
                try:
                    e[reference] = value  # this will catch already-set errors
                except DuplicateExchangeError:
                    if add_dups:
                        e.add_to_value(value, reference=reference)
                    else:
                        print('Duplicate exchange in process %s:\n%s' % (self.external_ref, e))
                        raise
                except ValueError:
                    print('Error adding [%s] = %10.3g for exchange\n%s\nto process\n%s' % (
                        reference.flow.external_ref, value, e, self.external_ref))
                    raise

                return e

        else:
            if isinstance(value, Number) or value is None:
                if reference is None:
                    e = ExchangeValue(self, flow, dirn, value=value, termination=termination)
                else:
                    if reference not in self.reference_entity:
                        raise KeyError('Specified reference is not registered with process: %s' % reference)
                    e = ExchangeValue(self, flow, dirn, value=None, termination=termination)
                    e[reference] = value

            elif isinstance(value, dict):
                e = ExchangeValue(self, flow, dirn, value_dict=value, termination=termination)
            else:
                raise TypeError('Unhandled value type %s' % type(value))

            # This is the only point an exchange (must be ExchangeValue) is added to the process (see also _strip_term)
            self._exchanges[e.key] = e
            self._exch_map[e.flow.external_ref].add(e)
            return e