summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES4
-rw-r--r--__init__.py2
-rw-r--r--_doc/example.rst31
-rw-r--r--_test/test_comments.py49
-rw-r--r--comments.py8
-rw-r--r--compat.py15
6 files changed, 106 insertions, 3 deletions
diff --git a/CHANGES b/CHANGES
index 1a14444..50c7e6f 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,8 @@
+0.11.10 2016-05-02
+
+- added .insert(pos, key, value, comment=None) to CommentedMap
+
0.11.10 2016-04-19
- indent=2, block_seq_indent=2 works as expected
diff --git a/__init__.py b/__init__.py
index 7a0c6f0..9be2082 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, 11, 10),
+ version_info=(0, 11, 11),
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/_doc/example.rst b/_doc/example.rst
index 8bf9c6a..4e8ac4a 100644
--- a/_doc/example.rst
+++ b/_doc/example.rst
@@ -34,9 +34,10 @@ Resulting in ::
.. example output small.py
+----
YAML handcrafted anchors and references as well as key merging
-is preserved. The merged keys can transparently be accessed
+are preserved. The merged keys can transparently be accessed
using ``[]`` and ``.get()``::
import ruamel.yaml
@@ -71,3 +72,31 @@ using ``[]`` and ``.get()``::
.. example code anchor_merge.py
+----
+
+The ``CommentedMap``, which is the ``dict`` like construct one gets when round-trip loading,
+supports insertion of a key into a particular position, while optionally adding a comment::
+
+ yaml_str = """\
+ first_name: Art
+ occupation: Architect # This is an occupation comment
+ about: Art Vandelay is a fictional character that George invents...
+ """
+
+ data = ruamel.yaml.round_trip_load(yaml_str)
+ data.insert(1, 'last name', 'Vandelay', comment="new key")
+ print(ruamel.yaml.round_trip_dump(data))
+
+gives::
+
+ first_name: Art
+ last name: Vandelay # new key
+ occupation: Architect # This is an occupation comment
+ about: Art Vandelay is a fictional character that George invents...
+
+Please note that the comment is aligned with that of its neighbour (if available).
+
+The above was inspired by a `question <http://stackoverflow.com/a/36970608/1307905>`_
+posted by *demux* on StackOverflow.
+
+
diff --git a/_test/test_comments.py b/_test/test_comments.py
index ffe0b04..b6b12e2 100644
--- a/_test/test_comments.py
+++ b/_test/test_comments.py
@@ -423,3 +423,52 @@ class TestInsertPopList:
- 1
- 2
""")
+
+
+# inspired by demux' question on stackoverflow
+# http://stackoverflow.com/a/36970608/1307905
+class TestInsertInMapping:
+ @property
+ def ins(self):
+ return """\
+ first_name: Art
+ occupation: Architect # This is an occupation comment
+ about: Art Vandelay is a fictional character that George invents...
+ """
+
+ def test_insert_at_pos_1(self):
+ d = round_trip_load(self.ins)
+ d.insert(1, 'last name', 'Vandelay', comment="new key")
+ y = round_trip_dump(d)
+ print(y)
+ assert y == dedent("""\
+ first_name: Art
+ last name: Vandelay # new key
+ occupation: Architect # This is an occupation comment
+ about: Art Vandelay is a fictional character that George invents...
+ """)
+
+ def test_insert_at_pos_0(self):
+ d = round_trip_load(self.ins)
+ d.insert(0, 'last name', 'Vandelay', comment="new key")
+ y = round_trip_dump(d)
+ print(y)
+ assert y == dedent("""\
+ last name: Vandelay # new key
+ first_name: Art
+ occupation: Architect # This is an occupation comment
+ about: Art Vandelay is a fictional character that George invents...
+ """)
+
+ def test_insert_at_pos_3(self):
+ # much more simple if done with appending.
+ d = round_trip_load(self.ins)
+ d.insert(3, 'last name', 'Vandelay', comment="new key")
+ y = round_trip_dump(d)
+ print(y)
+ assert y == dedent("""\
+ first_name: Art
+ occupation: Architect # This is an occupation comment
+ about: Art Vandelay is a fictional character that George invents...
+ last name: Vandelay # new key
+ """)
diff --git a/comments.py b/comments.py
index 8e5ebb8..4a99931 100644
--- a/comments.py
+++ b/comments.py
@@ -389,6 +389,14 @@ class CommentedMap(ordereddict, CommentedBase):
for x in vals:
self[x] = vals[x]
+ def insert(self, pos, key, value, comment=None):
+ """insert key value into given position
+ attach comment if provided
+ """
+ ordereddict.insert(self, pos, key, value)
+ if comment is not None:
+ self.yaml_add_eol_comment(comment, key=key)
+
def mlget(self, key, default=None, list_ok=False):
"""multi-level get that expects dicts within dicts"""
if not isinstance(key, list):
diff --git a/compat.py b/compat.py
index 8120a4e..abd10ac 100644
--- a/compat.py
+++ b/compat.py
@@ -18,7 +18,20 @@ except:
# to get the right name import ... as ordereddict doesn't do that
class ordereddict(OrderedDict):
- pass
+ if not hasattr(OrderedDict, 'insert'):
+ def insert(self, pos, key, value):
+ if pos >= len(self):
+ self[key] = value
+ return
+ od = ordereddict()
+ od.update(self)
+ for k in od:
+ del self[k]
+ for index, old_key in enumerate(od):
+ if pos == index:
+ self[key] = value
+ self[old_key] = od[old_key]
+
PY2 = sys.version_info[0] == 2
PY3 = sys.version_info[0] == 3