2 __all__
= ['Composer', 'ComposerError']
4 from error
import MarkedYAMLError
8 class ComposerError(MarkedYAMLError
):
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()
27 while not self
.check_event(StreamEndEvent
):
28 yield self
.compose_document()
30 def compose_document(self
):
32 # Drop the STREAM-START event.
33 if self
.check_event(StreamStartEvent
):
36 # Drop the DOCUMENT-START event.
39 # Compose the root node.
40 node
= self
.compose_node(None, None)
42 # Drop the DOCUMENT-END event.
45 self
.complete_anchors
= {}
48 def compose_node(self
, parent
, index
):
49 if self
.check_event(AliasEvent
):
50 event
= self
.get_event()
52 if anchor
not in self
.anchors
:
53 raise ComposerError(None, None, "found undefined alias %r"
54 % anchor
.encode('utf-8'), event
.start_mark
)
55 return self
.anchors
[anchor
]
56 event
= self
.peek_event()
58 if anchor
is not None:
59 if anchor
in self
.anchors
:
60 raise ComposerError("found duplicate anchor %r; first occurence"
61 % anchor
.encode('utf-8'), self
.anchors
[anchor
].start_mark
,
62 "second occurence", event
.start_mark
)
63 self
.descend_resolver(parent
, index
)
64 if self
.check_event(ScalarEvent
):
65 node
= self
.compose_scalar_node(anchor
)
66 elif self
.check_event(SequenceStartEvent
):
67 node
= self
.compose_sequence_node(anchor
)
68 elif self
.check_event(MappingStartEvent
):
69 node
= self
.compose_mapping_node(anchor
)
70 self
.ascend_resolver()
73 def compose_scalar_node(self
, anchor
):
74 event
= self
.get_event()
76 if tag
is None or tag
== u
'!':
77 tag
= self
.resolve(ScalarNode
, event
.value
, event
.implicit
)
78 node
= ScalarNode(tag
, event
.value
,
79 event
.start_mark
, event
.end_mark
, style
=event
.style
)
80 if anchor
is not None:
81 self
.anchors
[anchor
] = node
84 def compose_sequence_node(self
, anchor
):
85 start_event
= self
.get_event()
87 if tag
is None or tag
== u
'!':
88 tag
= self
.resolve(SequenceNode
, None, start_event
.implicit
)
89 node
= SequenceNode(tag
, [],
90 start_event
.start_mark
, None,
91 flow_style
=start_event
.flow_style
)
92 if anchor
is not None:
93 self
.anchors
[anchor
] = node
95 while not self
.check_event(SequenceEndEvent
):
96 node
.value
.append(self
.compose_node(node
, index
))
98 end_event
= self
.get_event()
99 node
.end_mark
= end_event
.end_mark
102 def compose_mapping_node(self
, anchor
):
103 start_event
= self
.get_event()
104 tag
= start_event
.tag
105 if tag
is None or tag
== u
'!':
106 tag
= self
.resolve(MappingNode
, None, start_event
.implicit
)
107 node
= MappingNode(tag
, {},
108 start_event
.start_mark
, None,
109 flow_style
=start_event
.flow_style
)
110 if anchor
is not None:
111 self
.anchors
[anchor
] = node
112 while not self
.check_event(MappingEndEvent
):
113 key_event
= self
.peek_event()
114 item_key
= self
.compose_node(node
, None)
115 if item_key
in node
.value
:
116 raise ComposerError("while composing a mapping", start_event
.start_mark
,
117 "found duplicate key", key_event
.start_mark
)
118 item_value
= self
.compose_node(node
, item_key
)
119 node
.value
[item_key
] = item_value
120 end_event
= self
.get_event()
121 node
.end_mark
= end_event
.end_mark