Skip to content

_deepdiff

Errors

Class to represent deepdiff errors.

Source code in src/fractal_task_tools/_deepdiff.py
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
class Errors:
    """
    Class to represent deepdiff errors.
    """

    _data: list[tuple[JSONType, JSONType, str]]
    """
    Actual contents.

    Each item of `self._data` is made of the old JSON object, the new JSON object
    and the error message.
    """

    def __init__(self):
        self._data = []

    def reset_state(self):
        self._data = []

    def append(self: Self, item: tuple[JSONType, JSONType, str]):
        self._data.append(item)

    @property
    def tot_errors(self: Self) -> int:
        return len(self._data)

    @property
    def messages_str(self: Self) -> str:
        return str([item[2] for item in self._data])

    @property
    def data(self: Self) -> list[tuple[JSONType, JSONType, str]]:
        return self._data

_data = [] instance-attribute

Actual contents.

Each item of self._data is made of the old JSON object, the new JSON object and the error message.

deepdiff(*, old_object, new_object, path, ignore_keys_order, recursion_level=1, verbose=False)

Recursive diff of two JSON values.

Note: when a difference is identified, a new item is added to the ERRORS = Errors() variable.

PARAMETER DESCRIPTION
old_object

TYPE: JSONType

new_object

TYPE: JSONType

path

TYPE: str

ignore_keys_order

TYPE: bool

recursion_level

TYPE: int DEFAULT: 1

verbose

TYPE: bool DEFAULT: False

Source code in src/fractal_task_tools/_deepdiff.py
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
def deepdiff(
    *,
    old_object: JSONType,
    new_object: JSONType,
    path: str,
    ignore_keys_order: bool,
    recursion_level: int = 1,
    verbose: bool = False,
):
    """
    Recursive diff of two JSON values.

    Note: when a difference is identified, a new item is added to the
    `ERRORS = Errors()` variable.

    Args:
        old_object:
        new_object:
        path:
        ignore_keys_order:
        recursion_level:
        verbose:
    """

    if type(old_object) is not type(new_object):
        ERRORS.append(
            (
                old_object,
                new_object,
                f"[{path}] Type difference:\n"
                f"\tOld: {type(old_object)}\n\tNew: {type(new_object)}",
            )
        )
        return

    if type(old_object) not in [list, dict, str, int, float, bool, type(None)]:
        raise ValueError(f"[{path}] Invalid type {type(old_object)}, exit.")

    if recursion_level > MAX_RECURSION_LEVEL:
        raise ValueError(f"Reached {MAX_RECURSION_LEVEL=}. Exit.")

    if type(old_object) is dict:
        old_keys = list(old_object.keys())
        new_keys = list(new_object.keys())
        if ignore_keys_order:
            old_keys = sorted(old_keys)
            new_keys = sorted(new_keys)
        if old_keys != new_keys:
            ERRORS.append(
                (
                    old_object,
                    new_object,
                    f"[{path}] Dictionaries have different keys:\n"
                    f"\tOld: {old_keys}\n\tNew: {new_keys}",
                )
            )
            return

        for key, value_a in old_object.items():
            deepdiff(
                old_object=value_a,
                new_object=new_object[key],
                path=f"{path}['{key}']",
                ignore_keys_order=ignore_keys_order,
                recursion_level=recursion_level + 1,
                verbose=verbose,
            )
    elif type(old_object) is list:
        if len(old_object) != len(new_object):
            ERRORS.append(
                (
                    old_object,
                    new_object,
                    f"[{path}] Lists have different lengths:\n"
                    f"\tOld:{len(old_object)}\n\tNew: {len(new_object)}",
                )
            )
            return

        for ind, item_a in enumerate(old_object):
            deepdiff(
                old_object=item_a,
                new_object=new_object[ind],
                path=f"{path}[{ind}]",
                ignore_keys_order=ignore_keys_order,
                recursion_level=recursion_level + 1,
                verbose=verbose,
            )
    else:
        if old_object != new_object:
            ERRORS.append(
                (
                    old_object,
                    new_object,
                    f"[{path}] Values are different:\n"
                    f"\tOld: '{old_object}'\n\tNew: '{new_object}'",
                )
            )
            return