summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnthon van der Neut <anthon@mnt.org>2016-09-21 10:09:18 +0200
committerAnthon van der Neut <anthon@mnt.org>2016-09-21 10:09:18 +0200
commite08dd6b761c0b45a486beddcab67389830882b4f (patch)
tree8eef084d547c32984e590790888dba3c712a9553
parent4e855c8f3f6b2def2b2953e7bcd1ff07e35e42ed (diff)
downloadruamel.yaml-e08dd6b761c0b45a486beddcab67389830882b4f.tar.gz
round-trip sequence key elements0.12.14
-rw-r--r--README.rst4
-rw-r--r--__init__.py2
-rw-r--r--_test/roundtrip.py13
-rw-r--r--_test/test_flowsequencekey.py25
-rw-r--r--comments.py47
-rw-r--r--constructor.py7
-rw-r--r--emitter.py7
-rw-r--r--representer.py10
8 files changed, 102 insertions, 13 deletions
diff --git a/README.rst b/README.rst
index 4203014..5418ead 100644
--- a/README.rst
+++ b/README.rst
@@ -18,6 +18,10 @@ ChangeLog
::
+ 0.12.14 (2016-09-21):
+ - preserve round-trip sequences that are mapping keys
+ (prompted by stackoverflow question 39595807 from Nowox)
+
0.12.13 (2016-09-15):
- Fix for issue #60 representation of CommentedMap with merge
keys incorrect (reported by Tal Liron)
diff --git a/__init__.py b/__init__.py
index 15b8eff..15142b6 100644
--- a/__init__.py
+++ b/__init__.py
@@ -9,7 +9,7 @@ from __future__ import absolute_import
_package_data = dict(
full_package_name="ruamel.yaml",
- version_info=(0, 12, 13),
+ version_info=(0, 12, 14),
author="Anthon van der Neut",
author_email="a.van.der.neut@ruamel.eu",
description="ruamel.yaml is a YAML parser/emitter that supports roundtrip preservation of comments, seq/map flow style, and map key order", # NOQA
diff --git a/_test/roundtrip.py b/_test/roundtrip.py
index 632c206..cd79f2c 100644
--- a/_test/roundtrip.py
+++ b/_test/roundtrip.py
@@ -28,18 +28,19 @@ def round_trip_load(inp, preserve_quotes=None):
def round_trip_dump(data, indent=None, block_seq_indent=None, top_level_colon_align=None,
- prefix_colon=None, explicit_start=None, explicit_end=None):
+ prefix_colon=None, explicit_start=None, explicit_end=None, version=None):
return ruamel.yaml.round_trip_dump(data,
indent=indent, block_seq_indent=block_seq_indent,
top_level_colon_align=top_level_colon_align,
prefix_colon=prefix_colon,
explicit_start=explicit_start,
- explicit_end=explicit_end)
+ explicit_end=explicit_end,
+ version=version)
def round_trip(inp, outp=None, extra=None, intermediate=None, indent=None,
block_seq_indent=None, top_level_colon_align=None, prefix_colon=None,
- preserve_quotes=None):
+ preserve_quotes=None, explicit_start=None, version=None):
"""
inp: input string to parse
outp: expected output (equals input if not specified)
@@ -58,11 +59,13 @@ def round_trip(inp, outp=None, extra=None, intermediate=None, indent=None,
raise ValueError
res = round_trip_dump(data, indent=indent, block_seq_indent=block_seq_indent,
top_level_colon_align=top_level_colon_align,
- prefix_colon=prefix_colon)
+ prefix_colon=prefix_colon, explicit_start=explicit_start,
+ version=version)
print('roundtrip data:\n', res, sep='')
assert res == doutp
res = round_trip_dump(data, indent=indent, block_seq_indent=block_seq_indent,
top_level_colon_align=top_level_colon_align,
- prefix_colon=prefix_colon)
+ prefix_colon=prefix_colon, explicit_start=explicit_start,
+ version=version)
print('roundtrip second round data:\n', res, sep='')
assert res == doutp
diff --git a/_test/test_flowsequencekey.py b/_test/test_flowsequencekey.py
new file mode 100644
index 0000000..6f6d7db
--- /dev/null
+++ b/_test/test_flowsequencekey.py
@@ -0,0 +1,25 @@
+# coding: utf-8
+
+"""
+test flow style sequences as keys roundtrip
+
+"""
+
+# import pytest
+# import ruamel.yaml
+
+from roundtrip import round_trip # , dedent, round_trip_load, round_trip_dump
+
+
+class TestFlowStyleSequenceKey:
+ def test_so_39595807(self):
+ round_trip("""
+ %YAML 1.2
+ ---
+ [2, 3, 4]:
+ a:
+ - 1
+ - 2
+ b: Hello World!
+ c: 'VoilĂ !'
+ """, preserve_quotes=True, explicit_start=True, version=(1, 2))
diff --git a/comments.py b/comments.py
index 7dd8e8e..34154e8 100644
--- a/comments.py
+++ b/comments.py
@@ -12,7 +12,8 @@ from collections import MutableSet, Sized, Set # type: ignore
from ruamel.yaml.compat import ordereddict, PY2
-__all__ = ["CommentedSeq", "CommentedMap", "CommentedOrderedMap",
+__all__ = ["CommentedSeq", "CommentedKeySeq",
+ "CommentedMap", "CommentedOrderedMap",
"CommentedSet", 'comment_attrib', 'merge_attrib']
comment_attrib = '_yaml_comment'
@@ -321,8 +322,50 @@ class CommentedSeq(list, CommentedBase):
return pre_comments
-class CommentedMapView(Sized):
+class CommentedKeySeq(tuple, CommentedBase):
+ """This primarily exists to be able to roundtrip keys that are sequences"""
+ def _yaml_add_comment(self, comment, key=NoComment):
+ if key is not NoComment:
+ self.yaml_key_comment_extend(key, comment)
+ else:
+ self.ca.comment = comment
+
+ def _yaml_add_eol_comment(self, comment, key):
+ self._yaml_add_comment(comment, key=key)
+
+ def _yaml_get_columnX(self, key):
+ return self.ca.items[key][0].start_mark.column
+
+ def _yaml_get_column(self, key):
+ column = None
+ sel_idx = None
+ pre, post = key-1, key+1
+ if pre in self.ca.items:
+ sel_idx = pre
+ elif post in self.ca.items:
+ sel_idx = post
+ else:
+ # self.ca.items is not ordered
+ for row_idx, k1 in enumerate(self):
+ if row_idx >= key:
+ break
+ if row_idx not in self.ca.items:
+ continue
+ sel_idx = row_idx
+ if sel_idx is not None:
+ column = self._yaml_get_columnX(sel_idx)
+ return column
+ def _yaml_get_pre_comment(self):
+ if self.ca.comment is None:
+ pre_comments = []
+ self.ca.comment = [None, pre_comments]
+ else:
+ pre_comments = self.ca.comment[1] = []
+ return pre_comments
+
+
+class CommentedMapView(Sized):
__slots__ = '_mapping',
def __init__(self, mapping):
diff --git a/constructor.py b/constructor.py
index f2a6cc3..03c88ae 100644
--- a/constructor.py
+++ b/constructor.py
@@ -956,7 +956,12 @@ class RoundTripConstructor(SafeConstructor):
# lists are not hashable, but tuples are
if not isinstance(key, collections.Hashable):
if isinstance(key, list):
- key = tuple(key)
+ key = CommentedKeySeq(key)
+ if key_node.flow_style is True:
+ key.fa.set_flow_style()
+ elif key_node.flow_style is False:
+ key.fa.set_block_style()
+ # key = tuple(key)
if PY2:
try:
hash(key)
diff --git a/emitter.py b/emitter.py
index ac88dc6..497f173 100644
--- a/emitter.py
+++ b/emitter.py
@@ -465,8 +465,9 @@ class Emitter(object):
self.write_pre_comment(self.event)
self.write_indent()
if self.check_simple_key():
- if self.event.style == '?':
- self.write_indicator(u'?', True, indention=True)
+ if not isinstance(self.event, SequenceStartEvent): # sequence keys
+ if self.event.style == '?':
+ self.write_indicator(u'?', True, indention=True)
self.states.append(self.expect_block_mapping_simple_value)
self.expect_node(mapping=True, simple_key=True)
else:
@@ -526,6 +527,8 @@ class Emitter(object):
length += len(self.analysis.scalar)
return (length < self.MAX_SIMPLE_KEY_LENGTH and (
isinstance(self.event, AliasEvent) or
+ (isinstance(self.event, SequenceStartEvent) and
+ self.event.flow_style is True) or
(isinstance(self.event, ScalarEvent) and
not self.analysis.empty and not self.analysis.multiline) or
self.check_empty_sequence() or self.check_empty_mapping()))
diff --git a/representer.py b/representer.py
index 3e67a96..8fcbc7c 100644
--- a/representer.py
+++ b/representer.py
@@ -576,8 +576,8 @@ Representer.add_multi_representer(object,
Representer.represent_object)
-from ruamel.yaml.comments import CommentedMap, CommentedOrderedMap, \
- CommentedSeq, CommentedSet, comment_attrib, merge_attrib # NOQA
+from ruamel.yaml.comments import CommentedMap, CommentedOrderedMap, CommentedSeq, \
+ CommentedKeySeq, CommentedSet, comment_attrib, merge_attrib # NOQA
class RoundTripRepresenter(SafeRepresenter):
@@ -658,6 +658,12 @@ class RoundTripRepresenter(SafeRepresenter):
node.flow_style = best_style
return node
+ def represent_key(self, data):
+ if isinstance(data, CommentedKeySeq):
+ return self.represent_sequence(u'tag:yaml.org,2002:seq', data,
+ flow_style=True)
+ return SafeRepresenter.represent_key(self, data)
+
def represent_mapping(self, tag, mapping, flow_style=None):
value = []
try: