source: pyyaml/trunk/lib3/yaml/composer.py @ 328

Revision 328, 4.8 KB checked in by xi, 6 years ago (diff)

Added basic support for Python 3 (Thanks idadesub(at)users(dot)sourceforge(dot)net).

RevLine 
[53]1
[137]2__all__ = ['Composer', 'ComposerError']
[57]3
[328]4from .error import MarkedYAMLError
5from .events import *
6from .nodes import *
[53]7
8class ComposerError(MarkedYAMLError):
9    pass
10
[328]11class Composer:
[53]12
[136]13    def __init__(self):
[142]14        self.anchors = {}
[53]15
[136]16    def check_node(self):
[233]17        # Drop the STREAM-START event.
18        if self.check_event(StreamStartEvent):
19            self.get_event()
20
[53]21        # If there are more documents available?
[136]22        return not self.check_event(StreamEndEvent)
[53]23
[136]24    def get_node(self):
[53]25        # Get the root node of the next document.
[136]26        if not self.check_event(StreamEndEvent):
[53]27            return self.compose_document()
28
[258]29    def get_single_node(self):
30        # Drop the STREAM-START event.
31        self.get_event()
32
33        # Compose a document if the stream is not empty.
34        document = None
35        if not self.check_event(StreamEndEvent):
36            document = self.compose_document()
37
38        # Ensure that the stream contains no more documents.
39        if not self.check_event(StreamEndEvent):
40            event = self.get_event()
41            raise ComposerError("expected a single document in the stream",
42                    document.start_mark, "but found another document",
43                    event.start_mark)
44
45        # Drop the STREAM-END event.
46        self.get_event()
47
48        return document
49
[53]50    def compose_document(self):
[118]51        # Drop the DOCUMENT-START event.
[136]52        self.get_event()
[118]53
54        # Compose the root node.
[137]55        node = self.compose_node(None, None)
[118]56
57        # Drop the DOCUMENT-END event.
[136]58        self.get_event()
[118]59
[223]60        self.anchors = {}
[53]61        return node
62
[137]63    def compose_node(self, parent, index):
[136]64        if self.check_event(AliasEvent):
65            event = self.get_event()
[53]66            anchor = event.anchor
[142]67            if anchor not in self.anchors:
[53]68                raise ComposerError(None, None, "found undefined alias %r"
[328]69                        % anchor, event.start_mark)
[142]70            return self.anchors[anchor]
[136]71        event = self.peek_event()
[53]72        anchor = event.anchor
73        if anchor is not None:
[142]74            if anchor in self.anchors:
[53]75                raise ComposerError("found duplicate anchor %r; first occurence"
[328]76                        % anchor, self.anchors[anchor].start_mark,
[116]77                        "second occurence", event.start_mark)
[137]78        self.descend_resolver(parent, index)
[136]79        if self.check_event(ScalarEvent):
[142]80            node = self.compose_scalar_node(anchor)
[136]81        elif self.check_event(SequenceStartEvent):
[142]82            node = self.compose_sequence_node(anchor)
[136]83        elif self.check_event(MappingStartEvent):
[142]84            node = self.compose_mapping_node(anchor)
[137]85        self.ascend_resolver()
[53]86        return node
87
[142]88    def compose_scalar_node(self, anchor):
[136]89        event = self.get_event()
[137]90        tag = event.tag
[328]91        if tag is None or tag == '!':
[137]92            tag = self.resolve(ScalarNode, event.value, event.implicit)
[142]93        node = ScalarNode(tag, event.value,
[133]94                event.start_mark, event.end_mark, style=event.style)
[142]95        if anchor is not None:
96            self.anchors[anchor] = node
97        return node
[53]98
[142]99    def compose_sequence_node(self, anchor):
[136]100        start_event = self.get_event()
[137]101        tag = start_event.tag
[328]102        if tag is None or tag == '!':
[137]103            tag = self.resolve(SequenceNode, None, start_event.implicit)
[136]104        node = SequenceNode(tag, [],
105                start_event.start_mark, None,
[133]106                flow_style=start_event.flow_style)
[142]107        if anchor is not None:
108            self.anchors[anchor] = node
[136]109        index = 0
110        while not self.check_event(SequenceEndEvent):
[137]111            node.value.append(self.compose_node(node, index))
[136]112            index += 1
113        end_event = self.get_event()
114        node.end_mark = end_event.end_mark
115        return node
[53]116
[142]117    def compose_mapping_node(self, anchor):
[136]118        start_event = self.get_event()
[137]119        tag = start_event.tag
[328]120        if tag is None or tag == '!':
[137]121            tag = self.resolve(MappingNode, None, start_event.implicit)
[222]122        node = MappingNode(tag, [],
[136]123                start_event.start_mark, None,
124                flow_style=start_event.flow_style)
[142]125        if anchor is not None:
126            self.anchors[anchor] = node
[136]127        while not self.check_event(MappingEndEvent):
[222]128            #key_event = self.peek_event()
[137]129            item_key = self.compose_node(node, None)
[222]130            #if item_key in node.value:
131            #    raise ComposerError("while composing a mapping", start_event.start_mark,
132            #            "found duplicate key", key_event.start_mark)
[137]133            item_value = self.compose_node(node, item_key)
[222]134            #node.value[item_key] = item_value
135            node.value.append((item_key, item_value))
[136]136        end_event = self.get_event()
137        node.end_mark = end_event.end_mark
138        return node
[53]139
Note: See TracBrowser for help on using the repository browser.