Implement yaml.dump().
[pyyaml/python3.git] / lib / yaml / serializer.py
blob6a5aafc6adc9a954e683efc5adca3719b7ee8e08
2 __all__ = ['Serializer', 'SerializerError']
4 from error import YAMLError
5 from events import *
6 from nodes import *
8 class SerializerError(YAMLError):
9 pass
11 class Serializer:
13 ANCHOR_TEMPLATE = u'id%03d'
15 def __init__(self, emitter, encoding=None, line_break=None, canonical=None,
16 indent=None, width=None, allow_unicode=None):
17 self.emitter = emitter
18 self.serialized_nodes = {}
19 self.anchors = {}
20 self.last_anchor_id = 0
21 self.closed = None
22 self.open(encoding, line_break, canonical, indent, width)
24 def open(self, encoding=None, line_break=None, canonical=None,
25 indent=None, width=None, allow_unicode=None):
26 if self.closed is None:
27 self.emitter.emit(StreamStartEvent(encoding=encoding,
28 line_break=line_break, canonical=canonical,
29 indent=indent, width=width, allow_unicode=allow_unicode))
30 self.closed = False
31 elif self.closed:
32 raise SerializerError("serializer is closed")
33 else:
34 raise SerializerError("serializer is already opened")
36 def close(self):
37 if self.closed is None:
38 raise SerializerError("serializer is not opened")
39 elif not self.closed:
40 self.emitter.emit(StreamEndEvent())
41 self.closed = True
43 def __del__(self):
44 self.close()
46 def serialize(self, node, explicit_start=None, explicit_end=None,
47 version=None, tags=None):
48 if self.closed is None:
49 raise SerializerError("serializer is not opened")
50 elif self.closed:
51 raise SerializerError("serializer is closed")
52 self.emitter.emit(DocumentStartEvent(explicit=explicit_start,
53 version=version, tags=tags))
54 self.anchor_node(node)
55 self.serialize_node(node)
56 self.emitter.emit(DocumentEndEvent(explicit=explicit_end))
57 self.serialized_nodes = {}
58 self.anchors = {}
59 self.last_alias_id = 0
61 def anchor_node(self, node):
62 if node in self.anchors:
63 if self.anchors[node] is None:
64 self.anchors[node] = self.generate_anchor(node)
65 else:
66 self.anchors[node] = None
67 if isinstance(node, SequenceNode):
68 for item in node.value:
69 self.anchor_node(item)
70 elif isinstance(node, MappingNode):
71 for key in node.value:
72 self.anchor_node(key)
73 self.anchor_node(node.value[key])
75 def generate_anchor(self, node):
76 self.last_anchor_id += 1
77 return self.ANCHOR_TEMPLATE % self.last_anchor_id
79 def serialize_node(self, node):
80 alias = self.anchors[node]
81 if node in self.serialized_nodes:
82 self.emitter.emit(AliasEvent(alias))
83 else:
84 self.serialized_nodes[node] = True
85 if isinstance(node, ScalarNode):
86 self.emitter.emit(ScalarEvent(alias, node.tag, node.value,
87 implicit=node.implicit, style=node.style))
88 elif isinstance(node, SequenceNode):
89 self.emitter.emit(SequenceStartEvent(alias, node.tag,
90 flow_style=node.flow_style))
91 for item in node.value:
92 self.serialize_node(item)
93 self.emitter.emit(SequenceEndEvent())
94 elif isinstance(node, MappingNode):
95 self.emitter.emit(MappingStartEvent(alias, node.tag,
96 flow_style=node.flow_style))
97 for key in node.value:
98 self.serialize_node(key)
99 self.serialize_node(node.value[key])
100 self.emitter.emit(MappingEndEvent())