summaryrefslogtreecommitdiff
path: root/serializer.py
diff options
context:
space:
mode:
authorAnthon van der Neut <anthon@mnt.org>2015-08-28 08:03:59 +0200
committerAnthon van der Neut <anthon@mnt.org>2015-08-28 08:03:59 +0200
commit386029ed647ca7fd0209506285f02365c347eef9 (patch)
tree78263b913d9dbe9bf7c8a3c04379f508bff56a23 /serializer.py
parent04e651b6b062edbdf66271847d3dde06550adbb4 (diff)
downloadruamel.yaml-386029ed647ca7fd0209506285f02365c347eef9.tar.gz
- main problem in moving stuff from yaml/py to yaml was that
parser.py clashes with built-in parser module (CPython, C-module) which is inlucded from pkg_resources/__init__.py - no C compile yet
Diffstat (limited to 'serializer.py')
-rw-r--r--serializer.py166
1 files changed, 166 insertions, 0 deletions
diff --git a/serializer.py b/serializer.py
new file mode 100644
index 0000000..0bdc558
--- /dev/null
+++ b/serializer.py
@@ -0,0 +1,166 @@
+from __future__ import absolute_import
+
+__all__ = ['Serializer', 'SerializerError']
+
+import re
+
+from .error import YAMLError
+from .events import *
+from .nodes import *
+
+from .compat import nprint, DBG_NODE, dbg
+
+
+class SerializerError(YAMLError):
+ pass
+
+
+class Serializer(object):
+
+ # 'id' and 3+ numbers, but not 000
+ ANCHOR_TEMPLATE = u'id%03d'
+ ANCHOR_RE = re.compile(u'id(?!000$)\\d{3,}')
+
+
+ def __init__(self, encoding=None, explicit_start=None, explicit_end=None,
+ version=None, tags=None):
+ self.use_encoding = encoding
+ self.use_explicit_start = explicit_start
+ self.use_explicit_end = explicit_end
+ self.use_version = version
+ self.use_tags = tags
+ self.serialized_nodes = {}
+ self.anchors = {}
+ self.last_anchor_id = 0
+ self.closed = None
+ self._templated_id = None
+
+ def open(self):
+ if self.closed is None:
+ self.emit(StreamStartEvent(encoding=self.use_encoding))
+ self.closed = False
+ elif self.closed:
+ raise SerializerError("serializer is closed")
+ else:
+ raise SerializerError("serializer is already opened")
+
+ def close(self):
+ if self.closed is None:
+ raise SerializerError("serializer is not opened")
+ elif not self.closed:
+ self.emit(StreamEndEvent())
+ self.closed = True
+
+ # def __del__(self):
+ # self.close()
+
+ def serialize(self, node):
+ if dbg(DBG_NODE):
+ nprint('Serializing nodes')
+ node.dump()
+ if self.closed is None:
+ raise SerializerError("serializer is not opened")
+ elif self.closed:
+ raise SerializerError("serializer is closed")
+ self.emit(DocumentStartEvent(explicit=self.use_explicit_start,
+ version=self.use_version,
+ tags=self.use_tags))
+ self.anchor_node(node)
+ self.serialize_node(node, None, None)
+ self.emit(DocumentEndEvent(explicit=self.use_explicit_end))
+ self.serialized_nodes = {}
+ self.anchors = {}
+ self.last_anchor_id = 0
+
+ def anchor_node(self, node):
+ if node in self.anchors:
+ if self.anchors[node] is None:
+ self.anchors[node] = self.generate_anchor(node)
+ else:
+ anchor = None
+ try:
+ if node.anchor.always_dump:
+ anchor = node.anchor.value
+ except:
+ pass
+ self.anchors[node] = anchor
+ if isinstance(node, SequenceNode):
+ for item in node.value:
+ self.anchor_node(item)
+ elif isinstance(node, MappingNode):
+ for key, value in node.value:
+ self.anchor_node(key)
+ self.anchor_node(value)
+
+ def generate_anchor(self, node):
+ try:
+ anchor = node.anchor.value
+ except:
+ anchor = None
+ if anchor is None:
+ self.last_anchor_id += 1
+ return self.ANCHOR_TEMPLATE % self.last_anchor_id
+ return anchor
+
+ def serialize_node(self, node, parent, index):
+ alias = self.anchors[node]
+ if node in self.serialized_nodes:
+ self.emit(AliasEvent(alias))
+ else:
+ self.serialized_nodes[node] = True
+ self.descend_resolver(parent, index)
+ if isinstance(node, ScalarNode):
+ detected_tag = self.resolve(ScalarNode, node.value,
+ (True, False))
+ default_tag = self.resolve(ScalarNode, node.value,
+ (False, True))
+ implicit = \
+ (node.tag == detected_tag), (node.tag == default_tag)
+ self.emit(ScalarEvent(alias, node.tag, implicit, node.value,
+ style=node.style, comment=node.comment))
+ elif isinstance(node, SequenceNode):
+ implicit = (node.tag
+ == self.resolve(SequenceNode, node.value, True))
+ comment = node.comment
+ # print('comment >>>>>>>>>>>>>.', comment, node.flow_style)
+ end_comment = None
+ seq_comment = None
+ if node.flow_style is True:
+ if comment: # eol comment on flow style sequence
+ seq_comment = comment[0]
+ # comment[0] = None
+ if comment and len(comment) > 2:
+ end_comment = comment[2]
+ else:
+ end_comment = None
+ self.emit(SequenceStartEvent(alias, node.tag, implicit,
+ flow_style=node.flow_style,
+ comment=node.comment))
+ index = 0
+ for item in node.value:
+ self.serialize_node(item, node, index)
+ index += 1
+ self.emit(SequenceEndEvent(comment=[seq_comment, end_comment]))
+ elif isinstance(node, MappingNode):
+ implicit = (node.tag
+ == self.resolve(MappingNode, node.value, True))
+ comment = node.comment
+ end_comment = None
+ map_comment = None
+ if node.flow_style is True:
+ if comment: # eol comment on flow style sequence
+ map_comment = comment[0]
+ # comment[0] = None
+ if comment and len(comment) > 2:
+ end_comment = comment[2]
+ self.emit(MappingStartEvent(alias, node.tag, implicit,
+ flow_style=node.flow_style,
+ comment=node.comment))
+ for key, value in node.value:
+ self.serialize_node(key, node, None)
+ self.serialize_node(value, node, key)
+ self.emit(MappingEndEvent(comment=[map_comment, end_comment]))
+ self.ascend_resolver()
+
+def templated_id(s):
+ return Serializer.ANCHOR_RE.match(s) \ No newline at end of file