summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.rst5
-rw-r--r--__init__.py2
-rw-r--r--_test/test_copy.py118
-rw-r--r--comments.py26
-rw-r--r--configobjwalker.py2
-rw-r--r--tox.ini2
6 files changed, 151 insertions, 4 deletions
diff --git a/README.rst b/README.rst
index d346e4b..77d22bd 100644
--- a/README.rst
+++ b/README.rst
@@ -18,8 +18,11 @@ ChangeLog
.. should insert NEXT: at the beginning of line for next key
+0.13.5 (2016-12-25):
+ - fix for issue 84, deepcopy not properly workin (reported by Peter Amstutz)
+
0.13.4 (2016-12-05):
- - another fxi for issue 82, change to non-global resolver data broke implicit type
+ - another fix for issue 82, change to non-global resolver data broke implicit type
specification
0.13.3 (2016-12-05):
diff --git a/__init__.py b/__init__.py
index 508e2a2..29911ea 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, 13, 4),
+ version_info=(0, 13, 5),
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/test_copy.py b/_test/test_copy.py
new file mode 100644
index 0000000..37f978d
--- /dev/null
+++ b/_test/test_copy.py
@@ -0,0 +1,118 @@
+# coding: utf-8
+
+"""
+Testing copy and deepcopy, instigated by Issue 84 (Peter Amstutz)
+"""
+
+import copy
+
+import pytest # NOQA
+import ruamel.yaml # NOQA
+
+from roundtrip import dedent, round_trip_load, round_trip_dump
+
+
+class TestDeepCopy:
+ def test_preserve_flow_style_simple(self):
+ x = dedent("""\
+ {foo: bar, baz: quux}
+ """)
+ data = round_trip_load(x)
+ data_copy = copy.deepcopy(data)
+ y = round_trip_dump(data_copy)
+ print('x [{}]'.format(x))
+ print('y [{}]'.format(y))
+ assert y == x
+ assert data.fa.flow_style() == data_copy.fa.flow_style()
+
+ def test_deepcopy_flow_style_nested_dict(self):
+ x = dedent("""\
+ a: {foo: bar, baz: quux}
+ """)
+ data = round_trip_load(x)
+ assert data['a'].fa.flow_style() is True
+ data_copy = copy.deepcopy(data)
+ assert data_copy['a'].fa.flow_style() is True
+ data_copy['a'].fa.set_block_style()
+ assert data['a'].fa.flow_style() != data_copy['a'].fa.flow_style()
+ assert data['a'].fa._flow_style is True
+ assert data_copy['a'].fa._flow_style is False
+ y = round_trip_dump(data_copy)
+
+ print('x [{}]'.format(x))
+ print('y [{}]'.format(y))
+ assert y == dedent("""\
+ a:
+ foo: bar
+ baz: quux
+ """)
+
+ def test_deepcopy_flow_style_nested_list(self):
+ x = dedent("""\
+ a: [1, 2, 3]
+ """)
+ data = round_trip_load(x)
+ assert data['a'].fa.flow_style() is True
+ data_copy = copy.deepcopy(data)
+ assert data_copy['a'].fa.flow_style() is True
+ data_copy['a'].fa.set_block_style()
+ assert data['a'].fa.flow_style() != data_copy['a'].fa.flow_style()
+ assert data['a'].fa._flow_style is True
+ assert data_copy['a'].fa._flow_style is False
+ y = round_trip_dump(data_copy)
+
+ print('x [{}]'.format(x))
+ print('y [{}]'.format(y))
+ assert y == dedent("""\
+ a:
+ - 1
+ - 2
+ - 3
+ """)
+
+
+class TestCopy:
+ def test_copy_flow_style_nested_dict(self):
+ x = dedent("""\
+ a: {foo: bar, baz: quux}
+ """)
+ data = round_trip_load(x)
+ assert data['a'].fa.flow_style() is True
+ data_copy = copy.copy(data)
+ assert data_copy['a'].fa.flow_style() is True
+ data_copy['a'].fa.set_block_style()
+ assert data['a'].fa.flow_style() == data_copy['a'].fa.flow_style()
+ assert data['a'].fa._flow_style is False
+ assert data_copy['a'].fa._flow_style is False
+ y = round_trip_dump(data_copy)
+ z = round_trip_dump(data)
+ assert y == z
+
+ assert y == dedent("""\
+ a:
+ foo: bar
+ baz: quux
+ """)
+
+ def test_copy_flow_style_nested_list(self):
+ x = dedent("""\
+ a: [1, 2, 3]
+ """)
+ data = round_trip_load(x)
+ assert data['a'].fa.flow_style() is True
+ data_copy = copy.copy(data)
+ assert data_copy['a'].fa.flow_style() is True
+ data_copy['a'].fa.set_block_style()
+ assert data['a'].fa.flow_style() == data_copy['a'].fa.flow_style()
+ assert data['a'].fa._flow_style is False
+ assert data_copy['a'].fa._flow_style is False
+ y = round_trip_dump(data_copy)
+
+ print('x [{}]'.format(x))
+ print('y [{}]'.format(y))
+ assert y == dedent("""\
+ a:
+ - 1
+ - 2
+ - 3
+ """)
diff --git a/comments.py b/comments.py
index dc56594..e549a33 100644
--- a/comments.py
+++ b/comments.py
@@ -8,6 +8,7 @@ these are not really related, formatting could be factored out as
a separate base
"""
+import copy
from collections import MutableSet, Sized, Set # type: ignore
from ruamel.yaml.compat import ordereddict, PY2
@@ -296,6 +297,15 @@ class CommentedBase(object):
def yaml_set_tag(self, value):
self.tag.value = value
+ def copy_attributes(self, t, deep=False):
+ for a in [Comment.attrib, Format.attrib, LineCol.attrib, Anchor.attrib,
+ Tag.attrib, merge_attrib]:
+ if hasattr(self, a):
+ if deep:
+ setattr(t, a, copy.deepcopy(getattr(self, a)))
+ else:
+ setattr(t, a, getattr(self, a))
+
class CommentedSeq(list, CommentedBase):
__slots__ = Comment.attrib,
@@ -357,6 +367,14 @@ class CommentedSeq(list, CommentedBase):
pre_comments = self.ca.comment[1] = []
return pre_comments
+ def __deepcopy__(self, memo):
+ res = CommentedSeq()
+ memo[id(self)] = res
+ for k in self:
+ res.append(copy.deepcopy(k))
+ self.copy_attributes(res, deep=True)
+ return res
+
class CommentedKeySeq(tuple, CommentedBase):
"""This primarily exists to be able to roundtrip keys that are sequences"""
@@ -731,6 +749,14 @@ class CommentedMap(ordereddict, CommentedBase):
def add_yaml_merge(self, value):
self.merge.extend(value)
+ def __deepcopy__(self, memo):
+ res = CommentedMap()
+ memo[id(self)] = res
+ for k in self:
+ res[k] = copy.deepcopy(self[k])
+ self.copy_attributes(res, deep=True)
+ return res
+
class CommentedOrderedMap(CommentedMap):
__slots__ = Comment.attrib,
diff --git a/configobjwalker.py b/configobjwalker.py
index bab910c..a6eb54c 100644
--- a/configobjwalker.py
+++ b/configobjwalker.py
@@ -5,5 +5,5 @@ from ruamel.yaml.util import configobj_walker as new_configobj_walker
def configobj_walker(cfg):
- warnings.warn("configobj_walker has move to ruamel.yaml.util, please update your code")
+ warnings.warn("configobj_walker has moved to ruamel.yaml.util, please update your code")
return new_configobj_walker(cfg)
diff --git a/tox.ini b/tox.ini
index 40ed037..611e633 100644
--- a/tox.ini
+++ b/tox.ini
@@ -15,7 +15,7 @@ norecursedirs = test/lib .tox
[testenv:pep8]
commands =
- flake8 --exclude convert,cmd {posargs}
+ flake8 --exclude convert,cmd,base {posargs}
[flake8]
show-source = True