Skip to content

iterable_compare_func not working properly #414

Open
@brxdeop

Description

@brxdeop

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

Describe the bug
the issue is related to the use of the ability to compare iterable element with a customized function.
with an iterable_compare_func defined as in the documentation : to compare iterables only if they have the same id, the result of deepdiff is wrong as it is missing the differences.

To Reproduce
Exactly with the same examples on documentation.

from deepdiff import DeepDiff
from deepdiff.helper import CannotCompare

t1 = [
    {
        'id': 1,
        'value': [1]
    },
    {
        'id': 2,
        'value': [7, 8, 1]
    },
    {
        'id': 3,
        'value': [7, 8],
    },
]

t2 = [
    {
        'id': 2,
        'value': [7, 8]
    },
    {
        'id': 3,
        'value': [7, 8, 1],
    },
    {
        'id': 1,
        'value': [1]
    },
]

def compare_func(x, y, level=None):
    try:
        return x['id'] == y['id']
    except Exception:
        raise CannotCompare() from None

without iterable function - result is as expected

>>>DeepDiff(t1, t2)
{'values_changed': {"root[0]['id']": {'new_value': 2, 'old_value': 1}, "root[0]['value'][0]": {'new_value': 7, 'old_value': 1}, "root[1]['id']": {'new_value': 3, 'old_value': 2}, "root[2]['id']": {'new_value': 1, 'old_value': 3}, "root[2]['value'][0]": {'new_value': 1, 'old_value': 7}}, 'iterable_item_added': {"root[0]['value'][1]": 8}, 'iterable_item_removed': {"root[2]['value'][1]": 8}}

without iterable function - result is wrong

>>> DeepDiff(t1, t2, iterable_compare_func=compare_func)
{}
>>> DeepDiff(t1, t2, iterable_compare_func=compare_func, verbose_level=2)
{'iterable_item_moved': {'root[0]': {'new_path': 'root[2]', 'value': {'id': 1, 'value': [1]}}, 'root[1]': {'new_path': 'root[0]', 'value': {'id': 2, 'value': [7, 8]}}, 'root[2]': {'new_path': 'root[1]', 'value': {'id': 3, 'value': [7, 8, 1]}}}}
>>> DeepDiff(t1, t2, iterable_compare_func=compare_func, cutoff_distance_for_pairs=1, cutoff_intersection_for_pairs=1)
{}

as you can see on verbosity_level=2 the element is marked as moved even if it is not even the same value ? how this could happen ?

Expected behavior
Expected behavior to list compare with ids so the change will be.

>>>DeepDiff(t1, t2, iterable_compare_func=compare_func)
{'iterable_item_added': {"root[2]['value'][2]": 1}, 'iterable_item_removed': {"root[1]['value'][2]": 1}}

OS, DeepDiff version and Python version (please complete the following information):
The tests has been performed on several environments.

  • OS: Debian, SilverBlue (Fedora), Container (Alpine)
  • Python Version 3.10, 3.11.4, 3.10 respectively
  • DeepDiff Version : 6.3.1

Metadata

Metadata

Assignees

Labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions