nodes.py 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. # coding: utf-8
  2. import sys
  3. from typing import Dict, Any, Text, Optional # NOQA
  4. from ruamel.yaml.tag import Tag
  5. class Node:
  6. __slots__ = 'ctag', 'value', 'start_mark', 'end_mark', 'comment', 'anchor'
  7. def __init__(
  8. self,
  9. tag: Any,
  10. value: Any,
  11. start_mark: Any,
  12. end_mark: Any,
  13. comment: Any = None,
  14. anchor: Any = None,
  15. ) -> None:
  16. # you can still get a string from the serializer
  17. self.ctag = tag if isinstance(tag, Tag) else Tag(suffix=tag)
  18. self.value = value
  19. self.start_mark = start_mark
  20. self.end_mark = end_mark
  21. self.comment = comment
  22. self.anchor = anchor
  23. @property
  24. def tag(self) -> Optional[str]:
  25. return None if self.ctag is None else str(self.ctag)
  26. @tag.setter
  27. def tag(self, val: Any) -> None:
  28. if isinstance(val, str):
  29. val = Tag(suffix=val)
  30. self.ctag = val
  31. def __repr__(self) -> Any:
  32. value = self.value
  33. # if isinstance(value, list):
  34. # if len(value) == 0:
  35. # value = '<empty>'
  36. # elif len(value) == 1:
  37. # value = '<1 item>'
  38. # else:
  39. # value = f'<{len(value)} items>'
  40. # else:
  41. # if len(value) > 75:
  42. # value = repr(value[:70]+' ... ')
  43. # else:
  44. # value = repr(value)
  45. value = repr(value)
  46. return f'{self.__class__.__name__!s}(tag={self.tag!r}, value={value!s})'
  47. def dump(self, indent: int = 0) -> None:
  48. xx = self.__class__.__name__
  49. xi = ' ' * indent
  50. if isinstance(self.value, str):
  51. sys.stdout.write(f'{xi}{xx}(tag={self.tag!r}, value={self.value!r})\n')
  52. if self.comment:
  53. sys.stdout.write(f' {xi}comment: {self.comment})\n')
  54. return
  55. sys.stdout.write(f'{xi}{xx}(tag={self.tag!r})\n')
  56. if self.comment:
  57. sys.stdout.write(f' {xi}comment: {self.comment})\n')
  58. for v in self.value:
  59. if isinstance(v, tuple):
  60. for v1 in v:
  61. v1.dump(indent + 1)
  62. elif isinstance(v, Node):
  63. v.dump(indent + 1)
  64. else:
  65. sys.stdout.write(f'Node value type? {type(v)}\n')
  66. class ScalarNode(Node):
  67. """
  68. styles:
  69. ? -> set() ? key, no value
  70. - -> suppressable null value in set
  71. " -> double quoted
  72. ' -> single quoted
  73. | -> literal style
  74. > -> folding style
  75. """
  76. __slots__ = ('style',)
  77. id = 'scalar'
  78. def __init__(
  79. self,
  80. tag: Any,
  81. value: Any,
  82. start_mark: Any = None,
  83. end_mark: Any = None,
  84. style: Any = None,
  85. comment: Any = None,
  86. anchor: Any = None,
  87. ) -> None:
  88. Node.__init__(self, tag, value, start_mark, end_mark, comment=comment, anchor=anchor)
  89. self.style = style
  90. class CollectionNode(Node):
  91. __slots__ = ('flow_style',)
  92. def __init__(
  93. self,
  94. tag: Any,
  95. value: Any,
  96. start_mark: Any = None,
  97. end_mark: Any = None,
  98. flow_style: Any = None,
  99. comment: Any = None,
  100. anchor: Any = None,
  101. ) -> None:
  102. Node.__init__(self, tag, value, start_mark, end_mark, comment=comment)
  103. self.flow_style = flow_style
  104. self.anchor = anchor
  105. class SequenceNode(CollectionNode):
  106. __slots__ = ()
  107. id = 'sequence'
  108. class MappingNode(CollectionNode):
  109. __slots__ = ('merge',)
  110. id = 'mapping'
  111. def __init__(
  112. self,
  113. tag: Any,
  114. value: Any,
  115. start_mark: Any = None,
  116. end_mark: Any = None,
  117. flow_style: Any = None,
  118. comment: Any = None,
  119. anchor: Any = None,
  120. ) -> None:
  121. CollectionNode.__init__(
  122. self, tag, value, start_mark, end_mark, flow_style, comment, anchor,
  123. )
  124. self.merge = None