2 __all__
= ['Composer', 'ComposerError']
4 from error
import MarkedYAMLError
8 class ComposerError(MarkedYAMLError
):
11 class Composer(object):
17 # If there are more documents available?
18 return not self
.check_event(StreamEndEvent
)
21 # Get the root node of the next document.
22 if not self
.check_event(StreamEndEvent
):
23 return self
.compose_document()
25 def compose_document(self
):
27 # Drop the STREAM-START event.
28 if self
.check_event(StreamStartEvent
):
31 # Drop the DOCUMENT-START event.
34 # Compose the root node.
35 node
= self
.compose_node(None, None)
37 # Drop the DOCUMENT-END event.
43 def compose_node(self
, parent
, index
):
44 if self
.check_event(AliasEvent
):
45 event
= self
.get_event()
47 if anchor
not in self
.anchors
:
48 raise ComposerError(None, None, "found undefined alias %r"
49 % anchor
.encode('utf-8'), event
.start_mark
)
50 return self
.anchors
[anchor
]
51 event
= self
.peek_event()
53 if anchor
is not None:
54 if anchor
in self
.anchors
:
55 raise ComposerError("found duplicate anchor %r; first occurence"
56 % anchor
.encode('utf-8'), self
.anchors
[anchor
].start_mark
,
57 "second occurence", event
.start_mark
)
58 self
.descend_resolver(parent
, index
)
59 if self
.check_event(ScalarEvent
):
60 node
= self
.compose_scalar_node(anchor
)
61 elif self
.check_event(SequenceStartEvent
):
62 node
= self
.compose_sequence_node(anchor
)
63 elif self
.check_event(MappingStartEvent
):
64 node
= self
.compose_mapping_node(anchor
)
65 self
.ascend_resolver()
68 def compose_scalar_node(self
, anchor
):
69 event
= self
.get_event()
71 if tag
is None or tag
== u
'!':
72 tag
= self
.resolve(ScalarNode
, event
.value
, event
.implicit
)
73 node
= ScalarNode(tag
, event
.value
,
74 event
.start_mark
, event
.end_mark
, style
=event
.style
)
75 if anchor
is not None:
76 self
.anchors
[anchor
] = node
79 def compose_sequence_node(self
, anchor
):
80 start_event
= self
.get_event()
82 if tag
is None or tag
== u
'!':
83 tag
= self
.resolve(SequenceNode
, None, start_event
.implicit
)
84 node
= SequenceNode(tag
, [],
85 start_event
.start_mark
, None,
86 flow_style
=start_event
.flow_style
)
87 if anchor
is not None:
88 self
.anchors
[anchor
] = node
90 while not self
.check_event(SequenceEndEvent
):
91 node
.value
.append(self
.compose_node(node
, index
))
93 end_event
= self
.get_event()
94 node
.end_mark
= end_event
.end_mark
97 def compose_mapping_node(self
, anchor
):
98 start_event
= self
.get_event()
100 if tag
is None or tag
== u
'!':
101 tag
= self
.resolve(MappingNode
, None, start_event
.implicit
)
102 node
= MappingNode(tag
, [],
103 start_event
.start_mark
, None,
104 flow_style
=start_event
.flow_style
)
105 if anchor
is not None:
106 self
.anchors
[anchor
] = node
107 while not self
.check_event(MappingEndEvent
):
108 #key_event = self.peek_event()
109 item_key
= self
.compose_node(node
, None)
110 #if item_key in node.value:
111 # raise ComposerError("while composing a mapping", start_event.start_mark,
112 # "found duplicate key", key_event.start_mark)
113 item_value
= self
.compose_node(node
, item_key
)
114 #node.value[item_key] = item_value
115 node
.value
.append((item_key
, item_value
))
116 end_event
= self
.get_event()
117 node
.end_mark
= end_event
.end_mark