Skip to content

Some of unit tests failing for deepdiff 8.6.1 #574

@PatrykKups

Description

@PatrykKups

Describe the bug
Few of unit tests failing.
Following pinnings are used in conda environment:
AnacondaRecipes/deepdiff-feedstock#9
List of test deps:

    - pytest >=8.3.0,<9.0.0
    - pytest-benchmark >=5.1.0,<6.0.0
    - click >=8.1.0,<9.0.0
    - numpy >=2.2.0,<3.0.0  # [py>=310]
    - numpy >=2.0.0,<3.0.0  # [py<310]
    - pyyaml >=6.0.0,<8.0.0
    - python-dateutil >=2.9.0,<3.0.0
    - pydantic
    - tomli-w >=1.2.0,<1.3.0
    - pandas >=2.2.0,<3.0.0
    - uuid6 >=2025.0.0
    - polars >=1.21.0,<2.0.0

To Reproduce
PYPI source is used.
command: pytest tests

Expected behavior
All tests passing

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

  • OS: MacOS Pro M4
  • Version macOS Sequoia 15.7.2
  • Python Version 3.10
  • DeepDiff Version 8.6.1

Additional context

============================= test session starts ==============================
platform darwin -- Python 3.10.19, pytest-8.4.2, pluggy-1.5.0
benchmark: 5.1.0 (defaults: timer=time.perf_counter disable_gc=False min_rounds=5 min_time=0.000005 max_time=1.0 calibration_precision=10 warmup=False warmup_iterations=100000)
rootdir: $SRC_DIR
plugins: benchmark-5.1.0
collected 1039 items

tests/test_anyset.py .....                                               [  0%]
tests/test_cache.py ss....                                               [  1%]
tests/test_colored_view.py ................                              [  2%]
tests/test_command.py .......................                            [  4%]
tests/test_delta.py ...........F........................................ [  9%]
................................................................F....    [ 16%]
tests/test_diff_datetime.py ......                                       [ 17%]
tests/test_diff_include_paths.py .............                           [ 18%]
tests/test_diff_math.py .....                                            [ 18%]
tests/test_diff_numpy.py ................                                [ 20%]
tests/test_diff_other.py ..............                                  [ 21%]
tests/test_diff_text.py ................................................ [ 26%]
........................................................................ [ 33%]
..sss........................................................            [ 39%]
tests/test_diff_tree.py ..............s                                  [ 40%]
tests/test_distance.py ......................................            [ 44%]
tests/test_hash.py ..F.................................................. [ 49%]
......................................................                   [ 54%]
tests/test_helper.py ................................................... [ 59%]
........................................................................ [ 66%]
......................................                                   [ 69%]
tests/test_ignore_order.py .....................sss.s................... [ 74%]
.......................................                                  [ 78%]
tests/test_ignore_uuid_types.py ..........                               [ 79%]
tests/test_lfucache.py ....                                              [ 79%]
tests/test_memoryview.py .............                                   [ 80%]
tests/test_model.py ..................F...                               [ 82%]
tests/test_operators.py ..........                                       [ 83%]
tests/test_path.py ..................                                    [ 85%]
tests/test_search.py ................................................... [ 90%]
...........                                                              [ 91%]
tests/test_security.py ...                                               [ 91%]
tests/test_serialization.py FFFFFF...............F...................... [ 95%]
.....................F...FFF....                                         [ 99%]
tests/test_summarize.py .....FFFF.                                       [100%]

=================================== FAILURES ===================================
______________________ TestBasicsOfDelta.test_delta_repr _______________________

self = <tests.test_delta.TestBasicsOfDelta object at 0x13f5db6a0>

    def test_delta_repr(self):
        t1 = [1, 2]
        t2 = [1, 2, 3, 5]
        diff = DeepDiff(t1, t2)
        delta = Delta(diff)
        options = {
            '<Delta: {"iterable_item_added":{"root[2]":3,"root[3]":5}}>',
            '<Delta: {"iterable_item_added":{"root[3]":5,"root[2]":3}}>',
        }
>       assert repr(delta) in options
E       assert '<Delta: {"iterable_item_added": {"root[2]": 3, "root[3]": 5}}>' in {'<Delta: {"iterable_item_added":{"root[2]":3,"root[3]":5}}>', '<Delta: {"iterable_item_added":{"root[3]":5,"root[2]":3}}>'}
E        +  where '<Delta: {"iterable_item_added": {"root[2]": 3, "root[3]": 5}}>' = repr(<Delta: {"iterable_item_added": {"root[2]": 3, "root[3]": 5}}>)

tests/test_delta.py:177: AssertionError
___________ TestDeltaCompareFunc.test_list_of_alphabet_and_its_delta ___________

self = <tests.test_delta.TestDeltaCompareFunc object at 0x154252440>

    def test_list_of_alphabet_and_its_delta(self):
        l1 = "A B C D E F G D H".split()
        l2 = "B C X D H Y Z".split()
        diff = DeepDiff(l1, l2)
    
        # Problem: The index of values_changed should be either all for AFTER removals or BEFORE removals.
        # What we have here is that F & G transformation to Y and Z is not compatible with A and E removal
        # it is really meant for the removals to happen first, and then have indexes in L2 for values changing
        # rather than indexes in L1. Here what we need to have is:
        # A B C D E F G D H
        # A B C-X-E
        # B C D F G D H  # removal
    
        # What we really need is to report is as it is in difflib for delta specifically:
        # A B C D E F G D H
        # B C D E F G D H     delete    t1[0:1] --> t2[0:0]    ['A'] --> []
        # B C D E F G D H     equal     t1[1:3] --> t2[0:2] ['B', 'C'] --> ['B', 'C']
        # B C X D H           replace   t1[3:7] --> t2[2:3] ['D', 'E', 'F', 'G'] --> ['X']
        # B C X D H           equal     t1[7:9] --> t2[3:5] ['D', 'H'] --> ['D', 'H']
        # B C X D H Y Z       insert    t1[9:9] --> t2[5:7]       [] --> ['Y', 'Z']
    
        # So in this case, it needs to also include information about what stays equal in the delta
        # NOTE: the problem is that these operations need to be performed in a specific order.
        # DeepDiff removes that order and just buckets all insertions vs. replace vs. delete in their own buckets.
        # For times that we use Difflib, we may want to keep the information for the array_change key
        # just for the sake of delta, but not for reporting in deepdiff itself.
        # that way we can re-apply the changes as they were reported in delta.
    
        delta = Delta(diff)
        assert l2 == l1 + delta
        with pytest.raises(ValueError) as exc_info:
            l1 == l2 - delta
        assert "Please recreate the delta with bidirectional=True" == str(exc_info.value)
    
        delta2 = Delta(diff, bidirectional=True)
        assert l2 == l1 + delta2
        assert l1 == l2 - delta2
    
        dump = Delta(diff, bidirectional=True).dumps()
        delta3 = Delta(dump, bidirectional=True)
    
        assert l2 == l1 + delta3
        assert l1 == l2 - delta3
    
        dump4 = Delta(diff, bidirectional=True, serializer=json_dumps).dumps()
>       delta4 = Delta(dump4, bidirectional=True, deserializer=json_loads)

tests/test_delta.py:2767: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
../_test_env_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placeho/lib/python3.10/site-packages/deepdiff/delta.py:131: in __init__
    self.diff = _deserializer(diff, safe_to_import=safe_to_import)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

obj = '{"values_changed": {"root[3]": {"new_value": "X", "old_value": "D", "new_path": "root[2]"}, "root[5]": {"new_value": ...3, 7, 2, 3, ["D", "E", "F", "G"], ["X"]], ["equal", 7, 9, 3, 5, null, null], ["insert", 9, 9, 5, 7, [], ["Y", "Z"]]]}}'
safe_to_import = None

    def _deserializer(obj, safe_to_import=None):
        result = deserializer(obj)
        if result.get('_iterable_opcodes'):
            _iterable_opcodes = {}
            for path, op_codes in result['_iterable_opcodes'].items():
                _iterable_opcodes[path] = []
                for op_code in op_codes:
                    _iterable_opcodes[path].append(
>                       Opcode(
                            **op_code
                        )
                    )
E                   TypeError: deepdiff.helper.Opcode() argument after ** must be a mapping, not list

../_test_env_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placeho/lib/python3.10/site-packages/deepdiff/delta.py:103: TypeError
_______________________ TestDeepHash.test_deephash_repr ________________________

self = <tests.test_hash.TestDeepHash object at 0x154001b10>

    def test_deephash_repr(self):
        obj = "a"
        result = DeepHash(obj)
>       assert '{"a":"980410da9522db17c3ab8743541f192a5ab27772a6154dbc7795ee909e653a5c"}' == repr(result)
E       assert '{"a":"980410...e909e653a5c"}' == '{"a": "98041...e909e653a5c"}'
E         
E         - {"a": "980410da9522db17c3ab8743541f192a5ab27772a6154dbc7795ee909e653a5c"}
E         ?      -
E         + {"a":"980410da9522db17c3ab8743541f192a5ab27772a6154dbc7795ee909e653a5c"}

tests/test_hash.py:62: AssertionError
_______________ TestDiffLevel.test_repetition_attribute_and_repr _______________

self = <tests.test_model.TestDiffLevel object at 0x13f6dafe0>

    def test_repetition_attribute_and_repr(self):
        t1 = [1, 1]
        t2 = [1]
        some_repetition = 'some repetition'
        node = DiffLevel(t1, t2)
        node.additional['repetition'] = some_repetition
        assert node.repetition == some_repetition
>       assert repr(node) == '<root {"repetition":"some repetition"}>'
E       assert '<root {"repe...repetition"}>' == '<root {"repe...repetition"}>'
E         
E         - <root {"repetition":"some repetition"}>
E         + <root {"repetition": "some repetition"}>
E         ?                     +

tests/test_model.py:278: AssertionError
__________________ TestSerialization.test_serialization_text ___________________

self = <tests.test_serialization.TestSerialization object at 0x1543add50>

    def test_serialization_text(self):
        ddiff = DeepDiff(t1, t2)
>       assert "builtins.list" in ddiff.to_json_pickle()
E       TypeError: argument of type 'NoneType' is not iterable

tests/test_serialization.py:55: TypeError
_________ TestSerialization.test_serialization_text_force_builtin_json _________

self = <tests.test_serialization.TestSerialization object at 0x15444e9e0>

    def test_serialization_text_force_builtin_json(self):
        ddiff = DeepDiff(t1, t2)
>       with pytest.raises(TypeError) as excinfo:
E       Failed: DID NOT RAISE <class 'TypeError'>

tests/test_serialization.py:61: Failed
____________________ TestSerialization.test_deserialization ____________________

self = <tests.test_serialization.TestSerialization object at 0x13f424370>

    def test_deserialization(self):
        ddiff = DeepDiff(t1, t2)
        jsoned = ddiff.to_json_pickle()
        ddiff2 = DeepDiff.from_json_pickle(jsoned)
>       assert ddiff == ddiff2
E       assert {'type_changes': {"root[4]['b']": {'old_type': <class 'list'>, 'new_type': <class 'str'>, 'old_value': [1, 2, 3], 'new_value': 'world\n\n\nEnd'}}} == None

tests/test_serialization.py:71: AssertionError
__________________ TestSerialization.test_serialization_tree ___________________

self = <tests.test_serialization.TestSerialization object at 0x13f424b80>

    def test_serialization_tree(self):
        ddiff = DeepDiff(t1, t2, view='tree')
        pickle_jsoned = ddiff.to_json_pickle()
>       assert "world" in pickle_jsoned
E       TypeError: argument of type 'NoneType' is not iterable

tests/test_serialization.py:76: TypeError
_________________ TestSerialization.test_deserialization_tree __________________

