seperman / deepdiff

DeepDiff: Deep Difference and search of any Python object/data. DeepHash: Hash of any object based on its contents. Delta: Use deltas to reconstruct objects by adding deltas together.
http://zepworks.com
Other
2.03k stars 224 forks source link

Instantiating a Delta with a flat_dict_list unexpectedly mutates the flat_dict_list #457

Closed sf-tcalhoun closed 7 months ago

sf-tcalhoun commented 7 months ago

Please checkout the F.A.Q page before creating a bug ticket to make sure it is not already addressed.

Describe the bug We recently discovered some unexpected behaviour which we are considering as a bug. When instantiating a new Delta with a flat_dict_list, which contains indexed list items as being added and removed, we see that the list item path index is getting removed from the flat_dict_list from the perspective of the calling module.

To Reproduce


flat_dict_list = [{'path': ['individualNames', 1],
                                   'value': {'firstName': 'Johnny',
                                             'lastName': 'Doe',
                                             'prefix': '',
                                             'middleName': 'A',
                                             'primaryIndicator': False,
                                             'professionalDesignation': '',
                                             'suffix': 'SR',
                                             'nameIdentifier': '00003'},
                                   'action': 'unordered_iterable_item_added'},
                                  {'path': ['individualNames', 1],
                                   'value': {'firstName': 'John',
                                             'lastName': 'Doe',
                                             'prefix': '',
                                             'middleName': '',
                                             'primaryIndicator': False,
                                             'professionalDesignation': '',
                                             'suffix': 'SR',
                                             'nameIdentifier': '00002'},
                                   'action': 'unordered_iterable_item_removed'}]

        # Note: the list index is provided on the path value...

        # Now use the flat_dict_list to instantiate a new delta...
        delta = Delta(flat_dict_list=flat_dict_list,
                      always_include_values=True, bidirectional=True, raise_errors=True)

        # if the flat_dict_list is (unexpectedly) mutated, it will be missing the list index number on the path value.
        # our flat_dict_list will now look like this:
        mutated_list_missing_indexes_on_path = [{'path': ['individualNames'],
                                         'value': {'firstName': 'Johnny',
                                                   'lastName': 'Doe',
                                                   'prefix': '',
                                                   'middleName': 'A',
                                                   'primaryIndicator': False,
                                                   'professionalDesignation': '',
                                                   'suffix': 'SR',
                                                   'nameIdentifier': '00003'},
                                         'action': 'unordered_iterable_item_added'},
                                        {'path': ['individualNames'],
                                         'value': {'firstName': 'John',
                                                   'lastName': 'Doe',
                                                   'prefix': '',
                                                   'middleName': '',
                                                   'primaryIndicator': False,
                                                   'professionalDesignation': '',
                                                   'suffix': 'SR',
                                                   'nameIdentifier': '00002'},
                                         'action': 'unordered_iterable_item_removed'}]

Expected behavior A clear and concise description of what you expected to happen. We expect that the flat_dict_list will be used but not changed/mutated in any way. Think of this as pass by COPY rather than pass by REFERENCE.

OS, DeepDiff version and Python version (please complete the following information):

Additional context Add any other context about the problem here. We will submit a Pull Request to fix this issue.

seperman commented 7 months ago

Thanks for making the PR @sf-tcalhoun I will keep you posted. The new release only needs some documentation and will be out.