From bc25dd01b1ec8720769e7843148ad23f299c63d6 Mon Sep 17 00:00:00 2001 From: Ed Slavich Date: Wed, 29 Apr 2020 12:00:08 -0400 Subject: [PATCH 1/3] Fix deepcopy of TaggedList --- asdf/tagged.py | 9 +++++ asdf/tests/test_tagged.py | 82 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 91 insertions(+) create mode 100644 asdf/tests/test_tagged.py diff --git a/asdf/tagged.py b/asdf/tagged.py index ee6ea683d..da24d6bb8 100644 --- a/asdf/tagged.py +++ b/asdf/tagged.py @@ -32,6 +32,7 @@ """ from collections import UserDict, UserList, UserString +from copy import deepcopy __all__ = ['tag_object', 'get_tag'] @@ -63,6 +64,10 @@ def __eq__(self, other): self.data == other.data and self._tag == other._tag) + def __deepcopy__(self, memo): + data_copy = deepcopy(self.data, memo) + return TaggedDict(data_copy, self._tag) + class TaggedList(Tagged, UserList, list): """ @@ -81,6 +86,10 @@ def __eq__(self, other): self.data == other.data and self._tag == other._tag) + def __deepcopy__(self, memo): + data_copy = deepcopy(self.data, memo) + return TaggedList(data_copy, self._tag) + class TaggedString(Tagged, UserString, str): """ diff --git a/asdf/tests/test_tagged.py b/asdf/tests/test_tagged.py new file mode 100644 index 000000000..4a55bf625 --- /dev/null +++ b/asdf/tests/test_tagged.py @@ -0,0 +1,82 @@ +from copy import deepcopy, copy + +from asdf.tagged import TaggedList, TaggedDict, TaggedString + + +def test_tagged_list_deepcopy(): + original = TaggedList([0, 1, 2, ["foo"]], "tag:nowhere.org:custom/foo-1.0.0") + result = deepcopy(original) + assert result == original + assert result.data == original.data + assert result._tag == original._tag + original.append(4) + assert len(result) == 4 + original[3].append("bar") + assert len(result[3]) == 1 + + +def test_tagged_list_copy(): + original = TaggedList([0, 1, 2, ["foo"]], "tag:nowhere.org:custom/foo-1.0.0") + result = copy(original) + assert result == original + assert result.data == original.data + assert result._tag == original._tag + original.append(4) + assert len(result) == 4 + original[3].append("bar") + assert len(result[3]) == 2 + + +def test_tagged_list_isinstance(): + value = TaggedList([0, 1, 2, ["foo"]], "tag:nowhere.org:custom/foo-1.0.0") + assert isinstance(value, list) + + +def test_tagged_dict_deepcopy(): + original = TaggedDict({"a": 0, "b": 1, "c": 2, "nested": {"d": 3}}, "tag:nowhere.org:custom/foo-1.0.0") + result = deepcopy(original) + assert result == original + assert result.data == original.data + assert result._tag == original._tag + original["e"] = 4 + assert len(result) == 4 + original["nested"]["f"] = 5 + assert len(result["nested"]) == 1 + + +def test_tagged_dict_copy(): + original = TaggedDict({"a": 0, "b": 1, "c": 2, "nested": {"d": 3}}, "tag:nowhere.org:custom/foo-1.0.0") + result = copy(original) + assert result == original + assert result.data == original.data + assert result._tag == original._tag + original["e"] = 4 + assert len(result) == 4 + original["nested"]["f"] = 5 + assert len(result["nested"]) == 2 + + +def test_tagged_dict_isinstance(): + value = TaggedDict({"a": 0, "b": 1, "c": 2, "nested": {"d": 3}}, "tag:nowhere.org:custom/foo-1.0.0") + assert isinstance(value, dict) + + +def test_tagged_string_deepcopy(): + original = TaggedString("You're it!") + original._tag = "tag:nowhere.org:custom/foo-1.0.0" + result = deepcopy(original) + assert result == original + assert result._tag == original._tag + + +def test_tagged_string_copy(): + original = TaggedString("You're it!") + original._tag = "tag:nowhere.org:custom/foo-1.0.0" + result = copy(original) + assert result == original + assert result._tag == original._tag + + +def test_tagged_string_isinstance(): + value = TaggedString("You're it!") + assert isinstance(value, str) From f63c9d04db56b602b67f654d33ad8801353275fe Mon Sep 17 00:00:00 2001 From: Ed Slavich Date: Wed, 29 Apr 2020 12:36:06 -0400 Subject: [PATCH 2/3] Add CHANGES.rst entry --- CHANGES.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGES.rst b/CHANGES.rst index 0c6e914a5..a73b1d886 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,6 +4,9 @@ - Fix bug preventing diff of files containing ndarray-1.0.0 objects in simplified form. [#786] +- Fix bug causing duplicate elements to appear when calling + ``copy.deepcopy`` on a ``TaggedList``. [#788] + 2.6.0 (2020-04-22) ------------------ From 61c7f56951c0ebb44a73b88ced28e8bbf2b11804 Mon Sep 17 00:00:00 2001 From: Ed Slavich Date: Mon, 4 May 2020 17:28:13 -0400 Subject: [PATCH 3/3] Looks like we need a custom __copy__ method after all --- asdf/tagged.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/asdf/tagged.py b/asdf/tagged.py index da24d6bb8..baa7d5610 100644 --- a/asdf/tagged.py +++ b/asdf/tagged.py @@ -32,7 +32,7 @@ """ from collections import UserDict, UserList, UserString -from copy import deepcopy +from copy import deepcopy, copy __all__ = ['tag_object', 'get_tag'] @@ -68,6 +68,10 @@ def __deepcopy__(self, memo): data_copy = deepcopy(self.data, memo) return TaggedDict(data_copy, self._tag) + def __copy__(self): + data_copy = copy(self.data) + return TaggedDict(data_copy, self._tag) + class TaggedList(Tagged, UserList, list): """ @@ -90,6 +94,10 @@ def __deepcopy__(self, memo): data_copy = deepcopy(self.data, memo) return TaggedList(data_copy, self._tag) + def __copy__(self): + data_copy = copy(self.data) + return TaggedList(data_copy, self._tag) + class TaggedString(Tagged, UserString, str): """