serializer.py 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. # SPDX-License-Identifier: MIT
  2. __all__ = ['Serializer', 'SerializerError']
  3. from .error import YAMLError
  4. from .events import *
  5. from .nodes import *
  6. class SerializerError(YAMLError):
  7. pass
  8. class Serializer:
  9. ANCHOR_TEMPLATE = 'id%03d'
  10. def __init__(self, encoding=None,
  11. explicit_start=None, explicit_end=None, version=None, tags=None):
  12. self.use_encoding = encoding
  13. self.use_explicit_start = explicit_start
  14. self.use_explicit_end = explicit_end
  15. self.use_version = version
  16. self.use_tags = tags
  17. self.serialized_nodes = {}
  18. self.anchors = {}
  19. self.last_anchor_id = 0
  20. self.closed = None
  21. def open(self):
  22. if self.closed is None:
  23. self.emit(StreamStartEvent(encoding=self.use_encoding))
  24. self.closed = False
  25. elif self.closed:
  26. raise SerializerError("serializer is closed")
  27. else:
  28. raise SerializerError("serializer is already opened")
  29. def close(self):
  30. if self.closed is None:
  31. raise SerializerError("serializer is not opened")
  32. elif not self.closed:
  33. self.emit(StreamEndEvent())
  34. self.closed = True
  35. #def __del__(self):
  36. # self.close()
  37. def serialize(self, node):
  38. if self.closed is None:
  39. raise SerializerError("serializer is not opened")
  40. elif self.closed:
  41. raise SerializerError("serializer is closed")
  42. self.emit(DocumentStartEvent(explicit=self.use_explicit_start,
  43. version=self.use_version, tags=self.use_tags))
  44. self.anchor_node(node)
  45. self.serialize_node(node, None, None)
  46. self.emit(DocumentEndEvent(explicit=self.use_explicit_end))
  47. self.serialized_nodes = {}
  48. self.anchors = {}
  49. self.last_anchor_id = 0
  50. def anchor_node(self, node):
  51. if node in self.anchors:
  52. if self.anchors[node] is None:
  53. self.anchors[node] = self.generate_anchor(node)
  54. else:
  55. self.anchors[node] = None
  56. if isinstance(node, SequenceNode):
  57. for item in node.value:
  58. self.anchor_node(item)
  59. elif isinstance(node, MappingNode):
  60. for key, value in node.value:
  61. self.anchor_node(key)
  62. self.anchor_node(value)
  63. def generate_anchor(self, node):
  64. self.last_anchor_id += 1
  65. return self.ANCHOR_TEMPLATE % self.last_anchor_id
  66. def serialize_node(self, node, parent, index):
  67. alias = self.anchors[node]
  68. if node in self.serialized_nodes:
  69. self.emit(AliasEvent(alias))
  70. else:
  71. self.serialized_nodes[node] = True
  72. self.descend_resolver(parent, index)
  73. if isinstance(node, ScalarNode):
  74. detected_tag = self.resolve(ScalarNode, node.value, (True, False))
  75. default_tag = self.resolve(ScalarNode, node.value, (False, True))
  76. implicit = (node.tag == detected_tag), (node.tag == default_tag)
  77. self.emit(ScalarEvent(alias, node.tag, implicit, node.value,
  78. style=node.style))
  79. elif isinstance(node, SequenceNode):
  80. implicit = (node.tag
  81. == self.resolve(SequenceNode, node.value, True))
  82. self.emit(SequenceStartEvent(alias, node.tag, implicit,
  83. flow_style=node.flow_style))
  84. index = 0
  85. for item in node.value:
  86. self.serialize_node(item, node, index)
  87. index += 1
  88. self.emit(SequenceEndEvent())
  89. elif isinstance(node, MappingNode):
  90. implicit = (node.tag
  91. == self.resolve(MappingNode, node.value, True))
  92. self.emit(MappingStartEvent(alias, node.tag, implicit,
  93. flow_style=node.flow_style))
  94. for key, value in node.value:
  95. self.serialize_node(key, node, None)
  96. self.serialize_node(value, node, key)
  97. self.emit(MappingEndEvent())
  98. self.ascend_resolver()