def replace(p): asdict = lambda d: \ d.asdict(eval=False) if isinstance(d, _DotDict) else d if isinstance(p, (list, tuple)): p = [asdict(e) for e in p] else: p = asdict(p) return recursive_apply(p, func_map, skip_inner_module)
def _normalize(self, value): def normalize_map(mapping): d = _DotDict({}, normalize=False) for key, value in mapping.items(): d[key] = value return d._mapping return recursive_apply(value, {collections.Mapping: normalize_map})
def skip_inner_module(value): if not isinstance(value, collections.Mapping): return None if value.get('type') != 'module': return None # recursively replace inner module kwargs inner_kwargs = value.get('kwargs', {}) kwargs = {k: v for k, v in value.items() if k in inner_kwargs} value = dict(value, **recursive_apply(kwargs, func_map)) return _replace_module_kwargs(value)
def _eval(self, value, parent): def eval_tag(value): return value.__class__(self._eval(value.content, parent)).value() def eval_str(value): regex = r'\$\((\.?[_a-zA-Z][_a-zA-Z0-9\.\s\n\t]*)\)' while True: keys = re.findall(regex, value, re.MULTILINE) if not keys: break for k in keys: placeholder = '$({})'.format(k) k = k.replace(' ', '').replace('\n', '').replace('\t', '') try: if k.startswith('.'): # relative path v = parent[k[1:]] else: # absolute path v = self._root[k] except KeyError: raise KeyError( 'Attempting to resolve a non-existent key-path ' 'with placeholder {!r}.'.format(placeholder)) is_unique = not value.replace(placeholder, '').strip() if is_unique: return v if isinstance(v, collections.Mapping): if not is_unique: raise ValueError( 'Do not know how to replace {!r} where {!r} ' 'accesses a mapping.'.format( value, placeholder)) return v else: value = value.replace(placeholder, str(v)) return value def skip_map(value): if not isinstance(value, collections.Mapping): return None if not isinstance(value, _DotDict): return _DotDict(value, self._root, False) return value funcs = {YamlScalarTag: eval_tag, str: eval_str} return recursive_apply(value, funcs, skip_map)
def asdict(self, eval=True): if not eval: return self._mapping return recursive_apply(self, {collections.Mapping: lambda m: dict(m)})
def replace(params, key): p = copy.deepcopy(params[key]) params[key] = recursive_apply(p, {str: replace_str}, skip_inner_module)