2 __all__
= ['Composer', 'ComposerError']
4 from error
import MarkedYAMLError
8 class ComposerError(MarkedYAMLError
):
13 def __init__(self
, parser
):
16 self
.complete_anchors
= {}
18 # Drop the STREAM-START event.
22 # If there are more documents available?
23 return not self
.parser
.check(StreamEndEvent
)
26 # Get the root node of the next document.
27 if not self
.parser
.check(StreamEndEvent
):
28 return self
.compose_document()
32 while not self
.parser
.check(StreamEndEvent
):
33 yield self
.compose_document()
35 def compose_document(self
):
37 # Drop the DOCUMENT-START event.
40 # Compose the root node.
41 node
= self
.compose_node()
43 # Drop the DOCUMENT-END event.
47 self
.complete_anchors
= {}
50 def compose_node(self
):
51 if self
.parser
.check(AliasEvent
):
52 event
= self
.parser
.get()
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
.parser
.peek()
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 if self
.parser
.check(ScalarEvent
):
73 node
= self
.compose_scalar_node()
74 elif self
.parser
.check(SequenceStartEvent
):
75 node
= self
.compose_sequence_node()
76 elif self
.parser
.check(MappingStartEvent
):
77 node
= self
.compose_mapping_node()
78 if anchor
is not None:
79 self
.complete_anchors
[anchor
] = node
82 def compose_scalar_node(self
):
83 event
= self
.parser
.get()
84 return ScalarNode(event
.tag
, event
.value
, event
.implicit
,
85 event
.start_mark
, event
.end_mark
, style
=event
.style
)
87 def compose_sequence_node(self
):
88 start_event
= self
.parser
.get()
90 while not self
.parser
.check(SequenceEndEvent
):
91 value
.append(self
.compose_node())
92 end_event
= self
.parser
.get()
93 return SequenceNode(start_event
.tag
, value
,
94 start_event
.start_mark
, end_event
.end_mark
,
95 flow_style
=start_event
.flow_style
)
97 def compose_mapping_node(self
):
98 start_event
= self
.parser
.get()
100 while not self
.parser
.check(MappingEndEvent
):
101 key_event
= self
.parser
.peek()
102 item_key
= self
.compose_node()
103 item_value
= self
.compose_node()
104 if item_key
in value
:
105 raise ComposerError("while composing a mapping", start_event
.start_mark
,
106 "found duplicate key", key_event
.start_mark
)
107 value
[item_key
] = item_value
108 end_event
= self
.parser
.get()
109 return MappingNode(start_event
.tag
, value
,
110 start_event
.start_mark
, end_event
.end_mark
,
111 flow_style
=start_event
.flow_style
)