Example #1
0
def multi_constructor(loader, tag_suffix, node):
    """
    Deal with !Ref style function format
    """

    if tag_suffix not in UNCONVERTED_SUFFIXES:
        tag_suffix = '{}{}'.format(FN_PREFIX, tag_suffix)

    constructor = None
    if tag_suffix == 'Fn::GetAtt':
        constructor = construct_getatt
    elif isinstance(node, ScalarNode):
        constructor = loader.construct_scalar
    elif isinstance(node, SequenceNode):
        constructor = loader.construct_sequence
    elif isinstance(node, MappingNode):
        constructor = loader.construct_mapping
    else:
        raise 'Bad tag: !{}'.format(tag_suffix)

    if tag_suffix == 'Fn::Sub':
        return sub_node({tag_suffix: constructor(node)}, node.start_mark,
                        node.end_mark)

    return dict_node({tag_suffix: constructor(node)}, node.start_mark,
                     node.end_mark)
Example #2
0
    def construct_yaml_map(self, node):

        # Check for duplicate keys on the current level, this is not desirable
        # because a dict does not support this. It overwrites it with the last
        # occurance, which can give unexpected results
        mapping = {}
        self.flatten_mapping(node)
        for key_node, value_node in node.value:
            key = self.construct_object(key_node, False)
            value = self.construct_object(value_node, False)

            for key_dup in mapping:
                if key_dup == key:
                    raise CfnParseError(self.filename, [
                        build_match(
                            filename=self.filename,
                            message='Duplicate resource found "{}" (line {})'.
                            format(key, key_dup.start_mark.line + 1),
                            line_number=key_dup.start_mark.line,
                            column_number=key_dup.start_mark.column,
                            key=key),
                        build_match(
                            filename=self.filename,
                            message='Duplicate resource found "{}" (line {})'.
                            format(key, key_node.start_mark.line + 1),
                            line_number=key_node.start_mark.line,
                            column_number=key_node.start_mark.column,
                            key=key),
                    ])
            try:
                mapping[key] = value
            except:
                raise CfnParseError(self.filename, [
                    build_match(
                        filename=self.filename,
                        message=
                        f'Unhashable type "{key}" (line {key.start_mark.line + 1})',
                        line_number=key.start_mark.line,
                        column_number=key.start_mark.column,
                        key=key),
                ])

        obj, = SafeConstructor.construct_yaml_map(self, node)

        if len(mapping) == 1:
            if 'Fn::Sub' in mapping:
                return sub_node(obj, node.start_mark, node.end_mark)

        return dict_node(obj, node.start_mark, node.end_mark)
Example #3
0
def check_duplicates(ordered_pairs, beg_mark, end_mark):
    """
        Check for duplicate keys on the current level, this is not desirable
        because a dict does not support this. It overwrites it with the last
        occurrence, which can give unexpected results
    """
    mapping = dict_node({}, beg_mark, end_mark)
    for key, value in ordered_pairs:
        if value is None:
            raise NullError('"{}"'.format(key))
        if key in mapping:
            raise DuplicateError('"{}"'.format(key), mapping, key)
        mapping[key] = value

    if len(mapping) == 1:
        if 'Fn::Sub' in mapping:
            return sub_node(ordered_pairs, beg_mark, end_mark)
    return mapping