self = <tests.test_serialization.TestSerialization object at 0x13f424a90>

    def test_deserialization_tree(self):
        ddiff = DeepDiff(t1, t2, view='tree')
        jsoned = ddiff.to_json_pickle()
        ddiff2 = DeepDiff.from_json_pickle(jsoned)
>       assert 'type_changes' in ddiff2
E       TypeError: argument of type 'NoneType' is not iterable

tests/test_serialization.py:84: TypeError
_________ TestSerialization.test_serialize_custom_objects_throws_error _________

self = <tests.test_serialization.TestSerialization object at 0x13f425e70>

    def test_serialize_custom_objects_throws_error(self):
        class A:
            pass
    
        class B:
            pass
    
        t1 = A()
        t2 = B()
        ddiff = DeepDiff(t1, t2)
>       assert r'{"type_changes":{"root":{"old_type":"A","new_type":"B","old_value":{},"new_value":{}}}}' == ddiff.to_json()
E       assert '{"type_chang..._value":{}}}}' == '{"type_chang...value": {}}}}'
E         
E         - {"type_changes": {"root": {"old_type": "A", "new_type": "B", "old_value": {}, "new_value": {}}}}
E         ?                 -        -            -    -           -    -            -   -            -
E         + {"type_changes":{"root":{"old_type":"A","new_type":"B","old_value":{},"new_value":{}}}}

tests/test_serialization.py:96: AssertionError
_____________________ TestPickling.test_seriaize_property ______________________

self = <tests.test_serialization.TestPickling object at 0x13f424c40>

    def test_seriaize_property(self):
    
        class Sample:
            @property
            def something(self):
                return 10
    
        sample = Sample()
        serialized = json_dumps(sample)
>       assert '{"something":10}' == serialized
E       assert '{"something":10}' == '{"something": 10}'
E         
E         - {"something": 10}
E         ?              -
E         + {"something":10}

tests/test_serialization.py:219: AssertionError
_______ TestDeepDiffPretty.test_json_dumps_and_loads[8-value7-<lambda>] ________

self = <tests.test_serialization.TestDeepDiffPretty object at 0x13f785c60>
test_num = 8
value = SomeStats(counter=Counter({'a': 2, 'b': 1}), context_aware_counter=None, min_int=0, max_int=10)
func_to_convert_back = <function TestDeepDiffPretty.<lambda> at 0x13f67eb90>

    @pytest.mark.parametrize('test_num, value, func_to_convert_back', [
        (1, {'10': None}, None),
        (2, {"type_changes": {"root": {"old_type": None, "new_type": list, "new_value": ["你好", 2, 3, 5]}}}, None),
        (3, {'10': Decimal(2017)}, None),
        (4, Decimal(2017.1), None),
        (5, {1, 2, 10}, set),
        (6, datetime.datetime(2023, 10, 11), datetime.datetime.fromisoformat),
        (7, datetime.datetime.utcnow(), datetime.datetime.fromisoformat),
        (8, field_stats1, lambda x: SomeStats(**x)),
        (9, np.array([[ 101, 3533, 1998, 4532, 2024, 3415, 1012,  102]]), np.array),
        (10, memoryview(b"hello"), lambda x: memoryview(x.encode('utf-8'))),
        (11, {'file_type': 'xlsx', 'signature': b'52bd9907785'}, sig_to_bytes)
    ])
    def test_json_dumps_and_loads(self, test_num, value, func_to_convert_back):
        serialized = json_dumps(value)
        back = json_loads(serialized)
        if func_to_convert_back:
>           back = func_to_convert_back(back)

tests/test_serialization.py:435: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

x = [{'a': 2, 'b': 1}, None, 0, 10]

>       (8, field_stats1, lambda x: SomeStats(**x)),
        (9, np.array([[ 101, 3533, 1998, 4532, 2024, 3415, 1012,  102]]), np.array),
        (10, memoryview(b"hello"), lambda x: memoryview(x.encode('utf-8'))),
        (11, {'file_type': 'xlsx', 'signature': b'52bd9907785'}, sig_to_bytes)
    ])
