diff --git a/dictdiffer/__init__.py b/dictdiffer/__init__.py index 230ff9b..13083cc 100644 --- a/dictdiffer/__init__.py +++ b/dictdiffer/__init__.py @@ -294,6 +294,7 @@ def patch(diff_result, destination, in_place=False): def add(node, changes): for key, value in changes: + value = deepcopy(value) dest = dot_lookup(destination, node) if isinstance(dest, LIST_TYPES): dest.insert(key, value) @@ -311,7 +312,7 @@ def change(node, changes): if isinstance(dest, LIST_TYPES): last_node = int(last_node) _, value = changes - dest[last_node] = value + dest[last_node] = deepcopy(value) def remove(node, changes): for key, value in changes: diff --git a/tests/test_dictdiffer.py b/tests/test_dictdiffer.py index c1152b8..a6e0338 100644 --- a/tests/test_dictdiffer.py +++ b/tests/test_dictdiffer.py @@ -753,5 +753,18 @@ def test_ignore_dotted_ignore_key(ignore, dot_notation, diff_size): ignore=[ignore]))) +@pytest.mark.parametrize('first', [{}, {'value': None}]) +@pytest.mark.parametrize('in_place', [False, True]) +def test_patch_does_not_alias_diff_values(first, in_place): + first = dict(first) + second = {'value': {'items': [1]}} + changes = list(diff(first, second)) + original_changes = list(diff(first, second)) + result = patch(changes, first, in_place=in_place) + result['value']['items'].append(2) + assert changes == original_changes + assert patch(changes, {})['value'] == {'items': [1]} + + if __name__ == "__main__": unittest.main()