Exemplo n.º 1
0
 def _result(self,globals,locals):
     assert('tools' in globals)
     assert('doc' in globals)
     ( keys, values, otherwise_idx ) = \
         self._gather_keys_and_values(globals,locals)
     if self._require_an_otherwise_clause() and \
        otherwise_idx is Conditional.MISSING:
         raise ConditionalMissingOtherwise(
             f'{self._path}: no "otherwise" clause provided')
     idx=self._index(keys)
     if idx is None:
         if otherwise_idx is Conditional.MISSING:
             raise ConditionalMissingOtherwise(
                 f'{self._path}: no clauses match and no '
                 f'"otherwise" value was given. {keys} {values}')
         self.__result=self[otherwise_idx]._raw('otherwise')
         if superdebug: _logger.debug(f'{self._path}: result=otherwise: {self.__result!r}')
         idx=otherwise_idx
     else:
         self.__result=values[idx]
         if superdebug: _logger.debug(f'{self._path}: result index {idx}: {self.__result!r}')
     if 'message' in self[idx]:
         message=from_config('message',self[idx].message,globals,locals,self._path)
         _logger.info(f'{self._path}[{idx}]: {message}')
     assert(self.__result is not Conditional.MISSING)
     return self.__result
Exemplo n.º 2
0
 def _gather_keys_and_values(self,globals,locals):
     keys=list()
     values=list()
     otherwise_idx=Conditional.MISSING
     for i in range(len(self)):
         vk=self[i]
         has_otherwise = vk._has_raw('otherwise')
         has_when = vk._has_raw('when')
         has_do = vk._has_raw('do')
         has_take = vk._has_raw('take')
         if has_do and has_take:
             raise ConditionalOverspecified(
                 f'{self._path}[{i}]: cannot have "do" and "take" in one entry')
         if has_otherwise and ( has_when or has_do or has_take ):
             raise ConditionalOverspecified(
                 f'{self._path}[{i}]: cannot have "otherwise" in the same entry '
                 'as "when," "take," or "do"')
         elif has_otherwise and i!=len(self)-1:
             raise ConditionalInvalidOtherwise(
                 f'{self._path}[{i}]: "otherwise" must be the last item')
         elif has_otherwise:
             otherwise_idx=i
         elif has_when and ( has_do or has_take ):
             values.append(vk._raw('do') if has_do else vk._raw('take'))
             vk_locals=multidict(vk,locals)
             raw_when=vk._raw('when')
             keys.append(from_config('when',raw_when,globals,vk_locals,
                                     f'{self._path}[{i}]'))
         else:
             raise ConditionalMissingDoWhen(
                 f'{self._path}[{i}]: entries must have both "take" and "when"'
                 'or "otherwise" (or "message").  You can use "do" in place of '
                 '"take" for backward compatibility.  Saw keys: '+
                 ', '.join(list(vk.keys())))
     return keys, values, otherwise_idx
Exemplo n.º 3
0
    def _result(self,globals,locals):
        rank_specs=list()
        for i in range(len(self)):
            spec=from_config('JobResourceSpecMaker',self._raw(i),globals,locals,f'{self._path}[{i}]')
            if superdebug: _logger.debug(f'Look at spec #{i} in {self._path}...')
            if not hasattr(spec,'_raw_child'):
                rank_specs.append(spec)
                continue

            # Get the value, from that new dict_eval, of all keys in spec.
            # Store it in the rank_specs list for the later constructor.
            with_parent_scope=multidict(spec,self._get_locals(),locals)
            ranks=dict()
            for key in spec.keys():
                ranks[key]=from_config(key,with_parent_scope._raw(key),globals,locals,f'{self._path}[{i}].{key}')
            rank_specs.append(ranks)
        return crow.sysenv.JobResourceSpec(rank_specs)
Exemplo n.º 4
0
 def _result(self,globals,locals):
     result={}
     for i in range(len(self)):
         d=from_config('MergeMapping',self._raw(i),globals,locals,f'{self._path}[{i}]')
         if not isinstance(d,collections.Mapping): continue
         if not d: continue
         if hasattr(d,'_raw_child'):
             result.update(d._raw_child())
         else:
             result.update(d)
     result=dict_eval(result,self._path,self._get_globals())
     return result
Exemplo n.º 5
0
 def _result(self,globals,locals):
     if 'select' not in self or 'otherwise' not in self or 'cases' not in self:
         raise KeyError(f'{self._path}: !Select must contain select, otherwise, and cases.')
     if not isinstance(self.cases,collections.Mapping):
         raise TypeError(f'{self._path}.cases: !Select cases must be a map')
     value=from_config('select',self._raw('select'),
                       globals,locals,self._path)
     if value in self.cases:
         if hasattr(self.cases,'_raw'):
             return self.cases._raw(value)
         return self.cases[value]
     return self._raw('otherwise')
Exemplo n.º 6
0
 def _result(self,globals,locals):
     result=[]
     for i in range(len(self)):
         d=from_config('AppendSequence',self._raw(i),globals,locals,f'{self._path}[{i}]')
         if not isinstance(d,collections.Sequence) or isinstance(d,str):
             raise TypeError(f'{self._path}: can only append lists.')
         if not len(d):
             continue
         if hasattr(d,'_raw_child'):
             result.extend(d._raw_child())
         else:
             result.extend(d)
     result=list_eval(result,self._path,self._get_globals())
     return result
Exemplo n.º 7
0
    def _check_scope(self, scope, stage, memo):
        if self.__my_id in memo:
            _logger.debug(
                f'{scope._path}: do not re-validate with {self._path}')
            return
        memo.add(self.__my_id)

        _logger.debug(f'{scope._path}: validate with {self._path}')

        checked = set()
        errors = list()
        template = copy(self)
        did_something = True

        # Main validation loop.  Iteratively validate, adding new
        # Templates as they become available via is_present.
        for var in template:
            _logger.debug(f'{scope._path}.{var}: validate...')
            try:
                scheme = template[var]
                if not isinstance(scheme, Mapping): continue  # not a template
                if stage and 'stages' in scheme:
                    if stage not in scheme.stages:
                        continue  # skip validation; wrong stage
                elif 'stages' in scheme:
                    continue  # skip validation of stage-specific schemes

                if 'precheck' in scheme:
                    scope[var] = scheme.precheck

                if var in scope:
                    validate_var(scope._path, scheme, var, scope[var])
                elif 'default' in scheme:
                    scope[var] = from_config(var, scheme._raw('default'),
                                             self._globals(), scope,
                                             f'{scope._path}.{var}')
                    _logger.debug(
                        f'{scope._path}.{var}: insert default {scope._raw(var)}'
                    )
                if var not in scope and 'if_present' in scheme:
                    _logger.debug(
                        f'{scope._path}.{var}: not present; skip if_present')
                if var in scope and 'if_present' in scheme:
                    _logger.debug(f'{scope._path}.{var}: evaluate if_present '
                                  f'{scheme._raw("if_present")._path}')
                    ip = from_config(var, scheme._raw('if_present'),
                                     self._globals(), scope,
                                     f'{scope._path}.{var}')
                    _logger.debug(f'{scope._path}.{var}: result = {ip!r}')
                    if not ip: continue
                    if not isinstance(ip, Template):
                        if not isinstance(ip, Mapping): continue
                        ip = Template(ip._raw_child(), ip._path,
                                      ip._get_globals())
                    _logger.debug(
                        f'{scope._path}.{var}: present ({scope._raw(var)!r}); '
                        f'add {ip._path} to validation')
                    ip._check_scope(scope, stage, memo)

                if 'override' in scheme:
                    override = from_config(
                        'override', template[var]._raw('override'),
                        scope._globals(), scope,
                        f'{scope._path}.Template.{var}.override')
                    if override is not None: scope[var] = override

            except (IndexError, AttributeError, TypeError, ValueError) as pye:
                errors.append(
                    f'{scope._path}.{var}: {type(pye).__name__}: {pye}')
                _logger.debug(f'{scope._path}.{var}: {pye}', exc_info=True)
            except ConfigError as ce:
                errors.append(str(ce))
                _logger.debug(
                    f'{scope._path}.{var}: {type(ce).__name__}: {ce}',
                    exc_info=True)

        # Insert default values for all templates found thus far and
        # detect any missing, non-optional, variables
        missing = list()
        for var in template:
            if var not in scope:
                tmpl = template[var]
                if not hasattr(tmpl, '__getitem__') or not hasattr(
                        tmpl, 'update'):
                    raise TypeError(
                        f'{self._path}.{var}: All entries in a !Template must be maps not {type(tmpl).__name__}'
                    )
                if 'default' not in tmpl and not tmpl.get('optional', False):
                    missing.append(var)

        # Second pass checking for required variables that have no
        # values.  This second pass deals with variables that were
        # updated by an "override" clause.
        reported_missing = set(missing)
        in_scope = set([k for k in scope.keys()])
        still_missing = reported_missing - in_scope
        if still_missing:
            raise VariableMissing(f'{scope._path}: missing: ' +
                                  ', '.join(still_missing) + ' in: ' +
                                  ', '.join([k for k in scope.keys()]))

        # Check for variables that evaluate to an error
        for key, expr in scope._raw_child().items():
            if hasattr(expr, '_is_error'):
                try:
                    scope[key]
                except ConfigUserError as ce:
                    errors.append(f'{scope._path}.{key}: {ce}')

        if errors: raise TemplateErrors(errors)
