Пример #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])
Пример #2
0
def yaml_map_node():
    # A yaml.MappingNode representing a mapping of mappings
    tag1 = 'tag:yaml.org,2002:map'
    item1_key1_node = yaml.ScalarNode('tag:yaml.org,2002:str', 'price')
    item1_value1_node = yaml.ScalarNode('tag:yaml.org,2002:float', '100.0')
    value1 = [(item1_key1_node, item1_value1_node)]

    item1 = yaml.MappingNode(tag1, value1)
    key1 = yaml.ScalarNode('tag:yaml.org,2002:str', 'item1')

    tag2 = 'tag:yaml.org,2002:map'
    item2_key1_node = yaml.ScalarNode('tag:yaml.org,2002:str', 'price')
    item2_value1_node = yaml.ScalarNode('tag:yaml.org,2002:float', '200.0')
    value2 = [(item2_key1_node, item2_value1_node)]

    item2 = yaml.MappingNode(tag2, value2)
    key2 = yaml.ScalarNode('tag:yaml.org,2002:str', 'item2')

    item3 = yaml.ScalarNode('tag:yaml.org,2002:float', '150.0')
    key3 = yaml.ScalarNode('tag:yaml.org,2002:str', 'item3')

    outer_map_value = [(key1, item1), (key2, item2), (key3, item3)]
    outer_tag = 'tag:yaml.org,2002:map'
    outer_map = yaml.MappingNode(outer_tag, outer_map_value)

    return outer_map
Пример #3
0
    def __call__(self, dumper: 'Dumper', data: Any) -> yaml.Node:
        """Represents the class as a ScalarNode.

        Args:
            dumper: The dumper to use.
            data: The user-defined object to dump.

        Returns:
            A yaml.Node representing the object.
        """
        # make a ScalarNode of type str with name of value
        logger.info('Representing {} of class {}'.format(
            data, self.class_.__name__))

        # convert to a yaml.ScalarNode
        start_mark = yaml.error.StreamMark('Generated node', 0, 0, 0)
        end_mark = start_mark
        represented = yaml.ScalarNode('tag:yaml.org,2002:str', data.name,
                                      start_mark, end_mark)  # type: yaml.Node

        # sweeten
        snode = Node(represented)
        if hasattr(self.class_, '_yatiml_sweeten'):
            self.class_._yatiml_sweeten(snode)
            represented = snode.yaml_node

        logger.debug('End representing {}'.format(data))
        return represented
Пример #4
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)
Пример #5
0
def test_set_attribute(class_node: yatiml.Node) -> None:
    assert class_node.get_attribute('attr1').get_value() == 42

    class_node.set_attribute('attr1', 43)
    attr1 = class_node.get_attribute('attr1')
    assert attr1.yaml_node.tag == 'tag:yaml.org,2002:int'
    assert attr1.yaml_node.value == '43'
    assert attr1.yaml_node.start_mark is not None
    assert attr1.yaml_node.end_mark is not None

    class_node.set_attribute('attr1', 'test')
    attr1 = class_node.get_attribute('attr1')
    assert attr1.yaml_node.tag == 'tag:yaml.org,2002:str'
    assert attr1.yaml_node.value == 'test'
    assert attr1.yaml_node.start_mark is not None
    assert attr1.yaml_node.end_mark is not None

    class_node.set_attribute('attr1', 3.14)
    attr1 = class_node.get_attribute('attr1')
    assert attr1.yaml_node.tag == 'tag:yaml.org,2002:float'
    assert attr1.yaml_node.value == '3.14'
    assert attr1.yaml_node.start_mark is not None
    assert attr1.yaml_node.end_mark is not None

    class_node.set_attribute('attr1', True)
    attr1 = class_node.get_attribute('attr1')
    assert attr1.yaml_node.tag == 'tag:yaml.org,2002:bool'
    assert attr1.yaml_node.value == 'true'
    assert attr1.yaml_node.start_mark is not None
    assert attr1.yaml_node.end_mark is not None

    class_node.set_attribute('attr1', None)
    attr1 = class_node.get_attribute('attr1')
    assert attr1.yaml_node.tag == 'tag:yaml.org,2002:null'
    assert attr1.yaml_node.value == ''
    assert attr1.yaml_node.start_mark is not None
    assert attr1.yaml_node.end_mark is not None

    assert not class_node.has_attribute('attr2')
    class_node.set_attribute('attr2', 'testing')
    attr2 = class_node.get_attribute('attr2')
    assert attr2.yaml_node.value == 'testing'
    assert attr2.yaml_node.start_mark is not None
    assert attr2.yaml_node.end_mark is not None

    node = yaml.ScalarNode('tag:yaml.org,2002:str', 'testnode')
    class_node.set_attribute('attr3', node)
    assert class_node.get_attribute('attr3').yaml_node == node

    with pytest.raises(TypeError):
        class_node.set_attribute('attr4', class_node)  # type: ignore
