Mercurial > repos > shellac > guppy_basecaller
comparison env/lib/python3.7/site-packages/ruamel/yaml/representer.py @ 0:26e78fe6e8c4 draft
"planemo upload commit c699937486c35866861690329de38ec1a5d9f783"
| author | shellac |
|---|---|
| date | Sat, 02 May 2020 07:14:21 -0400 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 0:26e78fe6e8c4 |
|---|---|
| 1 # coding: utf-8 | |
| 2 | |
| 3 from __future__ import print_function, absolute_import, division | |
| 4 | |
| 5 | |
| 6 from ruamel.yaml.error import * # NOQA | |
| 7 from ruamel.yaml.nodes import * # NOQA | |
| 8 from ruamel.yaml.compat import text_type, binary_type, to_unicode, PY2, PY3, ordereddict | |
| 9 from ruamel.yaml.compat import nprint, nprintf # NOQA | |
| 10 from ruamel.yaml.scalarstring import ( | |
| 11 LiteralScalarString, | |
| 12 FoldedScalarString, | |
| 13 SingleQuotedScalarString, | |
| 14 DoubleQuotedScalarString, | |
| 15 PlainScalarString, | |
| 16 ) | |
| 17 from ruamel.yaml.scalarint import ScalarInt, BinaryInt, OctalInt, HexInt, HexCapsInt | |
| 18 from ruamel.yaml.scalarfloat import ScalarFloat | |
| 19 from ruamel.yaml.scalarbool import ScalarBoolean | |
| 20 from ruamel.yaml.timestamp import TimeStamp | |
| 21 | |
| 22 import datetime | |
| 23 import sys | |
| 24 import types | |
| 25 | |
| 26 if PY3: | |
| 27 import copyreg | |
| 28 import base64 | |
| 29 else: | |
| 30 import copy_reg as copyreg # type: ignore | |
| 31 | |
| 32 if False: # MYPY | |
| 33 from typing import Dict, List, Any, Union, Text, Optional # NOQA | |
| 34 | |
| 35 # fmt: off | |
| 36 __all__ = ['BaseRepresenter', 'SafeRepresenter', 'Representer', | |
| 37 'RepresenterError', 'RoundTripRepresenter'] | |
| 38 # fmt: on | |
| 39 | |
| 40 | |
| 41 class RepresenterError(YAMLError): | |
| 42 pass | |
| 43 | |
| 44 | |
| 45 if PY2: | |
| 46 | |
| 47 def get_classobj_bases(cls): | |
| 48 # type: (Any) -> Any | |
| 49 bases = [cls] | |
| 50 for base in cls.__bases__: | |
| 51 bases.extend(get_classobj_bases(base)) | |
| 52 return bases | |
| 53 | |
| 54 | |
| 55 class BaseRepresenter(object): | |
| 56 | |
| 57 yaml_representers = {} # type: Dict[Any, Any] | |
| 58 yaml_multi_representers = {} # type: Dict[Any, Any] | |
| 59 | |
| 60 def __init__(self, default_style=None, default_flow_style=None, dumper=None): | |
| 61 # type: (Any, Any, Any, Any) -> None | |
| 62 self.dumper = dumper | |
| 63 if self.dumper is not None: | |
| 64 self.dumper._representer = self | |
| 65 self.default_style = default_style | |
| 66 self.default_flow_style = default_flow_style | |
| 67 self.represented_objects = {} # type: Dict[Any, Any] | |
| 68 self.object_keeper = [] # type: List[Any] | |
| 69 self.alias_key = None # type: Optional[int] | |
| 70 self.sort_base_mapping_type_on_output = True | |
| 71 | |
| 72 @property | |
| 73 def serializer(self): | |
| 74 # type: () -> Any | |
| 75 try: | |
| 76 if hasattr(self.dumper, 'typ'): | |
| 77 return self.dumper.serializer | |
| 78 return self.dumper._serializer | |
| 79 except AttributeError: | |
| 80 return self # cyaml | |
| 81 | |
| 82 def represent(self, data): | |
| 83 # type: (Any) -> None | |
| 84 node = self.represent_data(data) | |
| 85 self.serializer.serialize(node) | |
| 86 self.represented_objects = {} # type: Dict[Any, Any] | |
| 87 self.object_keeper = [] # type: List[Any] | |
| 88 self.alias_key = None | |
| 89 | |
| 90 def represent_data(self, data): | |
| 91 # type: (Any) -> Any | |
| 92 if self.ignore_aliases(data): | |
| 93 self.alias_key = None | |
| 94 else: | |
| 95 self.alias_key = id(data) | |
| 96 if self.alias_key is not None: | |
| 97 if self.alias_key in self.represented_objects: | |
| 98 node = self.represented_objects[self.alias_key] | |
| 99 # if node is None: | |
| 100 # raise RepresenterError( | |
| 101 # "recursive objects are not allowed: %r" % data) | |
| 102 return node | |
| 103 # self.represented_objects[alias_key] = None | |
| 104 self.object_keeper.append(data) | |
| 105 data_types = type(data).__mro__ | |
| 106 if PY2: | |
| 107 # if type(data) is types.InstanceType: | |
| 108 if isinstance(data, types.InstanceType): | |
| 109 data_types = get_classobj_bases(data.__class__) + list(data_types) | |
| 110 if data_types[0] in self.yaml_representers: | |
| 111 node = self.yaml_representers[data_types[0]](self, data) | |
| 112 else: | |
| 113 for data_type in data_types: | |
| 114 if data_type in self.yaml_multi_representers: | |
| 115 node = self.yaml_multi_representers[data_type](self, data) | |
| 116 break | |
| 117 else: | |
| 118 if None in self.yaml_multi_representers: | |
| 119 node = self.yaml_multi_representers[None](self, data) | |
| 120 elif None in self.yaml_representers: | |
| 121 node = self.yaml_representers[None](self, data) | |
| 122 else: | |
| 123 node = ScalarNode(None, text_type(data)) | |
| 124 # if alias_key is not None: | |
| 125 # self.represented_objects[alias_key] = node | |
| 126 return node | |
| 127 | |
| 128 def represent_key(self, data): | |
| 129 # type: (Any) -> Any | |
| 130 """ | |
| 131 David Fraser: Extract a method to represent keys in mappings, so that | |
| 132 a subclass can choose not to quote them (for example) | |
| 133 used in represent_mapping | |
| 134 https://bitbucket.org/davidfraser/pyyaml/commits/d81df6eb95f20cac4a79eed95ae553b5c6f77b8c | |
| 135 """ | |
| 136 return self.represent_data(data) | |
| 137 | |
| 138 @classmethod | |
| 139 def add_representer(cls, data_type, representer): | |
| 140 # type: (Any, Any) -> None | |
| 141 if 'yaml_representers' not in cls.__dict__: | |
| 142 cls.yaml_representers = cls.yaml_representers.copy() | |
| 143 cls.yaml_representers[data_type] = representer | |
| 144 | |
| 145 @classmethod | |
| 146 def add_multi_representer(cls, data_type, representer): | |
| 147 # type: (Any, Any) -> None | |
| 148 if 'yaml_multi_representers' not in cls.__dict__: | |
| 149 cls.yaml_multi_representers = cls.yaml_multi_representers.copy() | |
| 150 cls.yaml_multi_representers[data_type] = representer | |
| 151 | |
| 152 def represent_scalar(self, tag, value, style=None, anchor=None): | |
| 153 # type: (Any, Any, Any, Any) -> Any | |
| 154 if style is None: | |
| 155 style = self.default_style | |
| 156 comment = None | |
| 157 if style and style[0] in '|>': | |
| 158 comment = getattr(value, 'comment', None) | |
| 159 if comment: | |
| 160 comment = [None, [comment]] | |
| 161 node = ScalarNode(tag, value, style=style, comment=comment, anchor=anchor) | |
| 162 if self.alias_key is not None: | |
| 163 self.represented_objects[self.alias_key] = node | |
| 164 return node | |
| 165 | |
| 166 def represent_sequence(self, tag, sequence, flow_style=None): | |
| 167 # type: (Any, Any, Any) -> Any | |
| 168 value = [] # type: List[Any] | |
| 169 node = SequenceNode(tag, value, flow_style=flow_style) | |
| 170 if self.alias_key is not None: | |
| 171 self.represented_objects[self.alias_key] = node | |
| 172 best_style = True | |
| 173 for item in sequence: | |
| 174 node_item = self.represent_data(item) | |
| 175 if not (isinstance(node_item, ScalarNode) and not node_item.style): | |
| 176 best_style = False | |
| 177 value.append(node_item) | |
| 178 if flow_style is None: | |
| 179 if self.default_flow_style is not None: | |
| 180 node.flow_style = self.default_flow_style | |
| 181 else: | |
| 182 node.flow_style = best_style | |
| 183 return node | |
| 184 | |
| 185 def represent_omap(self, tag, omap, flow_style=None): | |
| 186 # type: (Any, Any, Any) -> Any | |
| 187 value = [] # type: List[Any] | |
| 188 node = SequenceNode(tag, value, flow_style=flow_style) | |
| 189 if self.alias_key is not None: | |
| 190 self.represented_objects[self.alias_key] = node | |
| 191 best_style = True | |
| 192 for item_key in omap: | |
| 193 item_val = omap[item_key] | |
| 194 node_item = self.represent_data({item_key: item_val}) | |
| 195 # if not (isinstance(node_item, ScalarNode) \ | |
| 196 # and not node_item.style): | |
| 197 # best_style = False | |
| 198 value.append(node_item) | |
| 199 if flow_style is None: | |
| 200 if self.default_flow_style is not None: | |
| 201 node.flow_style = self.default_flow_style | |
| 202 else: | |
| 203 node.flow_style = best_style | |
| 204 return node | |
| 205 | |
| 206 def represent_mapping(self, tag, mapping, flow_style=None): | |
| 207 # type: (Any, Any, Any) -> Any | |
| 208 value = [] # type: List[Any] | |
| 209 node = MappingNode(tag, value, flow_style=flow_style) | |
| 210 if self.alias_key is not None: | |
| 211 self.represented_objects[self.alias_key] = node | |
| 212 best_style = True | |
| 213 if hasattr(mapping, 'items'): | |
| 214 mapping = list(mapping.items()) | |
| 215 if self.sort_base_mapping_type_on_output: | |
| 216 try: | |
| 217 mapping = sorted(mapping) | |
| 218 except TypeError: | |
| 219 pass | |
| 220 for item_key, item_value in mapping: | |
| 221 node_key = self.represent_key(item_key) | |
| 222 node_value = self.represent_data(item_value) | |
| 223 if not (isinstance(node_key, ScalarNode) and not node_key.style): | |
| 224 best_style = False | |
| 225 if not (isinstance(node_value, ScalarNode) and not node_value.style): | |
| 226 best_style = False | |
| 227 value.append((node_key, node_value)) | |
| 228 if flow_style is None: | |
| 229 if self.default_flow_style is not None: | |
| 230 node.flow_style = self.default_flow_style | |
| 231 else: | |
| 232 node.flow_style = best_style | |
| 233 return node | |
| 234 | |
| 235 def ignore_aliases(self, data): | |
| 236 # type: (Any) -> bool | |
| 237 return False | |
| 238 | |
| 239 | |
| 240 class SafeRepresenter(BaseRepresenter): | |
| 241 def ignore_aliases(self, data): | |
| 242 # type: (Any) -> bool | |
| 243 # https://docs.python.org/3/reference/expressions.html#parenthesized-forms : | |
| 244 # "i.e. two occurrences of the empty tuple may or may not yield the same object" | |
| 245 # so "data is ()" should not be used | |
| 246 if data is None or (isinstance(data, tuple) and data == ()): | |
| 247 return True | |
| 248 if isinstance(data, (binary_type, text_type, bool, int, float)): | |
| 249 return True | |
| 250 return False | |
| 251 | |
| 252 def represent_none(self, data): | |
| 253 # type: (Any) -> Any | |
| 254 return self.represent_scalar(u'tag:yaml.org,2002:null', u'null') | |
| 255 | |
| 256 if PY3: | |
| 257 | |
| 258 def represent_str(self, data): | |
| 259 # type: (Any) -> Any | |
| 260 return self.represent_scalar(u'tag:yaml.org,2002:str', data) | |
| 261 | |
| 262 def represent_binary(self, data): | |
| 263 # type: (Any) -> Any | |
| 264 if hasattr(base64, 'encodebytes'): | |
| 265 data = base64.encodebytes(data).decode('ascii') | |
| 266 else: | |
| 267 data = base64.encodestring(data).decode('ascii') | |
| 268 return self.represent_scalar(u'tag:yaml.org,2002:binary', data, style='|') | |
| 269 | |
| 270 else: | |
| 271 | |
| 272 def represent_str(self, data): | |
| 273 # type: (Any) -> Any | |
| 274 tag = None | |
| 275 style = None | |
| 276 try: | |
| 277 data = unicode(data, 'ascii') | |
| 278 tag = u'tag:yaml.org,2002:str' | |
| 279 except UnicodeDecodeError: | |
| 280 try: | |
| 281 data = unicode(data, 'utf-8') | |
| 282 tag = u'tag:yaml.org,2002:str' | |
| 283 except UnicodeDecodeError: | |
| 284 data = data.encode('base64') | |
| 285 tag = u'tag:yaml.org,2002:binary' | |
| 286 style = '|' | |
| 287 return self.represent_scalar(tag, data, style=style) | |
| 288 | |
| 289 def represent_unicode(self, data): | |
| 290 # type: (Any) -> Any | |
| 291 return self.represent_scalar(u'tag:yaml.org,2002:str', data) | |
| 292 | |
| 293 def represent_bool(self, data, anchor=None): | |
| 294 # type: (Any, Optional[Any]) -> Any | |
| 295 try: | |
| 296 value = self.dumper.boolean_representation[bool(data)] | |
| 297 except AttributeError: | |
| 298 if data: | |
| 299 value = u'true' | |
| 300 else: | |
| 301 value = u'false' | |
| 302 return self.represent_scalar(u'tag:yaml.org,2002:bool', value, anchor=anchor) | |
| 303 | |
| 304 def represent_int(self, data): | |
| 305 # type: (Any) -> Any | |
| 306 return self.represent_scalar(u'tag:yaml.org,2002:int', text_type(data)) | |
| 307 | |
| 308 if PY2: | |
| 309 | |
| 310 def represent_long(self, data): | |
| 311 # type: (Any) -> Any | |
| 312 return self.represent_scalar(u'tag:yaml.org,2002:int', text_type(data)) | |
| 313 | |
| 314 inf_value = 1e300 | |
| 315 while repr(inf_value) != repr(inf_value * inf_value): | |
| 316 inf_value *= inf_value | |
| 317 | |
| 318 def represent_float(self, data): | |
| 319 # type: (Any) -> Any | |
| 320 if data != data or (data == 0.0 and data == 1.0): | |
| 321 value = u'.nan' | |
| 322 elif data == self.inf_value: | |
| 323 value = u'.inf' | |
| 324 elif data == -self.inf_value: | |
| 325 value = u'-.inf' | |
| 326 else: | |
| 327 value = to_unicode(repr(data)).lower() | |
| 328 if getattr(self.serializer, 'use_version', None) == (1, 1): | |
| 329 if u'.' not in value and u'e' in value: | |
| 330 # Note that in some cases `repr(data)` represents a float number | |
| 331 # without the decimal parts. For instance: | |
| 332 # >>> repr(1e17) | |
| 333 # '1e17' | |
| 334 # Unfortunately, this is not a valid float representation according | |
| 335 # to the definition of the `!!float` tag in YAML 1.1. We fix | |
| 336 # this by adding '.0' before the 'e' symbol. | |
| 337 value = value.replace(u'e', u'.0e', 1) | |
| 338 return self.represent_scalar(u'tag:yaml.org,2002:float', value) | |
| 339 | |
| 340 def represent_list(self, data): | |
| 341 # type: (Any) -> Any | |
| 342 # pairs = (len(data) > 0 and isinstance(data, list)) | |
| 343 # if pairs: | |
| 344 # for item in data: | |
| 345 # if not isinstance(item, tuple) or len(item) != 2: | |
| 346 # pairs = False | |
| 347 # break | |
| 348 # if not pairs: | |
| 349 return self.represent_sequence(u'tag:yaml.org,2002:seq', data) | |
| 350 | |
| 351 # value = [] | |
| 352 # for item_key, item_value in data: | |
| 353 # value.append(self.represent_mapping(u'tag:yaml.org,2002:map', | |
| 354 # [(item_key, item_value)])) | |
| 355 # return SequenceNode(u'tag:yaml.org,2002:pairs', value) | |
| 356 | |
| 357 def represent_dict(self, data): | |
| 358 # type: (Any) -> Any | |
| 359 return self.represent_mapping(u'tag:yaml.org,2002:map', data) | |
| 360 | |
| 361 def represent_ordereddict(self, data): | |
| 362 # type: (Any) -> Any | |
| 363 return self.represent_omap(u'tag:yaml.org,2002:omap', data) | |
| 364 | |
| 365 def represent_set(self, data): | |
| 366 # type: (Any) -> Any | |
| 367 value = {} # type: Dict[Any, None] | |
| 368 for key in data: | |
| 369 value[key] = None | |
| 370 return self.represent_mapping(u'tag:yaml.org,2002:set', value) | |
| 371 | |
| 372 def represent_date(self, data): | |
| 373 # type: (Any) -> Any | |
| 374 value = to_unicode(data.isoformat()) | |
| 375 return self.represent_scalar(u'tag:yaml.org,2002:timestamp', value) | |
| 376 | |
| 377 def represent_datetime(self, data): | |
| 378 # type: (Any) -> Any | |
| 379 value = to_unicode(data.isoformat(' ')) | |
| 380 return self.represent_scalar(u'tag:yaml.org,2002:timestamp', value) | |
| 381 | |
| 382 def represent_yaml_object(self, tag, data, cls, flow_style=None): | |
| 383 # type: (Any, Any, Any, Any) -> Any | |
| 384 if hasattr(data, '__getstate__'): | |
| 385 state = data.__getstate__() | |
| 386 else: | |
| 387 state = data.__dict__.copy() | |
| 388 return self.represent_mapping(tag, state, flow_style=flow_style) | |
| 389 | |
| 390 def represent_undefined(self, data): | |
| 391 # type: (Any) -> None | |
| 392 raise RepresenterError('cannot represent an object: %s' % (data,)) | |
| 393 | |
| 394 | |
| 395 SafeRepresenter.add_representer(type(None), SafeRepresenter.represent_none) | |
| 396 | |
| 397 SafeRepresenter.add_representer(str, SafeRepresenter.represent_str) | |
| 398 | |
| 399 if PY2: | |
| 400 SafeRepresenter.add_representer(unicode, SafeRepresenter.represent_unicode) | |
| 401 else: | |
| 402 SafeRepresenter.add_representer(bytes, SafeRepresenter.represent_binary) | |
| 403 | |
| 404 SafeRepresenter.add_representer(bool, SafeRepresenter.represent_bool) | |
| 405 | |
| 406 SafeRepresenter.add_representer(int, SafeRepresenter.represent_int) | |
| 407 | |
| 408 if PY2: | |
| 409 SafeRepresenter.add_representer(long, SafeRepresenter.represent_long) | |
| 410 | |
| 411 SafeRepresenter.add_representer(float, SafeRepresenter.represent_float) | |
| 412 | |
| 413 SafeRepresenter.add_representer(list, SafeRepresenter.represent_list) | |
| 414 | |
| 415 SafeRepresenter.add_representer(tuple, SafeRepresenter.represent_list) | |
| 416 | |
| 417 SafeRepresenter.add_representer(dict, SafeRepresenter.represent_dict) | |
| 418 | |
| 419 SafeRepresenter.add_representer(set, SafeRepresenter.represent_set) | |
| 420 | |
| 421 SafeRepresenter.add_representer(ordereddict, SafeRepresenter.represent_ordereddict) | |
| 422 | |
| 423 if sys.version_info >= (2, 7): | |
| 424 import collections | |
| 425 | |
| 426 SafeRepresenter.add_representer( | |
| 427 collections.OrderedDict, SafeRepresenter.represent_ordereddict | |
| 428 ) | |
| 429 | |
| 430 SafeRepresenter.add_representer(datetime.date, SafeRepresenter.represent_date) | |
| 431 | |
| 432 SafeRepresenter.add_representer(datetime.datetime, SafeRepresenter.represent_datetime) | |
| 433 | |
| 434 SafeRepresenter.add_representer(None, SafeRepresenter.represent_undefined) | |
| 435 | |
| 436 | |
| 437 class Representer(SafeRepresenter): | |
| 438 if PY2: | |
| 439 | |
| 440 def represent_str(self, data): | |
| 441 # type: (Any) -> Any | |
| 442 tag = None | |
| 443 style = None | |
| 444 try: | |
| 445 data = unicode(data, 'ascii') | |
| 446 tag = u'tag:yaml.org,2002:str' | |
| 447 except UnicodeDecodeError: | |
| 448 try: | |
| 449 data = unicode(data, 'utf-8') | |
| 450 tag = u'tag:yaml.org,2002:python/str' | |
| 451 except UnicodeDecodeError: | |
| 452 data = data.encode('base64') | |
| 453 tag = u'tag:yaml.org,2002:binary' | |
| 454 style = '|' | |
| 455 return self.represent_scalar(tag, data, style=style) | |
| 456 | |
| 457 def represent_unicode(self, data): | |
| 458 # type: (Any) -> Any | |
| 459 tag = None | |
| 460 try: | |
| 461 data.encode('ascii') | |
| 462 tag = u'tag:yaml.org,2002:python/unicode' | |
| 463 except UnicodeEncodeError: | |
| 464 tag = u'tag:yaml.org,2002:str' | |
| 465 return self.represent_scalar(tag, data) | |
| 466 | |
| 467 def represent_long(self, data): | |
| 468 # type: (Any) -> Any | |
| 469 tag = u'tag:yaml.org,2002:int' | |
| 470 if int(data) is not data: | |
| 471 tag = u'tag:yaml.org,2002:python/long' | |
| 472 return self.represent_scalar(tag, to_unicode(data)) | |
| 473 | |
| 474 def represent_complex(self, data): | |
| 475 # type: (Any) -> Any | |
| 476 if data.imag == 0.0: | |
| 477 data = u'%r' % data.real | |
| 478 elif data.real == 0.0: | |
| 479 data = u'%rj' % data.imag | |
| 480 elif data.imag > 0: | |
| 481 data = u'%r+%rj' % (data.real, data.imag) | |
| 482 else: | |
| 483 data = u'%r%rj' % (data.real, data.imag) | |
| 484 return self.represent_scalar(u'tag:yaml.org,2002:python/complex', data) | |
| 485 | |
| 486 def represent_tuple(self, data): | |
| 487 # type: (Any) -> Any | |
| 488 return self.represent_sequence(u'tag:yaml.org,2002:python/tuple', data) | |
| 489 | |
| 490 def represent_name(self, data): | |
| 491 # type: (Any) -> Any | |
| 492 try: | |
| 493 name = u'%s.%s' % (data.__module__, data.__qualname__) | |
| 494 except AttributeError: | |
| 495 # probably PY2 | |
| 496 name = u'%s.%s' % (data.__module__, data.__name__) | |
| 497 return self.represent_scalar(u'tag:yaml.org,2002:python/name:' + name, "") | |
| 498 | |
| 499 def represent_module(self, data): | |
| 500 # type: (Any) -> Any | |
| 501 return self.represent_scalar(u'tag:yaml.org,2002:python/module:' + data.__name__, "") | |
| 502 | |
| 503 if PY2: | |
| 504 | |
| 505 def represent_instance(self, data): | |
| 506 # type: (Any) -> Any | |
| 507 # For instances of classic classes, we use __getinitargs__ and | |
| 508 # __getstate__ to serialize the data. | |
| 509 | |
| 510 # If data.__getinitargs__ exists, the object must be reconstructed | |
| 511 # by calling cls(**args), where args is a tuple returned by | |
| 512 # __getinitargs__. Otherwise, the cls.__init__ method should never | |
| 513 # be called and the class instance is created by instantiating a | |
| 514 # trivial class and assigning to the instance's __class__ variable. | |
| 515 | |
| 516 # If data.__getstate__ exists, it returns the state of the object. | |
| 517 # Otherwise, the state of the object is data.__dict__. | |
| 518 | |
| 519 # We produce either a !!python/object or !!python/object/new node. | |
| 520 # If data.__getinitargs__ does not exist and state is a dictionary, | |
| 521 # we produce a !!python/object node . Otherwise we produce a | |
| 522 # !!python/object/new node. | |
| 523 | |
| 524 cls = data.__class__ | |
| 525 class_name = u'%s.%s' % (cls.__module__, cls.__name__) | |
| 526 args = None | |
| 527 state = None | |
| 528 if hasattr(data, '__getinitargs__'): | |
| 529 args = list(data.__getinitargs__()) | |
| 530 if hasattr(data, '__getstate__'): | |
| 531 state = data.__getstate__() | |
| 532 else: | |
| 533 state = data.__dict__ | |
| 534 if args is None and isinstance(state, dict): | |
| 535 return self.represent_mapping( | |
| 536 u'tag:yaml.org,2002:python/object:' + class_name, state | |
| 537 ) | |
| 538 if isinstance(state, dict) and not state: | |
| 539 return self.represent_sequence( | |
| 540 u'tag:yaml.org,2002:python/object/new:' + class_name, args | |
| 541 ) | |
| 542 value = {} | |
| 543 if bool(args): | |
| 544 value['args'] = args | |
| 545 value['state'] = state # type: ignore | |
| 546 return self.represent_mapping( | |
| 547 u'tag:yaml.org,2002:python/object/new:' + class_name, value | |
| 548 ) | |
| 549 | |
| 550 def represent_object(self, data): | |
| 551 # type: (Any) -> Any | |
| 552 # We use __reduce__ API to save the data. data.__reduce__ returns | |
| 553 # a tuple of length 2-5: | |
| 554 # (function, args, state, listitems, dictitems) | |
| 555 | |
| 556 # For reconstructing, we calls function(*args), then set its state, | |
| 557 # listitems, and dictitems if they are not None. | |
| 558 | |
| 559 # A special case is when function.__name__ == '__newobj__'. In this | |
| 560 # case we create the object with args[0].__new__(*args). | |
| 561 | |
| 562 # Another special case is when __reduce__ returns a string - we don't | |
| 563 # support it. | |
| 564 | |
| 565 # We produce a !!python/object, !!python/object/new or | |
| 566 # !!python/object/apply node. | |
| 567 | |
| 568 cls = type(data) | |
| 569 if cls in copyreg.dispatch_table: | |
| 570 reduce = copyreg.dispatch_table[cls](data) | |
| 571 elif hasattr(data, '__reduce_ex__'): | |
| 572 reduce = data.__reduce_ex__(2) | |
| 573 elif hasattr(data, '__reduce__'): | |
| 574 reduce = data.__reduce__() | |
| 575 else: | |
| 576 raise RepresenterError('cannot represent object: %r' % (data,)) | |
| 577 reduce = (list(reduce) + [None] * 5)[:5] | |
| 578 function, args, state, listitems, dictitems = reduce | |
| 579 args = list(args) | |
| 580 if state is None: | |
| 581 state = {} | |
| 582 if listitems is not None: | |
| 583 listitems = list(listitems) | |
| 584 if dictitems is not None: | |
| 585 dictitems = dict(dictitems) | |
| 586 if function.__name__ == '__newobj__': | |
| 587 function = args[0] | |
| 588 args = args[1:] | |
| 589 tag = u'tag:yaml.org,2002:python/object/new:' | |
| 590 newobj = True | |
| 591 else: | |
| 592 tag = u'tag:yaml.org,2002:python/object/apply:' | |
| 593 newobj = False | |
| 594 try: | |
| 595 function_name = u'%s.%s' % (function.__module__, function.__qualname__) | |
| 596 except AttributeError: | |
| 597 # probably PY2 | |
| 598 function_name = u'%s.%s' % (function.__module__, function.__name__) | |
| 599 if not args and not listitems and not dictitems and isinstance(state, dict) and newobj: | |
| 600 return self.represent_mapping( | |
| 601 u'tag:yaml.org,2002:python/object:' + function_name, state | |
| 602 ) | |
| 603 if not listitems and not dictitems and isinstance(state, dict) and not state: | |
| 604 return self.represent_sequence(tag + function_name, args) | |
| 605 value = {} | |
| 606 if args: | |
| 607 value['args'] = args | |
| 608 if state or not isinstance(state, dict): | |
| 609 value['state'] = state | |
| 610 if listitems: | |
| 611 value['listitems'] = listitems | |
| 612 if dictitems: | |
| 613 value['dictitems'] = dictitems | |
| 614 return self.represent_mapping(tag + function_name, value) | |
| 615 | |
| 616 | |
| 617 if PY2: | |
| 618 Representer.add_representer(str, Representer.represent_str) | |
| 619 | |
| 620 Representer.add_representer(unicode, Representer.represent_unicode) | |
| 621 | |
| 622 Representer.add_representer(long, Representer.represent_long) | |
| 623 | |
| 624 Representer.add_representer(complex, Representer.represent_complex) | |
| 625 | |
| 626 Representer.add_representer(tuple, Representer.represent_tuple) | |
| 627 | |
| 628 Representer.add_representer(type, Representer.represent_name) | |
| 629 | |
| 630 if PY2: | |
| 631 Representer.add_representer(types.ClassType, Representer.represent_name) | |
| 632 | |
| 633 Representer.add_representer(types.FunctionType, Representer.represent_name) | |
| 634 | |
| 635 Representer.add_representer(types.BuiltinFunctionType, Representer.represent_name) | |
| 636 | |
| 637 Representer.add_representer(types.ModuleType, Representer.represent_module) | |
| 638 | |
| 639 if PY2: | |
| 640 Representer.add_multi_representer(types.InstanceType, Representer.represent_instance) | |
| 641 | |
| 642 Representer.add_multi_representer(object, Representer.represent_object) | |
| 643 | |
| 644 Representer.add_multi_representer(type, Representer.represent_name) | |
| 645 | |
| 646 from ruamel.yaml.comments import ( | |
| 647 CommentedMap, | |
| 648 CommentedOrderedMap, | |
| 649 CommentedSeq, | |
| 650 CommentedKeySeq, | |
| 651 CommentedKeyMap, | |
| 652 CommentedSet, | |
| 653 comment_attrib, | |
| 654 merge_attrib, | |
| 655 TaggedScalar, | |
| 656 ) # NOQA | |
| 657 | |
| 658 | |
| 659 class RoundTripRepresenter(SafeRepresenter): | |
| 660 # need to add type here and write out the .comment | |
| 661 # in serializer and emitter | |
| 662 | |
| 663 def __init__(self, default_style=None, default_flow_style=None, dumper=None): | |
| 664 # type: (Any, Any, Any) -> None | |
| 665 if not hasattr(dumper, 'typ') and default_flow_style is None: | |
| 666 default_flow_style = False | |
| 667 SafeRepresenter.__init__( | |
| 668 self, | |
| 669 default_style=default_style, | |
| 670 default_flow_style=default_flow_style, | |
| 671 dumper=dumper, | |
| 672 ) | |
| 673 | |
| 674 def ignore_aliases(self, data): | |
| 675 # type: (Any) -> bool | |
| 676 try: | |
| 677 if data.anchor is not None and data.anchor.value is not None: | |
| 678 return False | |
| 679 except AttributeError: | |
| 680 pass | |
| 681 return SafeRepresenter.ignore_aliases(self, data) | |
| 682 | |
| 683 def represent_none(self, data): | |
| 684 # type: (Any) -> Any | |
| 685 if len(self.represented_objects) == 0 and not self.serializer.use_explicit_start: | |
| 686 # this will be open ended (although it is not yet) | |
| 687 return self.represent_scalar(u'tag:yaml.org,2002:null', u'null') | |
| 688 return self.represent_scalar(u'tag:yaml.org,2002:null', "") | |
| 689 | |
| 690 def represent_literal_scalarstring(self, data): | |
| 691 # type: (Any) -> Any | |
| 692 tag = None | |
| 693 style = '|' | |
| 694 anchor = data.yaml_anchor(any=True) | |
| 695 if PY2 and not isinstance(data, unicode): | |
| 696 data = unicode(data, 'ascii') | |
| 697 tag = u'tag:yaml.org,2002:str' | |
| 698 return self.represent_scalar(tag, data, style=style, anchor=anchor) | |
| 699 | |
| 700 represent_preserved_scalarstring = represent_literal_scalarstring | |
| 701 | |
| 702 def represent_folded_scalarstring(self, data): | |
| 703 # type: (Any) -> Any | |
| 704 tag = None | |
| 705 style = '>' | |
| 706 anchor = data.yaml_anchor(any=True) | |
| 707 for fold_pos in reversed(getattr(data, 'fold_pos', [])): | |
| 708 if ( | |
| 709 data[fold_pos] == ' ' | |
| 710 and (fold_pos > 0 and not data[fold_pos - 1].isspace()) | |
| 711 and (fold_pos < len(data) and not data[fold_pos + 1].isspace()) | |
| 712 ): | |
| 713 data = data[:fold_pos] + '\a' + data[fold_pos:] | |
| 714 if PY2 and not isinstance(data, unicode): | |
| 715 data = unicode(data, 'ascii') | |
| 716 tag = u'tag:yaml.org,2002:str' | |
| 717 return self.represent_scalar(tag, data, style=style, anchor=anchor) | |
| 718 | |
| 719 def represent_single_quoted_scalarstring(self, data): | |
| 720 # type: (Any) -> Any | |
| 721 tag = None | |
| 722 style = "'" | |
| 723 anchor = data.yaml_anchor(any=True) | |
| 724 if PY2 and not isinstance(data, unicode): | |
| 725 data = unicode(data, 'ascii') | |
| 726 tag = u'tag:yaml.org,2002:str' | |
| 727 return self.represent_scalar(tag, data, style=style, anchor=anchor) | |
| 728 | |
| 729 def represent_double_quoted_scalarstring(self, data): | |
| 730 # type: (Any) -> Any | |
| 731 tag = None | |
| 732 style = '"' | |
| 733 anchor = data.yaml_anchor(any=True) | |
| 734 if PY2 and not isinstance(data, unicode): | |
| 735 data = unicode(data, 'ascii') | |
| 736 tag = u'tag:yaml.org,2002:str' | |
| 737 return self.represent_scalar(tag, data, style=style, anchor=anchor) | |
| 738 | |
| 739 def represent_plain_scalarstring(self, data): | |
| 740 # type: (Any) -> Any | |
| 741 tag = None | |
| 742 style = '' | |
| 743 anchor = data.yaml_anchor(any=True) | |
| 744 if PY2 and not isinstance(data, unicode): | |
| 745 data = unicode(data, 'ascii') | |
| 746 tag = u'tag:yaml.org,2002:str' | |
| 747 return self.represent_scalar(tag, data, style=style, anchor=anchor) | |
| 748 | |
| 749 def insert_underscore(self, prefix, s, underscore, anchor=None): | |
| 750 # type: (Any, Any, Any, Any) -> Any | |
| 751 if underscore is None: | |
| 752 return self.represent_scalar(u'tag:yaml.org,2002:int', prefix + s, anchor=anchor) | |
| 753 if underscore[0]: | |
| 754 sl = list(s) | |
| 755 pos = len(s) - underscore[0] | |
| 756 while pos > 0: | |
| 757 sl.insert(pos, '_') | |
| 758 pos -= underscore[0] | |
| 759 s = "".join(sl) | |
| 760 if underscore[1]: | |
| 761 s = '_' + s | |
| 762 if underscore[2]: | |
| 763 s += '_' | |
| 764 return self.represent_scalar(u'tag:yaml.org,2002:int', prefix + s, anchor=anchor) | |
| 765 | |
| 766 def represent_scalar_int(self, data): | |
| 767 # type: (Any) -> Any | |
| 768 if data._width is not None: | |
| 769 s = '{:0{}d}'.format(data, data._width) | |
| 770 else: | |
| 771 s = format(data, 'd') | |
| 772 anchor = data.yaml_anchor(any=True) | |
| 773 return self.insert_underscore("", s, data._underscore, anchor=anchor) | |
| 774 | |
| 775 def represent_binary_int(self, data): | |
| 776 # type: (Any) -> Any | |
| 777 if data._width is not None: | |
| 778 # cannot use '{:#0{}b}', that strips the zeros | |
| 779 s = '{:0{}b}'.format(data, data._width) | |
| 780 else: | |
| 781 s = format(data, 'b') | |
| 782 anchor = data.yaml_anchor(any=True) | |
| 783 return self.insert_underscore('0b', s, data._underscore, anchor=anchor) | |
| 784 | |
| 785 def represent_octal_int(self, data): | |
| 786 # type: (Any) -> Any | |
| 787 if data._width is not None: | |
| 788 # cannot use '{:#0{}o}', that strips the zeros | |
| 789 s = '{:0{}o}'.format(data, data._width) | |
| 790 else: | |
| 791 s = format(data, 'o') | |
| 792 anchor = data.yaml_anchor(any=True) | |
| 793 return self.insert_underscore('0o', s, data._underscore, anchor=anchor) | |
| 794 | |
| 795 def represent_hex_int(self, data): | |
| 796 # type: (Any) -> Any | |
| 797 if data._width is not None: | |
| 798 # cannot use '{:#0{}x}', that strips the zeros | |
| 799 s = '{:0{}x}'.format(data, data._width) | |
| 800 else: | |
| 801 s = format(data, 'x') | |
| 802 anchor = data.yaml_anchor(any=True) | |
| 803 return self.insert_underscore('0x', s, data._underscore, anchor=anchor) | |
| 804 | |
| 805 def represent_hex_caps_int(self, data): | |
| 806 # type: (Any) -> Any | |
| 807 if data._width is not None: | |
| 808 # cannot use '{:#0{}X}', that strips the zeros | |
| 809 s = '{:0{}X}'.format(data, data._width) | |
| 810 else: | |
| 811 s = format(data, 'X') | |
| 812 anchor = data.yaml_anchor(any=True) | |
| 813 return self.insert_underscore('0x', s, data._underscore, anchor=anchor) | |
| 814 | |
| 815 def represent_scalar_float(self, data): | |
| 816 # type: (Any) -> Any | |
| 817 """ this is way more complicated """ | |
| 818 value = None | |
| 819 anchor = data.yaml_anchor(any=True) | |
| 820 if data != data or (data == 0.0 and data == 1.0): | |
| 821 value = u'.nan' | |
| 822 elif data == self.inf_value: | |
| 823 value = u'.inf' | |
| 824 elif data == -self.inf_value: | |
| 825 value = u'-.inf' | |
| 826 if value: | |
| 827 return self.represent_scalar(u'tag:yaml.org,2002:float', value, anchor=anchor) | |
| 828 if data._exp is None and data._prec > 0 and data._prec == data._width - 1: | |
| 829 # no exponent, but trailing dot | |
| 830 value = u'{}{:d}.'.format(data._m_sign if data._m_sign else "", abs(int(data))) | |
| 831 elif data._exp is None: | |
| 832 # no exponent, "normal" dot | |
| 833 prec = data._prec | |
| 834 ms = data._m_sign if data._m_sign else "" | |
| 835 # -1 for the dot | |
| 836 value = u'{}{:0{}.{}f}'.format( | |
| 837 ms, abs(data), data._width - len(ms), data._width - prec - 1 | |
| 838 ) | |
| 839 if prec == 0 or (prec == 1 and ms != ""): | |
| 840 value = value.replace(u'0.', u'.') | |
| 841 while len(value) < data._width: | |
| 842 value += u'0' | |
| 843 else: | |
| 844 # exponent | |
| 845 m, es = u'{:{}.{}e}'.format( | |
| 846 # data, data._width, data._width - data._prec + (1 if data._m_sign else 0) | |
| 847 data, | |
| 848 data._width, | |
| 849 data._width + (1 if data._m_sign else 0), | |
| 850 ).split('e') | |
| 851 w = data._width if data._prec > 0 else (data._width + 1) | |
| 852 if data < 0: | |
| 853 w += 1 | |
| 854 m = m[:w] | |
| 855 e = int(es) | |
| 856 m1, m2 = m.split('.') # always second? | |
| 857 while len(m1) + len(m2) < data._width - (1 if data._prec >= 0 else 0): | |
| 858 m2 += u'0' | |
| 859 if data._m_sign and data > 0: | |
| 860 m1 = '+' + m1 | |
| 861 esgn = u'+' if data._e_sign else "" | |
| 862 if data._prec < 0: # mantissa without dot | |
| 863 if m2 != u'0': | |
| 864 e -= len(m2) | |
| 865 else: | |
| 866 m2 = "" | |
| 867 while (len(m1) + len(m2) - (1 if data._m_sign else 0)) < data._width: | |
| 868 m2 += u'0' | |
| 869 e -= 1 | |
| 870 value = m1 + m2 + data._exp + u'{:{}0{}d}'.format(e, esgn, data._e_width) | |
| 871 elif data._prec == 0: # mantissa with trailing dot | |
| 872 e -= len(m2) | |
| 873 value = ( | |
| 874 m1 + m2 + u'.' + data._exp + u'{:{}0{}d}'.format(e, esgn, data._e_width) | |
| 875 ) | |
| 876 else: | |
| 877 if data._m_lead0 > 0: | |
| 878 m2 = u'0' * (data._m_lead0 - 1) + m1 + m2 | |
| 879 m1 = u'0' | |
| 880 m2 = m2[: -data._m_lead0] # these should be zeros | |
| 881 e += data._m_lead0 | |
| 882 while len(m1) < data._prec: | |
| 883 m1 += m2[0] | |
| 884 m2 = m2[1:] | |
| 885 e -= 1 | |
| 886 value = ( | |
| 887 m1 + u'.' + m2 + data._exp + u'{:{}0{}d}'.format(e, esgn, data._e_width) | |
| 888 ) | |
| 889 | |
| 890 if value is None: | |
| 891 value = to_unicode(repr(data)).lower() | |
| 892 return self.represent_scalar(u'tag:yaml.org,2002:float', value, anchor=anchor) | |
| 893 | |
| 894 def represent_sequence(self, tag, sequence, flow_style=None): | |
| 895 # type: (Any, Any, Any) -> Any | |
| 896 value = [] # type: List[Any] | |
| 897 # if the flow_style is None, the flow style tacked on to the object | |
| 898 # explicitly will be taken. If that is None as well the default flow | |
| 899 # style rules | |
| 900 try: | |
| 901 flow_style = sequence.fa.flow_style(flow_style) | |
| 902 except AttributeError: | |
| 903 flow_style = flow_style | |
| 904 try: | |
| 905 anchor = sequence.yaml_anchor() | |
| 906 except AttributeError: | |
| 907 anchor = None | |
| 908 node = SequenceNode(tag, value, flow_style=flow_style, anchor=anchor) | |
| 909 if self.alias_key is not None: | |
| 910 self.represented_objects[self.alias_key] = node | |
| 911 best_style = True | |
| 912 try: | |
| 913 comment = getattr(sequence, comment_attrib) | |
| 914 node.comment = comment.comment | |
| 915 # reset any comment already printed information | |
| 916 if node.comment and node.comment[1]: | |
| 917 for ct in node.comment[1]: | |
| 918 ct.reset() | |
| 919 item_comments = comment.items | |
| 920 for v in item_comments.values(): | |
| 921 if v and v[1]: | |
| 922 for ct in v[1]: | |
| 923 ct.reset() | |
| 924 item_comments = comment.items | |
| 925 node.comment = comment.comment | |
| 926 try: | |
| 927 node.comment.append(comment.end) | |
| 928 except AttributeError: | |
| 929 pass | |
| 930 except AttributeError: | |
| 931 item_comments = {} | |
| 932 for idx, item in enumerate(sequence): | |
| 933 node_item = self.represent_data(item) | |
| 934 self.merge_comments(node_item, item_comments.get(idx)) | |
| 935 if not (isinstance(node_item, ScalarNode) and not node_item.style): | |
| 936 best_style = False | |
| 937 value.append(node_item) | |
| 938 if flow_style is None: | |
| 939 if len(sequence) != 0 and self.default_flow_style is not None: | |
| 940 node.flow_style = self.default_flow_style | |
| 941 else: | |
| 942 node.flow_style = best_style | |
| 943 return node | |
| 944 | |
| 945 def merge_comments(self, node, comments): | |
| 946 # type: (Any, Any) -> Any | |
| 947 if comments is None: | |
| 948 assert hasattr(node, 'comment') | |
| 949 return node | |
| 950 if getattr(node, 'comment', None) is not None: | |
| 951 for idx, val in enumerate(comments): | |
| 952 if idx >= len(node.comment): | |
| 953 continue | |
| 954 nc = node.comment[idx] | |
| 955 if nc is not None: | |
| 956 assert val is None or val == nc | |
| 957 comments[idx] = nc | |
| 958 node.comment = comments | |
| 959 return node | |
| 960 | |
| 961 def represent_key(self, data): | |
| 962 # type: (Any) -> Any | |
| 963 if isinstance(data, CommentedKeySeq): | |
| 964 self.alias_key = None | |
| 965 return self.represent_sequence(u'tag:yaml.org,2002:seq', data, flow_style=True) | |
| 966 if isinstance(data, CommentedKeyMap): | |
| 967 self.alias_key = None | |
| 968 return self.represent_mapping(u'tag:yaml.org,2002:map', data, flow_style=True) | |
| 969 return SafeRepresenter.represent_key(self, data) | |
| 970 | |
| 971 def represent_mapping(self, tag, mapping, flow_style=None): | |
| 972 # type: (Any, Any, Any) -> Any | |
| 973 value = [] # type: List[Any] | |
| 974 try: | |
| 975 flow_style = mapping.fa.flow_style(flow_style) | |
| 976 except AttributeError: | |
| 977 flow_style = flow_style | |
| 978 try: | |
| 979 anchor = mapping.yaml_anchor() | |
| 980 except AttributeError: | |
| 981 anchor = None | |
| 982 node = MappingNode(tag, value, flow_style=flow_style, anchor=anchor) | |
| 983 if self.alias_key is not None: | |
| 984 self.represented_objects[self.alias_key] = node | |
| 985 best_style = True | |
| 986 # no sorting! !! | |
| 987 try: | |
| 988 comment = getattr(mapping, comment_attrib) | |
| 989 node.comment = comment.comment | |
| 990 if node.comment and node.comment[1]: | |
| 991 for ct in node.comment[1]: | |
| 992 ct.reset() | |
| 993 item_comments = comment.items | |
| 994 for v in item_comments.values(): | |
| 995 if v and v[1]: | |
| 996 for ct in v[1]: | |
| 997 ct.reset() | |
| 998 try: | |
| 999 node.comment.append(comment.end) | |
| 1000 except AttributeError: | |
| 1001 pass | |
| 1002 except AttributeError: | |
| 1003 item_comments = {} | |
| 1004 merge_list = [m[1] for m in getattr(mapping, merge_attrib, [])] | |
| 1005 try: | |
| 1006 merge_pos = getattr(mapping, merge_attrib, [[0]])[0][0] | |
| 1007 except IndexError: | |
| 1008 merge_pos = 0 | |
| 1009 item_count = 0 | |
| 1010 if bool(merge_list): | |
| 1011 items = mapping.non_merged_items() | |
| 1012 else: | |
| 1013 items = mapping.items() | |
| 1014 for item_key, item_value in items: | |
| 1015 item_count += 1 | |
| 1016 node_key = self.represent_key(item_key) | |
| 1017 node_value = self.represent_data(item_value) | |
| 1018 item_comment = item_comments.get(item_key) | |
| 1019 if item_comment: | |
| 1020 assert getattr(node_key, 'comment', None) is None | |
| 1021 node_key.comment = item_comment[:2] | |
| 1022 nvc = getattr(node_value, 'comment', None) | |
| 1023 if nvc is not None: # end comment already there | |
| 1024 nvc[0] = item_comment[2] | |
| 1025 nvc[1] = item_comment[3] | |
| 1026 else: | |
| 1027 node_value.comment = item_comment[2:] | |
| 1028 if not (isinstance(node_key, ScalarNode) and not node_key.style): | |
| 1029 best_style = False | |
| 1030 if not (isinstance(node_value, ScalarNode) and not node_value.style): | |
| 1031 best_style = False | |
| 1032 value.append((node_key, node_value)) | |
| 1033 if flow_style is None: | |
| 1034 if ((item_count != 0) or bool(merge_list)) and self.default_flow_style is not None: | |
| 1035 node.flow_style = self.default_flow_style | |
| 1036 else: | |
| 1037 node.flow_style = best_style | |
| 1038 if bool(merge_list): | |
| 1039 # because of the call to represent_data here, the anchors | |
| 1040 # are marked as being used and thereby created | |
| 1041 if len(merge_list) == 1: | |
| 1042 arg = self.represent_data(merge_list[0]) | |
| 1043 else: | |
| 1044 arg = self.represent_data(merge_list) | |
| 1045 arg.flow_style = True | |
| 1046 value.insert(merge_pos, (ScalarNode(u'tag:yaml.org,2002:merge', '<<'), arg)) | |
| 1047 return node | |
| 1048 | |
| 1049 def represent_omap(self, tag, omap, flow_style=None): | |
| 1050 # type: (Any, Any, Any) -> Any | |
| 1051 value = [] # type: List[Any] | |
| 1052 try: | |
| 1053 flow_style = omap.fa.flow_style(flow_style) | |
| 1054 except AttributeError: | |
| 1055 flow_style = flow_style | |
| 1056 try: | |
| 1057 anchor = omap.yaml_anchor() | |
| 1058 except AttributeError: | |
| 1059 anchor = None | |
| 1060 node = SequenceNode(tag, value, flow_style=flow_style, anchor=anchor) | |
| 1061 if self.alias_key is not None: | |
| 1062 self.represented_objects[self.alias_key] = node | |
| 1063 best_style = True | |
| 1064 try: | |
| 1065 comment = getattr(omap, comment_attrib) | |
| 1066 node.comment = comment.comment | |
| 1067 if node.comment and node.comment[1]: | |
| 1068 for ct in node.comment[1]: | |
| 1069 ct.reset() | |
| 1070 item_comments = comment.items | |
| 1071 for v in item_comments.values(): | |
| 1072 if v and v[1]: | |
| 1073 for ct in v[1]: | |
| 1074 ct.reset() | |
| 1075 try: | |
| 1076 node.comment.append(comment.end) | |
| 1077 except AttributeError: | |
| 1078 pass | |
| 1079 except AttributeError: | |
| 1080 item_comments = {} | |
| 1081 for item_key in omap: | |
| 1082 item_val = omap[item_key] | |
| 1083 node_item = self.represent_data({item_key: item_val}) | |
| 1084 # node_item.flow_style = False | |
| 1085 # node item has two scalars in value: node_key and node_value | |
| 1086 item_comment = item_comments.get(item_key) | |
| 1087 if item_comment: | |
| 1088 if item_comment[1]: | |
| 1089 node_item.comment = [None, item_comment[1]] | |
| 1090 assert getattr(node_item.value[0][0], 'comment', None) is None | |
| 1091 node_item.value[0][0].comment = [item_comment[0], None] | |
| 1092 nvc = getattr(node_item.value[0][1], 'comment', None) | |
| 1093 if nvc is not None: # end comment already there | |
| 1094 nvc[0] = item_comment[2] | |
| 1095 nvc[1] = item_comment[3] | |
| 1096 else: | |
| 1097 node_item.value[0][1].comment = item_comment[2:] | |
| 1098 # if not (isinstance(node_item, ScalarNode) \ | |
| 1099 # and not node_item.style): | |
| 1100 # best_style = False | |
| 1101 value.append(node_item) | |
| 1102 if flow_style is None: | |
| 1103 if self.default_flow_style is not None: | |
| 1104 node.flow_style = self.default_flow_style | |
| 1105 else: | |
| 1106 node.flow_style = best_style | |
| 1107 return node | |
| 1108 | |
| 1109 def represent_set(self, setting): | |
| 1110 # type: (Any) -> Any | |
| 1111 flow_style = False | |
| 1112 tag = u'tag:yaml.org,2002:set' | |
| 1113 # return self.represent_mapping(tag, value) | |
| 1114 value = [] # type: List[Any] | |
| 1115 flow_style = setting.fa.flow_style(flow_style) | |
| 1116 try: | |
| 1117 anchor = setting.yaml_anchor() | |
| 1118 except AttributeError: | |
| 1119 anchor = None | |
| 1120 node = MappingNode(tag, value, flow_style=flow_style, anchor=anchor) | |
| 1121 if self.alias_key is not None: | |
| 1122 self.represented_objects[self.alias_key] = node | |
| 1123 best_style = True | |
| 1124 # no sorting! !! | |
| 1125 try: | |
| 1126 comment = getattr(setting, comment_attrib) | |
| 1127 node.comment = comment.comment | |
| 1128 if node.comment and node.comment[1]: | |
| 1129 for ct in node.comment[1]: | |
| 1130 ct.reset() | |
| 1131 item_comments = comment.items | |
| 1132 for v in item_comments.values(): | |
| 1133 if v and v[1]: | |
| 1134 for ct in v[1]: | |
| 1135 ct.reset() | |
| 1136 try: | |
| 1137 node.comment.append(comment.end) | |
| 1138 except AttributeError: | |
| 1139 pass | |
| 1140 except AttributeError: | |
| 1141 item_comments = {} | |
| 1142 for item_key in setting.odict: | |
| 1143 node_key = self.represent_key(item_key) | |
| 1144 node_value = self.represent_data(None) | |
| 1145 item_comment = item_comments.get(item_key) | |
| 1146 if item_comment: | |
| 1147 assert getattr(node_key, 'comment', None) is None | |
| 1148 node_key.comment = item_comment[:2] | |
| 1149 node_key.style = node_value.style = '?' | |
| 1150 if not (isinstance(node_key, ScalarNode) and not node_key.style): | |
| 1151 best_style = False | |
| 1152 if not (isinstance(node_value, ScalarNode) and not node_value.style): | |
| 1153 best_style = False | |
| 1154 value.append((node_key, node_value)) | |
| 1155 best_style = best_style | |
| 1156 return node | |
| 1157 | |
| 1158 def represent_dict(self, data): | |
| 1159 # type: (Any) -> Any | |
| 1160 """write out tag if saved on loading""" | |
| 1161 try: | |
| 1162 t = data.tag.value | |
| 1163 except AttributeError: | |
| 1164 t = None | |
| 1165 if t: | |
| 1166 if t.startswith('!!'): | |
| 1167 tag = 'tag:yaml.org,2002:' + t[2:] | |
| 1168 else: | |
| 1169 tag = t | |
| 1170 else: | |
| 1171 tag = u'tag:yaml.org,2002:map' | |
| 1172 return self.represent_mapping(tag, data) | |
| 1173 | |
| 1174 def represent_list(self, data): | |
| 1175 # type: (Any) -> Any | |
| 1176 try: | |
| 1177 t = data.tag.value | |
| 1178 except AttributeError: | |
| 1179 t = None | |
| 1180 if t: | |
| 1181 if t.startswith('!!'): | |
| 1182 tag = 'tag:yaml.org,2002:' + t[2:] | |
| 1183 else: | |
| 1184 tag = t | |
| 1185 else: | |
| 1186 tag = u'tag:yaml.org,2002:seq' | |
| 1187 return self.represent_sequence(tag, data) | |
| 1188 | |
| 1189 def represent_datetime(self, data): | |
| 1190 # type: (Any) -> Any | |
| 1191 inter = 'T' if data._yaml['t'] else ' ' | |
| 1192 _yaml = data._yaml | |
| 1193 if _yaml['delta']: | |
| 1194 data += _yaml['delta'] | |
| 1195 value = data.isoformat(inter) | |
| 1196 else: | |
| 1197 value = data.isoformat(inter) | |
| 1198 if _yaml['tz']: | |
| 1199 value += _yaml['tz'] | |
| 1200 return self.represent_scalar(u'tag:yaml.org,2002:timestamp', to_unicode(value)) | |
| 1201 | |
| 1202 def represent_tagged_scalar(self, data): | |
| 1203 # type: (Any) -> Any | |
| 1204 try: | |
| 1205 tag = data.tag.value | |
| 1206 except AttributeError: | |
| 1207 tag = None | |
| 1208 try: | |
| 1209 anchor = data.yaml_anchor() | |
| 1210 except AttributeError: | |
| 1211 anchor = None | |
| 1212 return self.represent_scalar(tag, data.value, style=data.style, anchor=anchor) | |
| 1213 | |
| 1214 def represent_scalar_bool(self, data): | |
| 1215 # type: (Any) -> Any | |
| 1216 try: | |
| 1217 anchor = data.yaml_anchor() | |
| 1218 except AttributeError: | |
| 1219 anchor = None | |
| 1220 return SafeRepresenter.represent_bool(self, data, anchor=anchor) | |
| 1221 | |
| 1222 | |
| 1223 RoundTripRepresenter.add_representer(type(None), RoundTripRepresenter.represent_none) | |
| 1224 | |
| 1225 RoundTripRepresenter.add_representer( | |
| 1226 LiteralScalarString, RoundTripRepresenter.represent_literal_scalarstring | |
| 1227 ) | |
| 1228 | |
| 1229 RoundTripRepresenter.add_representer( | |
| 1230 FoldedScalarString, RoundTripRepresenter.represent_folded_scalarstring | |
| 1231 ) | |
| 1232 | |
| 1233 RoundTripRepresenter.add_representer( | |
| 1234 SingleQuotedScalarString, RoundTripRepresenter.represent_single_quoted_scalarstring | |
| 1235 ) | |
| 1236 | |
| 1237 RoundTripRepresenter.add_representer( | |
| 1238 DoubleQuotedScalarString, RoundTripRepresenter.represent_double_quoted_scalarstring | |
| 1239 ) | |
| 1240 | |
| 1241 RoundTripRepresenter.add_representer( | |
| 1242 PlainScalarString, RoundTripRepresenter.represent_plain_scalarstring | |
| 1243 ) | |
| 1244 | |
| 1245 RoundTripRepresenter.add_representer(ScalarInt, RoundTripRepresenter.represent_scalar_int) | |
| 1246 | |
| 1247 RoundTripRepresenter.add_representer(BinaryInt, RoundTripRepresenter.represent_binary_int) | |
| 1248 | |
| 1249 RoundTripRepresenter.add_representer(OctalInt, RoundTripRepresenter.represent_octal_int) | |
| 1250 | |
| 1251 RoundTripRepresenter.add_representer(HexInt, RoundTripRepresenter.represent_hex_int) | |
| 1252 | |
| 1253 RoundTripRepresenter.add_representer(HexCapsInt, RoundTripRepresenter.represent_hex_caps_int) | |
| 1254 | |
| 1255 RoundTripRepresenter.add_representer(ScalarFloat, RoundTripRepresenter.represent_scalar_float) | |
| 1256 | |
| 1257 RoundTripRepresenter.add_representer(ScalarBoolean, RoundTripRepresenter.represent_scalar_bool) | |
| 1258 | |
| 1259 RoundTripRepresenter.add_representer(CommentedSeq, RoundTripRepresenter.represent_list) | |
| 1260 | |
| 1261 RoundTripRepresenter.add_representer(CommentedMap, RoundTripRepresenter.represent_dict) | |
| 1262 | |
| 1263 RoundTripRepresenter.add_representer( | |
| 1264 CommentedOrderedMap, RoundTripRepresenter.represent_ordereddict | |
| 1265 ) | |
| 1266 | |
| 1267 if sys.version_info >= (2, 7): | |
| 1268 import collections | |
| 1269 | |
| 1270 RoundTripRepresenter.add_representer( | |
| 1271 collections.OrderedDict, RoundTripRepresenter.represent_ordereddict | |
| 1272 ) | |
| 1273 | |
| 1274 RoundTripRepresenter.add_representer(CommentedSet, RoundTripRepresenter.represent_set) | |
| 1275 | |
| 1276 RoundTripRepresenter.add_representer( | |
| 1277 TaggedScalar, RoundTripRepresenter.represent_tagged_scalar | |
| 1278 ) | |
| 1279 | |
| 1280 RoundTripRepresenter.add_representer(TimeStamp, RoundTripRepresenter.represent_datetime) |
