2 __all__
= ['Composer', 'ComposerError']
4 from error
import MarkedYAMLError
8 class ComposerError(MarkedYAMLError
):
15 self
.complete_anchors
= {}
18 # If there are more documents available?
19 return not self
.check_event(StreamEndEvent
)
22 # Get the root node of the next document.
23 if not self
.check_event(StreamEndEvent
):
24 return self
.compose_document()
28 while not self
.check_event(StreamEndEvent
):
29 yield self
.compose_document()
31 def compose_document(self
):
33 # Drop the STREAM-START event.
34 if self
.check_event(StreamStartEvent
):
37 # Drop the DOCUMENT-START event.
40 # Compose the root node.
41 node
= self
.compose_node(None, None)
43 # Drop the DOCUMENT-END event.
47 self
.complete_anchors
= {}
50 def compose_node(self
, parent
, index
):
51 if self
.check_event(AliasEvent
):
52 event
= self
.get_event()
54 if anchor
not in self
.all_anchors
:
55 raise ComposerError(None, None, "found undefined alias %r"
56 % anchor
.encode('utf-8'), event
.start_mark
)
57 if anchor
not in self
.complete_anchors
:
58 collection_event
= self
.all_anchors
[anchor
]
59 raise ComposerError("while composing a collection",
60 collection_event
.start_mark
,
61 "found recursive anchor %r" % anchor
.encode('utf-8'),
63 return self
.complete_anchors
[anchor
]
64 event
= self
.peek_event()
66 if anchor
is not None:
67 if anchor
in self
.all_anchors
:
68 raise ComposerError("found duplicate anchor %r; first occurence"
69 % anchor
.encode('utf-8'), self
.all_anchors
[anchor
].start_mark
,
70 "second occurence", event
.start_mark
)
71 self
.all_anchors
[anchor
] = event
72 self
.descend_resolver(parent
, index
)
73 if self
.check_event(ScalarEvent
):
74 node
= self
.compose_scalar_node()
75 elif self
.check_event(SequenceStartEvent
):
76 node
= self
.compose_sequence_node()
77 elif self
.check_event(MappingStartEvent
):
78 node
= self
.compose_mapping_node()
79 if anchor
is not None:
80 self
.complete_anchors
[anchor
] = node
81 self
.ascend_resolver()
84 def compose_scalar_node(self
):
85 event
= self
.get_event()
87 if tag
is None or tag
== u
'!':
88 tag
= self
.resolve(ScalarNode
, event
.value
, event
.implicit
)
89 return ScalarNode(tag
, event
.value
,
90 event
.start_mark
, event
.end_mark
, style
=event
.style
)
92 def compose_sequence_node(self
):
93 start_event
= self
.get_event()
95 if tag
is None or tag
== u
'!':
96 tag
= self
.resolve(SequenceNode
, None, start_event
.implicit
)
97 node
= SequenceNode(tag
, [],
98 start_event
.start_mark
, None,
99 flow_style
=start_event
.flow_style
)
101 while not self
.check_event(SequenceEndEvent
):
102 node
.value
.append(self
.compose_node(node
, index
))
104 end_event
= self
.get_event()
105 node
.end_mark
= end_event
.end_mark
108 def compose_mapping_node(self
):
109 start_event
= self
.get_event()
110 tag
= start_event
.tag
111 if tag
is None or tag
== u
'!':
112 tag
= self
.resolve(MappingNode
, None, start_event
.implicit
)
113 node
= MappingNode(tag
, {},
114 start_event
.start_mark
, None,
115 flow_style
=start_event
.flow_style
)
116 while not self
.check_event(MappingEndEvent
):
117 key_event
= self
.peek_event()
118 item_key
= self
.compose_node(node
, None)
119 if item_key
in node
.value
:
120 raise ComposerError("while composing a mapping", start_event
.start_mark
,
121 "found duplicate key", key_event
.start_mark
)
122 item_value
= self
.compose_node(node
, item_key
)
123 node
.value
[item_key
] = item_value
124 end_event
= self
.get_event()
125 node
.end_mark
= end_event
.end_mark