Пример #6
0
def yaml_node(yaml_seq_node, yaml_map_node):
    tag = 'tag:yaml.org,2002:map'

    attr1_key_node = yaml.ScalarNode('tag:yaml.org,2002:str', 'attr1')
    attr1_value_node = yaml.ScalarNode('tag:yaml.org,2002:int', '42')

    null_attr_key_node = yaml.ScalarNode('tag:yaml.org,2002:str', 'null_attr')
    null_attr_value_node = yaml.ScalarNode('tag:yaml.org,2002:null', '')

    list1_key_node = yaml.ScalarNode('tag:yaml.org,2002:str', 'list1')
    dict1_key_node = yaml.ScalarNode('tag:yaml.org,2002:map', 'dict1')

    dashed_key_node = yaml.ScalarNode('tag:yaml.org,2002:str', 'dashed-attr')
    dashed_value_node = yaml.ScalarNode('tag:yaml.org,2002:int', '13')

    undered_key_node = yaml.ScalarNode('tag:yaml.org,2002:str', 'undered_attr')
    undered_value_node = yaml.ScalarNode('tag:yaml.org,2002:float', '13.0')

    value = [(attr1_key_node, attr1_value_node),
             (null_attr_key_node, null_attr_value_node),
             (list1_key_node, yaml_seq_node), (dict1_key_node, yaml_map_node),
             (dashed_key_node, dashed_value_node),
             (undered_key_node, undered_value_node)]
    return yaml.MappingNode(tag, value)
Пример #7
0
    def set_attribute(self, attribute: str, value: Union[ScalarType,
                                                         yaml.Node]) -> None:
        """Sets the attribute to the given value.

        Use only if :meth:`is_mapping` returns ``True``.

        If the attribute does not exist, this adds a new attribute,
        if it does, it will be overwritten.

        If value is a ``str``, ``int``, ``float``, ``bool`` or ``None``,
        the attribute will be set to this value. If you want to set the
        value to a list or dict containing other values, build a
        yaml.Node and pass it here.

        Args:
            attribute: Name of the attribute whose value to change.
            value: The value to set.
        """
        start_mark = StreamMark('generated node', 0, 0, 0)
        end_mark = StreamMark('generated node', 0, 0, 0)
        if isinstance(value, str):
            value_node = yaml.ScalarNode('tag:yaml.org,2002:str', value,
                                         start_mark,
                                         end_mark)  # type: yaml.Node
        elif isinstance(value, bool):
            value_str = 'true' if value else 'false'
            value_node = yaml.ScalarNode('tag:yaml.org,2002:bool', value_str,
                                         start_mark, end_mark)
        elif isinstance(value, int):
            value_node = yaml.ScalarNode('tag:yaml.org,2002:int', str(value),
                                         start_mark, end_mark)
        elif isinstance(value, float):
            value_node = yaml.ScalarNode('tag:yaml.org,2002:float', str(value),
                                         start_mark, end_mark)
        elif value is None:
            value_node = yaml.ScalarNode('tag:yaml.org,2002:null', '',
                                         start_mark, end_mark)
        elif isinstance(value, yaml.Node):
            value_node = value
        else:
            raise TypeError('Invalid kind of value passed to set_attribute()')

        attr_index = self.__attr_index(attribute)
        if attr_index is not None:
            key_node = self.yaml_node.value[attr_index][0]
            self.yaml_node.value[attr_index] = key_node, value_node
        else:
            key_node = yaml.ScalarNode('tag:yaml.org,2002:str', attribute,
                                       start_mark, end_mark)
            self.yaml_node.value.append((key_node, value_node))
            if isinstance(self.yaml_node, yaml.MappingNode):
                self.yaml_node.flow_style = False
Пример #8
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])
Пример #9
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)
Пример #10
0
    def set_value(self, value: ScalarType) -> None:
        """Sets the value of the node to a scalar value.

        After this, is_scalar(type(value)) will return true.

        Args:
            value: The value to set this node to, a str, int, float, \
                    bool, or None.
        """
        if isinstance(value, bool):
            value_str = 'true' if value else 'false'
        else:
            value_str = str(value)
        start_mark = self.yaml_node.start_mark
        end_mark = self.yaml_node.end_mark
        # If we're of a class type, then we want to keep that tag so that the
        # correct Constructor is called. If we're a built-in type, set the tag
        # to the appropriate YAML tag.
        tag = self.yaml_node.tag
        if tag.startswith('tag:yaml.org,2002:'):
            tag = scalar_type_to_tag[type(value)]
        new_node = yaml.ScalarNode(tag, value_str, start_mark, end_mark)
        self.yaml_node = new_node
Пример #11
0
    def map_attribute_to_index(self,
                               attribute: str,
                               key_attribute: str,
                               value_attribute: Optional[str] = None) -> None:
        """Converts a mapping attribute to an index .

        It is often convenient to represent a collection of objects by
        a dict mapping a name of each object to that object (let's call
        that an *index*). If each object knows its own name, then the
        name is stored twice, which is not nice to have to type and
        keep synchronised in YAML.

        In YAML, such an index is a mapping of mappings, where the key
        of the outer mapping matches the value of one of the items in
        the corresponding inner mapping.

        This function enables a short-hand notation for the above,
        where the name of the object is mentioned only in the key of
        the mapping and not again in the values, and, if
        ``value_attribute`` is specified, converting any entries with
        a scalar value (rather than a mapping) to a mapping with
        ''value_attribute'' as the key and the original value as the
        value.

        An example probably helps. Let's say we have a class
        ``Employee`` and a ``Company`` which has employees:

        .. code-block:: python

          class Employee:
              def __init__(
                      self, name: str, role: str, hours: int = 40
                      ) -> None:
                  ...

          class Company:
              def __init__(
                      self, employees: Dict[str, Employee]
                      ) -> None:
                  ...

          my_company = Company({
              'Mary': Employee('Mary', 'Director'),
              'Vishnu': Employee('Vishnu', 'Sales'),
              'Susan': Employee('Susan', 'Engineering')})

        By default, to load this from YAML, you have to write:

        .. code-block:: yaml

          employees:
            Mary:
              name: Mary
              role: Director
            Vishnu:
              name: Vishnu
              role: Sales
            Susan:
              name: Susan
              role: Engineering

        If you call
        ``node.map_attribute_to_index('employees', 'name')`` in
        ``Company._yatiml_savorize()``, then the following will also
        work:

        .. code-block:: yaml

          employees:
            Mary:
              role: Director
            Vishnu:
              role: Sales
            Susan:
              role: Engineering

        And if you call
        ``node.map_attribute_to_index('employees', 'name', 'role')``
        then you can also write:

        .. code-block:: yaml

          employees:
            Mary: Director
            Vishnu: Sales
            Susan: Engineering

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

        See :meth:`index_attribute_to_map` for the reverse.

        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 attribute in each item to
                    add, with the value of the key.
            value_attribute: Name of the attribute in each item to use
                    for the value in the new mapping, if only a key and
                    value have been given.
        """
        if not self.has_attribute(attribute):
            return

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

        new_value = list()
        for key_node, value_node in attr_node.yaml_node.value:
            if not isinstance(value_node, yaml.MappingNode):
                if value_attribute is not None:
                    new_key = yaml.ScalarNode('tag:yaml.org,2002:str',
                                              value_attribute,
                                              value_node.start_mark,
                                              value_node.end_mark)
                    new_mapping = yaml.MappingNode('tag:yaml.org,2002:map',
                                                   [(new_key, value_node)],
                                                   value_node.start_mark,
                                                   value_node.end_mark)
            else:
                new_mapping = value_node

            if isinstance(new_mapping, yaml.MappingNode):
                key_key = yaml.ScalarNode('tag:yaml.org,2002:str',
                                          key_attribute, key_node.start_mark,
                                          key_node.end_mark)
                new_mapping.value.append((key_key, copy(key_node)))

            new_value.append((key_node, new_mapping))

        attr_node.yaml_node.value = new_value
Пример #12
0
def unknown_scalar_node():
    ynode = yaml.ScalarNode('tag:yaml.org,2002:int', '23')
    return yatiml.UnknownNode(Recognizer({}), ynode)
Пример #13
0
def scalar_node():
    ynode = yaml.ScalarNode('tag:yaml.org,2002:int', '42')
    return yatiml.Node(ynode)
Пример #14
0
 def get_single_node(self):
     return yaml.ScalarNode(tag='tag:yaml.org,2002:str',
                            value=self.stream.read())
Пример #15
0
def unknown_scalar_node(recognizer: Recognizer) -> yatiml.UnknownNode:
    ynode = yaml.ScalarNode('tag:yaml.org,2002:int', '23')
    return yatiml.UnknownNode(recognizer, ynode)
Пример #16
0
def yaml_index_node() -> yaml.Node:
    # A yaml.MappingNode representing a mapping of mappings indexed
    # by item id
    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)
    key1 = yaml.ScalarNode('tag:yaml.org,2002:str', 'item1')

    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')
    value2 = [(item2_key1_node, item2_value1_node),
              (item2_key2_node, item2_value2_node)]

    item2 = yaml.MappingNode(tag2, value2)
    key2 = yaml.ScalarNode('tag:yaml.org,2002:str', 'item2')

    tag3 = 'tag:yaml.org,2002:map'
    item3_key1_node = yaml.ScalarNode('tag:yaml.org,2002:str', 'item_id')
    item3_value1_node = yaml.ScalarNode('tag:yaml.org,2002:str', 'item3')
    item3_key2_node = yaml.ScalarNode('tag:yaml.org,2002:str', 'price')
    item3_value2_node = yaml.ScalarNode('tag:yaml.org,2002:float', '150.0')
    item3_key3_node = yaml.ScalarNode('tag:yaml.org,2002:str', 'on_sale')
    item3_value3_node = yaml.ScalarNode('tag:yaml.org,2002:bool', 'true')
    value3 = [(item3_key1_node, item3_value1_node),
              (item3_key2_node, item3_value2_node),
              (item3_key3_node, item3_value3_node)]

    item3 = yaml.MappingNode(tag3, value3)
    key3 = yaml.ScalarNode('tag:yaml.org,2002:str', 'item3')

    outer_map_value = [(key1, item1), (key2, item2), (key3, item3)]
    outer_tag = 'tag:yaml.org,2002:map'
    outer_map = yaml.MappingNode(outer_tag, outer_map_value)

    return outer_map