E   TypeError: tests.test_serialization.SomeStats() argument after ** must be a mapping, not list

tests/test_serialization.py:426: TypeError
_______________ TestDeepDiffPretty.test_namedtuple_seriazliation _______________

self = <tests.test_serialization.TestDeepDiffPretty object at 0x13f786f20>

    def test_namedtuple_seriazliation(self):
        op_code = Opcode(tag="replace", t1_from_index=0, t1_to_index=1, t2_from_index=10, t2_to_index=20)
        serialized = json_dumps(op_code)
        expected = '{"tag":"replace","t1_from_index":0,"t1_to_index":1,"t2_from_index":10,"t2_to_index":20,"old_values":null,"new_values":null}'
>       assert serialized == expected
E       assert '["replace", ..., null, null]' == '{"tag":"repl...values":null}'
E         
E         - {"tag":"replace","t1_from_index":0,"t1_to_index":1,"t2_from_index":10,"t2_to_index":20,"old_values":null,"new_values":null}
E         + ["replace", 0, 1, 10, 20, null, null]

tests/test_serialization.py:445: AssertionError
____________________ TestDeepDiffPretty.test_reversed_list _____________________

self = <tests.test_serialization.TestDeepDiffPretty object at 0x13f786c20>

    def test_reversed_list(self):
        items = reversed([1, 2, 3])
    
        serialized = json_dumps(items)
        serialized2 = json_dumps(items)
    
>       assert '[3,2,1]' == serialized
E       AssertionError: assert '[3,2,1]' == '[3, 2, 1]'
E         
E         - [3, 2, 1]
E         ?    -  -
E         + [3,2,1]

tests/test_serialization.py:453: AssertionError
______________________ TestDeepDiffPretty.test_dict_keys _______________________

self = <tests.test_serialization.TestDeepDiffPretty object at 0x13f7840d0>

    def test_dict_keys(self):
        dic = {"foo": "bar", "apple": "too sweet"}
        serialized = json_dumps(dic.keys())
>       assert '["foo","apple"]' == serialized
E       assert '["foo","apple"]' == '["foo", "apple"]'
E         
E         - ["foo", "apple"]
E         ?        -
E         + ["foo","apple"]

tests/test_serialization.py:459: AssertionError
_______________ TestSummarize.test_long_value_truncation_in_dict _______________

self = <tests.test_summarize.TestSummarize object at 0x13f5b9f30>

    def test_long_value_truncation_in_dict(self):
        data = {
            "key1": "a" * 100,
            "key2": "b" * 50,
            "key3": "c" * 150
        }
        summary = summarize(data, max_length=100)
        # The summary should be under 100 characters and include ellipsis to indicate truncation.
>       assert len(summary) == 113, "Yes we are going slightly above"
E       AssertionError: Yes we are going slightly above
E       assert 116 == 113
E        +  where 116 = len('{"key3": "ccccccccccccccccccccccccccccccccccccccccccccccccccc...cc", "key1": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa...aa"}')

tests/test_summarize.py:40: AssertionError
_________________ TestSummarize.test_nested_structure_summary1 _________________

self = <tests.test_summarize.TestSummarize object at 0x13f5ba230>

    def test_nested_structure_summary1(self):
        data = {
            "RecordType": "CID",
            "RecordNumber": 2719,
            "RecordTitle": "Chloroquine",
            "Section": [
                {
                    "TOCHeading": "Structures",
                    "Description": "Structure depictions and information for 2D, 3D, and crystal related",
                    "Section": [
                        {
                            "TOCHeading": "2D Structure",
                            "Description": "A two-dimensional representation of the compound",
                            "DisplayControls": {"MoveToTop": True},
                            "Information": [
                                {
                                    "ReferenceNumber": 69,
                                    "Value": {"Boolean": [True]}
                                }
                            ]
                        },
                        {
                            "TOCHeading": "3D Conformer",
                            "Description": ("A three-dimensional representation of the compound. "
                                            "The 3D structure is not experimentally determined, but computed by PubChem. "
                                            "More detailed information on this conformer model is described in the PubChem3D thematic series published in the Journal of Cheminformatics."),
                            "DisplayControls": {"MoveToTop": True},
                            "Information": [
                                {
                                    "ReferenceNumber": 69,
                                    "Description": "Chloroquine",
                                    "Value": {"Number": [2719]}
                                }
                            ]
                        }
                    ]
                },
                {
                    "TOCHeading": "Chemical Safety",
                    "Description": "Launch the Laboratory Chemical Safety Summary datasheet, and link to the safety and hazard section",
                    "DisplayControls": {"HideThisSection": True, "MoveToTop": True},
                    "Information": [
                        {
                            "ReferenceNumber": 69,
                            "Name": "Chemical Safety",
                            "Value": {
                                "StringWithMarkup": [
                                    {
                                        "String": "          ",
                                        "Markup": [
                                            {
                                                "Start": 0,
                                                "Length": 1,
                                                "URL": "https://pubchem.ncbi.nlm.nih.gov/images/ghs/GHS07.svg",
                                                "Type": "Icon",
                                                "Extra": "Irritant"
                                            }
                                        ]
                                    }
                                ]
                            }
                        }
                    ]
                }
            ]
        }
        data_copy = deepcopy(data)
        summary = summarize(data_copy, max_length=200)
>       assert len(summary) == 240, "Yes slightly above"
E       AssertionError: Yes slightly above
E       assert 258 == 240
E        +  where 258 = len('{"Section": [{"Section": [{"Description": ""}, {"Description": ""}], "Description": "Structure depictions a...ed"}, {...: "C"}], "Description": "Launch the ...on"}], "RecordTitle": "Chloroquine", "RecordNumber": 2719, "RecordType": "CID"}')

tests/test_summarize.py:111: AssertionError
_________________ TestSummarize.test_nested_structure_summary2 _________________

self = <tests.test_summarize.TestSummarize object at 0x13f5b8c40>
compounds = {'RecordNumber': 2719, 'RecordTitle': 'Chloroquine', 'RecordType': 'CID', 'Reference': [{'ANID': 13015812, 'Descriptio...vide a link to the Legal Notice page.', 'LicenseURL': 'https://echa.europa.eu/web/guest/legal-notice', ...}, ...], ...}

    def test_nested_structure_summary2(self, compounds):
        summary = summarize(compounds, max_length=200)
>       assert len(summary) == 319, "Ok yeah max_length is more like a guide"
E       AssertionError: Ok yeah max_length is more like a guide
E       assert 344 == 319
E        +  where 344 = len('{"Section": [{"Section": [{"Description": ""}, {"Description": ""}], "Description": "Toxicity information r...y."}, {...": [{"LicenseNote": "Use of th...e.", "Description": "T...s."}, {"LicenseNote": "U...e.", "Description": "T"}, "..."]}')

tests/test_summarize.py:122: AssertionError
_______________________ TestSummarize.test_list_summary ________________________

self = <tests.test_summarize.TestSummarize object at 0x13f5b9a50>

    def test_list_summary(self):
        data = [1, 2, 3, 4]
        summary = summarize(data, max_length=50)
        # The summary should start with '[' and end with ']'
        assert summary.startswith("[") and summary.endswith("]")
        # When more than one element exists, expect a trailing ellipsis or indication of more elements
        assert "..." not in summary
    
        data2 = list(range(1, 200))
        summary2 = summarize(data2, max_length=14)
        assert "..." in summary2
        expected = '[100,101,102,103,10,"..."]'
>       assert expected == summary2
E       assert '[100,101,102,103,10,"..."]' == '[100, 101, 1...3, 10, "..."]'
E         
E         - [100, 101, 102, 103, 10, "..."]
E         ?      -    -    -    -   -
E         + [100,101,102,103,10,"..."]

tests/test_summarize.py:140: AssertionError

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions