Esempio n. 1
0
def yaml_seq_node():
    # A yaml.SequenceNode representing a sequence of mappings
    tag1 = 'tag:yaml.org,2002:map'
    item1_key1_node = yaml.ScalarNode('tag:yaml.org,2002:str', 'item_id')
    item1_value1_node = yaml.ScalarNode('tag:yaml.org,2002:str', 'item1')
    item1_key2_node = yaml.ScalarNode('tag:yaml.org,2002:str', 'price')
    item1_value2_node = yaml.ScalarNode('tag:yaml.org,2002:float', '100.0')
    value1 = [(item1_key1_node, item1_value1_node),
              (item1_key2_node, item1_value2_node)]

    item1 = yaml.MappingNode(tag1, value1)

    tag2 = 'tag:yaml.org,2002:map'
    item2_key1_node = yaml.ScalarNode('tag:yaml.org,2002:str', 'item_id')
    item2_value1_node = yaml.ScalarNode('tag:yaml.org,2002:str', 'item2')
    item2_key2_node = yaml.ScalarNode('tag:yaml.org,2002:str', 'price')
    item2_value2_node = yaml.ScalarNode('tag:yaml.org,2002:float', '200.0')
    item2_key3_node = yaml.ScalarNode('tag:yaml.org,2002:str', 'on_sale')
    item2_value3_node = yaml.ScalarNode('tag:yaml.org,2002:bool', 'True')
    value2 = [(item2_key1_node, item2_value1_node),
              (item2_key2_node, item2_value2_node),
              (item2_key3_node, item2_value3_node)]
    item2 = yaml.MappingNode(tag2, value2)

    return yaml.SequenceNode('tag:yaml.org,2002:seq', [item1, item2])
Esempio n. 2
0
    def get_args_kwargs(cls, loader: yaml.Loader, node: yaml.Node,
                        signature: Signature = free_signature) -> tp.Optional[BoundArguments]:
        if isinstance(node, yaml.ScalarNode):
            try:
                # This sometimes fails because of ruamel/yaml/resolver.py line 370
                node.tag = loader.resolver.resolve(yaml.ScalarNode, node.value, [True, False])
            except IndexError:
                node.tag = loader.DEFAULT_SCALAR_TAG
            val = loader.construct_object(node)
            if val is None:
                val = loader.yaml_constructors[node.tag](loader, node)
            return None if val is None else signature.bind(val)
        elif isinstance(node, yaml.SequenceNode):
            bound = signature.bind(*node.value)
            args = []
            subnodes = node.value
        elif isinstance(node, yaml.MappingNode):
            # Construct the keys
            kwargs = {loader.construct_object(key, deep=True): val for key, val in node.value}

            args = kwargs.setdefault('__args', yaml.SequenceNode('tag:yaml.org,2002:seq', []))
            args_is_seq = isinstance(args, yaml.SequenceNode) and args.tag == 'tag:yaml.org,2002:seq'
            if args_is_seq:
                kwargs['__args'] = args.value

            # Extract nodes in order (nodes are not iterable, so only "flattens" __args)
            subnodes = list(flatten(kwargs.values()))

            __args = kwargs.pop('__args')
            bound = signature.bind_partial(*(__args if args_is_seq else ()), **kwargs)
        else:
            raise ValueError(f'Invalid node type, {node}')

        # Experimental
        cls.fix_signature(bound)

        # Construct nodes in yaml order
        subnode_values = {n: loader.construct_object(n, deep=True)
                          for n in subnodes}

        for key, val in bound.arguments.items():
            bound.arguments[key] = (
                signature.parameters[key].kind == Parameter.VAR_POSITIONAL
                and (subnode_values[n] for n in val)
                or signature.parameters[key].kind == Parameter.VAR_KEYWORD
                and {name: subnode_values[n] for name, n in val.items()}
                or subnode_values[val]
            )

        if args and args in subnode_values:
            return bound.signature.bind(*subnode_values[args], **bound.kwargs)

        return bound
Esempio n. 3
0
    def yatiml_savorize(cls, node: yatiml.Node) -> None:
        text = str(node.get_value())
        parts = text.split('.')
        node.make_mapping()

        # We need to make a yaml.SequenceNode by hand here, since
        # set_attribute doesn't take lists as an argument.
        start_mark = yaml.error.StreamMark('generated node', 0, 0, 0)
        end_mark = yaml.error.StreamMark('generated node', 0, 0, 0)
        item_nodes = list()
        for part in parts[:-1]:
            item_nodes.append(
                yaml.ScalarNode('tag:yaml.org,2002:str', part, start_mark,
                                end_mark))
        ynode = yaml.SequenceNode('tag:yaml.org,2002:seq', item_nodes,
                                  start_mark, end_mark)
        node.set_attribute('namespaces', ynode)
        node.set_attribute('name', parts[-1])
Esempio n. 4
0
 def _yatiml_sweeten(cls, node: yatiml.Node) -> None:
     script_node = node.get_attribute('script')
     if script_node.is_scalar(str):
         text = cast(str, script_node.get_value())
         if '\n' in text:
             # make a sequence of lines
             lines = text.split('\n')
             start_mark = node.yaml_node.start_mark
             end_mark = node.yaml_node.end_mark
             lines_nodes = [
                     yaml.ScalarNode(
                         'tag:yaml.org,2002:str', line, start_mark,
                         end_mark)
                     for line in lines]
             seq_node = yaml.SequenceNode(
                     'tag:yaml.org,2002:seq', lines_nodes, start_mark,
                     end_mark)
             node.set_attribute('script', seq_node)
Esempio n. 5
0
def class_node_dup_key():
    # A Node wrapping a yaml.SequenceNode representing a sequence of
    # mappings with a duplicate key.
    tag1 = 'tag:yaml.org,2002:map'
    item1_key1_node = yaml.ScalarNode('tag:yaml.org,2002:str', 'item_id')
    item1_value1_node = yaml.ScalarNode('tag:yaml.org,2002:str', 'item')
    value1 = [(item1_key1_node, item1_value1_node)]

    item1 = yaml.MappingNode(tag1, value1)

    tag2 = 'tag:yaml.org,2002:map'
    item2_key1_node = yaml.ScalarNode('tag:yaml.org,2002:str', 'item_id')
    item2_value1_node = yaml.ScalarNode('tag:yaml.org,2002:str', 'item')
    value2 = [(item2_key1_node, item2_value1_node)]
    item2 = yaml.MappingNode(tag2, value2)

    seq_node = yaml.SequenceNode('tag:yaml.org,2002:seq', [item1, item2])

    list1_key_node = yaml.ScalarNode('tag:yaml.org,2002:str', 'dup_list')
    value = [(list1_key_node, seq_node)]
    map_node = yaml.MappingNode('tag:yaml.org,2002:map', value)
    return yatiml.Node(map_node)
Esempio n. 6
0
    def map_attribute_to_seq(self,
                             attribute: str,
                             key_attribute: str,
                             value_attribute: Optional[str] = None) -> None:
        """Converts a mapping attribute to a sequence.

        This function takes an attribute of this Node whose value \
        is a mapping or a mapping of mappings and turns it into a \
        sequence of mappings. Each entry in the original mapping is \
        converted to an entry in the list. If only a key attribute is \
        given, then each entry in the original mapping must map to a \
        (sub)mapping. This submapping becomes the corresponding list \
        entry, with the key added to it as an additional attribute. If a \
        value attribute is also given, then an entry in the original \
        mapping may map to any object. If the mapped-to object is a \
        mapping, the conversion is as before, otherwise a new \
        submapping is created, and key and value are added using the \
        given key and value attribute names.

        An example probably helps. If you have a Node representing \
        this piece of YAML::

            items:
              item1:
                description: Basic widget
                price: 100.0
              item2:
                description: Premium quality widget
                price: 200.0

        and call map_attribute_to_seq('items', 'item_id'), then the \
        Node will be modified to represent this::

            items:
            - item_id: item1
              description: Basic widget
              price: 100.0
            - item_id: item2
              description: Premium quality widget
              price: 200.0

        which once converted to an object is often easier to deal with \
        in code.

        Slightly more complicated, this YAML::

            items:
              item1: Basic widget
              item2:
                description: Premium quality widget
                price: 200.0

        when passed through map_attribute_to_seq('items', 'item_id', \
        'description'), will result in th equivalent of::

            items:
            - item_id: item1
              description: Basic widget
            - item_id: item2
              description: Premium quality widget
              price: 200.0

        If the attribute does not exist, or is not a mapping, this \
        function will silently do nothing.

        With thanks to the makers of the Common Workflow Language for \
        the idea.

        Args:
            attribute: Name of the attribute whose value to modify.
            key_attribute: Name of the new attribute in each item to \
                    add with the value of the key.
            value_attribute: Name of the new attribute in each item to \
                    add with the value of the key.
        """
        if not self.has_attribute(attribute):
            return

        attr_node = self.get_attribute(attribute)
        if not attr_node.is_mapping():
            return

        start_mark = attr_node.yaml_node.start_mark
        end_mark = attr_node.yaml_node.end_mark
        object_list = []
        for item_key, item_value in attr_node.yaml_node.value:
            item_value_node = Node(item_value)
            if not item_value_node.is_mapping():
                if value_attribute is None:
                    return
                ynode = item_value_node.yaml_node
                item_value_node.make_mapping()
                item_value_node.set_attribute(value_attribute, ynode)

            item_value_node.set_attribute(key_attribute, item_key.value)
            object_list.append(item_value_node.yaml_node)
        seq_node = yaml.SequenceNode('tag:yaml.org,2002:seq', object_list,
                                     start_mark, end_mark)
        self.set_attribute(attribute, seq_node)
Esempio n. 7
0
def unknown_sequence_node():
    ynode = yaml.SequenceNode('tag:yaml.org,2002:seq', [])
    return yatiml.UnknownNode(Recognizer({}), ynode)
Esempio n. 8
0
def unknown_sequence_node(recognizer: Recognizer) -> yatiml.UnknownNode:
    ynode = yaml.SequenceNode('tag:yaml.org,2002:seq', [])
    return yatiml.UnknownNode(recognizer, ynode)