Exemplo n.º 8
0
 def __init__(self,
              suite,
              viewed,
              path,
              parent,
              task_array_dimensions=None,
              task_array_dimval=None,
              task_array_dimidx=None):
     # assert(isinstance(suite,Suite))
     # assert(isinstance(viewed,dict_eval))
     assert (hasattr(self, '_iter_raw'))
     assert (isinstance(parent, SuiteView))
     assert (not isinstance(viewed, SuiteView))
     if task_array_dimensions:
         self.task_array_dimensions = OrderedDict(task_array_dimensions)
     else:
         self.task_array_dimensions = OrderedDict()
     if task_array_dimidx:
         self.task_array_dimidx = OrderedDict(task_array_dimidx)
     else:
         self.task_array_dimidx = OrderedDict()
     if task_array_dimval:
         self.task_array_dimval = OrderedDict(task_array_dimval)
     else:
         self.task_array_dimval = OrderedDict()
     self.suite = suite
     self.viewed = viewed
     self.viewed.task_path_list = path[1:]
     self.viewed.task_path_str = '/' + '/'.join(path[1:])
     self.viewed.task_path_var = '.'.join(path[1:])
     if self.viewed.task_path_var:
         self.viewed._path = self.viewed.task_path_var
     if type(self.viewed) in SUITE_CLASS_MAP:
         self.viewed.up = parent
         self.viewed.this = self.viewed
     elif not isinstance(self.viewed, Cycle):
         assert (False)
     self.path = SuitePath(path)
     self.parent = parent
     self.__cache = {}
     assert (isinstance(self.viewed, Cycle) or 'this' in self.viewed)
     if isinstance(self.viewed, Slot):
         locals = multidict(self.parent, self.viewed)
         globals = self.viewed._get_globals()
         for k, v in self.viewed._raw_child().items():
             if hasattr(v, '_as_dependency'): continue
             self.viewed[k] = from_config(k, v, globals, locals,
                                          self.viewed._path)
     if isinstance(self.viewed, Task):
         assert (isinstance(self.viewed, Cycle) or 'this' in self.viewed)
         for k, v in self.viewed.items():
             copied = False
             if hasattr(v, "_validate"):
                 copied = True
                 v = copy(v)
                 v._validate('suite')
             if self.__can_wrap(v):
                 if not copied:
                     v = copy(v)
                 self.viewed[k] = v
     assert (isinstance(viewed, Cycle)
             or self.viewed.task_path_var != parent.task_path_var)