Skip to content

Some of unit tests failing for deepdiff 8.6.1 #574

@kups-conda

Description

@kups-conda

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

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions