def _merge_dicts(dict1, dict2, list_merge_func, item_merger, max_levels=0): result = {} for key, value1 in six.iteritems(dict1): result[key] = value1 if key in dict2: value2 = dict2[key] if max_levels != 1 and isinstance(value2, utils.MappingType): if not isinstance(value1, utils.MappingType): raise TypeError( 'Cannot merge {0} with {1}'.format( type(value1), type(value2))) result[key] = _merge_dicts( value1, value2, list_merge_func, item_merger, 0 if max_levels == 0 else max_levels - 1) elif max_levels != 1 and utils.is_sequence(value2): if not utils.is_sequence(value1): raise TypeError( 'Cannot merge {0} with {1}'.format( type(value1), type(value2))) result[key] = list_merge_func(value1, value2) else: result[key] = item_merger(value1, value2) for key2, value2 in six.iteritems(dict2): if key2 not in result: result[key2] = value2 return result
def create(cls, data, package, name=None): namespaces = data.get('Namespaces') or {} ns_resolver = namespace_resolver.NamespaceResolver(namespaces) if not name: name = ns_resolver.resolve_name(data['Name']) parent_class_names = data.get('Extends') parent_classes = [] if parent_class_names: if not utils.is_sequence(parent_class_names): parent_class_names = [parent_class_names] for parent_name in parent_class_names: full_name = ns_resolver.resolve_name(parent_name) parent_classes.append(package.find_class(full_name)) type_obj = cls(ns_resolver, name, package, parent_classes) properties = data.get('Properties') or {} for property_name, property_spec in properties.iteritems(): spec = typespec.PropertySpec(property_spec, type_obj) type_obj.add_property(property_name, spec) methods = data.get('Methods') or data.get('Workflow') or {} method_mappings = { 'initialize': '.init', 'destroy': '.destroy' } for method_name, payload in methods.iteritems(): type_obj.add_method( method_mappings.get(method_name, method_name), payload) return type_obj
def _create_class(cls, name, ns_resolver, data, package, *args, **kwargs): parent_class_names = data.get('Extends') parent_classes = [] if parent_class_names: if not utils.is_sequence(parent_class_names): parent_class_names = [parent_class_names] for parent_name in parent_class_names: full_name = ns_resolver.resolve_name(str(parent_name)) parent_classes.append(package.find_class(full_name)) type_obj = cls( ns_resolver, name, package, parent_classes, data.get('Meta'), data.get('Import'), *args, **kwargs) properties = data.get('Properties') or {} for property_name, property_spec in six.iteritems(properties): spec = murano_property.MuranoProperty( type_obj, property_name, property_spec) type_obj.add_property(spec) methods = data.get('Methods') or data.get('Workflow') or {} method_mappings = { 'initialize': '.init', 'destroy': '.destroy' } for method_name, payload in six.iteritems(methods): type_obj.add_method( method_mappings.get(method_name, method_name), payload) return type_obj
def evaluate(value, context, freeze=True): list_type = tuple if freeze else list dict_type = yaqlutils.FrozenDict if freeze else dict set_type = frozenset if freeze else set if isinstance(value, (dsl_types.YaqlExpression, yaql.language.expressions.Statement)): return value(context) elif isinstance(value, yaqlutils.MappingType): return dict_type( (evaluate(d_key, context, freeze), evaluate(d_value, context, freeze)) for d_key, d_value in six.iteritems(value)) elif yaqlutils.is_sequence(value): return list_type(evaluate(t, context, freeze) for t in value) elif isinstance(value, yaqlutils.SetType): return set_type(evaluate(t, context, freeze) for t in value) elif yaqlutils.is_iterable(value): return list_type( evaluate(t, context, freeze) for t in yaqlutils.limit_iterable( value, constants.ITERATORS_LIMIT)) elif isinstance(value, dsl_types.MuranoObjectInterface): return value.object else: return value
def _map_list(self, data, spec, context): if not utils.is_sequence(data): if data is None or data is dsl.NO_VALUE: data = [] else: data = [data] if len(spec) < 1: return data shift = 0 max_length = sys.maxint min_length = 0 if isinstance(spec[-1], types.IntType): min_length = spec[-1] shift += 1 if len(spec) >= 2 and isinstance(spec[-2], types.IntType): max_length = min_length min_length = spec[-2] shift += 1 if not min_length <= len(data) <= max_length: raise exceptions.ContractViolationException( 'Array length {0} is not within [{1}..{2}] range'.format( len(data), min_length, max_length)) def map_func(): for index, item in enumerate(data): spec_item = ( spec[-1 - shift] if index >= len(spec) - shift else spec[index] ) yield self._map(item, spec_item, context) return tuple(map_func())
def _map(self, data, spec, context): child_context = context.create_child_context() if isinstance(spec, dsl_types.YaqlExpression): child_context[''] = data return spec(context=child_context) elif isinstance(spec, utils.MappingType): return self._map_dict(data, spec, child_context) elif utils.is_sequence(spec): return self._map_list(data, spec, child_context) else: return self._map_scalar(data, spec)
def _map(self, data, spec, context, path): child_context = context.create_child_context() if isinstance(spec, dsl_types.YaqlExpression): child_context[''] = data try: return spec(context=child_context) except exceptions.ContractViolationException as e: e.path = path raise elif isinstance(spec, utils.MappingType): return self._map_dict(data, spec, child_context, path) elif utils.is_sequence(spec): return self._map_list(data, spec, child_context, path) else: return self._map_scalar(data, spec)
def bind(obj, mappings): if isinstance(obj, types.StringTypes) and obj.startswith('$'): value = _convert_macro_parameter(obj[1:], mappings) if value is not None: return value elif utils.is_sequence(obj): return [bind(t, mappings) for t in obj] elif isinstance(obj, collections.Mapping): result = {} for key, value in obj.iteritems(): result[bind(key, mappings)] = bind(value, mappings) return result elif isinstance(obj, types.StringTypes) and obj.startswith('$'): value = _convert_macro_parameter(obj[1:], mappings) if value is not None: return value return obj
def evaluate(value, context): if isinstance(value, (dsl_types.YaqlExpression, yaql.language.expressions.Statement)): return value(context) elif isinstance(value, yaqlutils.MappingType): return yaqlutils.FrozenDict( (evaluate(d_key, context), evaluate(d_value, context)) for d_key, d_value in six.iteritems(value) ) elif yaqlutils.is_sequence(value): return tuple(evaluate(t, context) for t in value) elif isinstance(value, yaqlutils.SetType): return frozenset(evaluate(t, context) for t in value) elif yaqlutils.is_iterable(value): return tuple(evaluate(t, context) for t in yaqlutils.limit_iterable(value, constants.ITERATORS_LIMIT)) elif isinstance(value, dsl_types.MuranoObjectInterface): return value.object else: return value
def _map(self, data, spec, context, path): if is_passkey(data): return data child_context = context.create_child_context() if isinstance(spec, dsl_types.YaqlExpression): child_context[''] = data try: result = spec(context=child_context) return result except exceptions.ContractViolationException as e: e.path = path raise elif isinstance(spec, utils.MappingType): return self._map_dict(data, spec, child_context, path) elif utils.is_sequence(spec): return self._map_list(data, spec, child_context, path) else: return self._map_scalar(data, spec)
def is_list(arg): """:yaql:isList Returns true if arg is a list, false otherwise. :signature: isList(arg) :arg arg: value to be checked :argType arg: any :returnType: boolean .. code:: yaql> isList([1, 2]) true yaql> isList({"a" => 1}) false """ return utils.is_sequence(arg)
def _map_list(self, data, spec, context, path): if not utils.is_sequence(data): if data is None or data is dsl.NO_VALUE: data = [] else: data = [data] if len(spec) < 1: return data shift = 0 max_length = -1 min_length = 0 if isinstance(spec[-1], int): min_length = spec[-1] shift += 1 if len(spec) >= 2 and isinstance(spec[-2], int): max_length = min_length min_length = spec[-2] shift += 1 if max_length >= 0 and not min_length <= len(data) <= max_length: raise exceptions.ContractViolationException( 'Array length {0} is not within [{1}..{2}] range'.format( len(data), min_length, max_length)) elif not min_length <= len(data): raise exceptions.ContractViolationException( 'Array length {0} must not be less than {1}'.format( len(data), min_length)) def map_func(): for index, item in enumerate(data): spec_item = ( spec[-1 - shift] if index >= len(spec) - shift else spec[index] ) yield self._map( item, spec_item, context, '{0}[{1}]'.format(path, index)) return tuple(map_func())
def evaluate(value, context): if isinstance(value, (dsl_types.YaqlExpression, yaql.language.expressions.Statement)): return value(context) elif isinstance(value, yaqlutils.MappingType): return yaqlutils.FrozenDict( (evaluate(d_key, context), evaluate(d_value, context)) for d_key, d_value in six.iteritems(value)) elif yaqlutils.is_sequence(value): return tuple(evaluate(t, context) for t in value) elif isinstance(value, yaqlutils.SetType): return frozenset(evaluate(t, context) for t in value) elif yaqlutils.is_iterable(value): return tuple( evaluate(t, context) for t in yaqlutils.limit_iterable( value, constants.ITERATORS_LIMIT)) elif isinstance(value, dsl_types.MuranoObjectInterface): return value.object else: return value
def is_list(arg): return utils.is_sequence(arg)
def setter(src_property, value): src = src_property.get() if utils.is_sequence(src): src_property.set(src[:index] + (value,) + src[index + 1:])
def getter(src): if utils.is_sequence(src): return src[index] else: raise ValueError('indexation may only be applied to lists')
def setter(src_property, value): src = src_property.get() if utils.is_sequence(src): src_property.set(src[:index] + (value, ) + src[index + 1:])
def setter(src_property, value): src = src_property.get() if utils.is_sequence(src): src_property.set(src[:index] + (value, ) + src[index + 1:]) elif isinstance(src, utils.MappingType): attribution(src_property, index).set(value)
def __init__(self, expression_type=None): super(YaqlExpression, self).__init__(False) if expression_type and not utils.is_sequence(expression_type): expression_type = (expression_type,) self._expression_types = expression_type
def get_limited_if_need(data, engine): if (yaqlutils.is_iterable(data) or yaqlutils.is_sequence(data) or isinstance(data, (yaqlutils.MappingType, yaqlutils.SetType))): return yaqlutils.limit_iterable(data, engine) return data
def __init__(self, expression_type=None): super(YaqlExpression, self).__init__(False) if expression_type and not utils.is_sequence(expression_type): expression_type = (expression_type, ) self._expression_types = expression_type
def list_value(v): if v is None: return [] if not yaqlutils.is_sequence(v): v = [v] return v
def setter(src_property, value): src = src_property.get() if utils.is_sequence(src): src_property.set(src[:index] + (value,) + src[index + 1:]) elif isinstance(src, utils.MappingType): attribution(src_property, index).set(value)