(acc: dict[object, object], delta: dict[object, object])
| 978 | |
| 979 | |
| 980 | def accumulate_delta(acc: dict[object, object], delta: dict[object, object]) -> dict[object, object]: |
| 981 | for key, delta_value in delta.items(): |
| 982 | if key not in acc: |
| 983 | acc[key] = delta_value |
| 984 | continue |
| 985 | |
| 986 | acc_value = acc[key] |
| 987 | if acc_value is None: |
| 988 | acc[key] = delta_value |
| 989 | continue |
| 990 | |
| 991 | # the `index` property is used in arrays of objects so it should |
| 992 | # not be accumulated like other values e.g. |
| 993 | # [{'foo': 'bar', 'index': 0}] |
| 994 | # |
| 995 | # the same applies to `type` properties as they're used for |
| 996 | # discriminated unions |
| 997 | if key == "index" or key == "type": |
| 998 | acc[key] = delta_value |
| 999 | continue |
| 1000 | |
| 1001 | if isinstance(acc_value, str) and isinstance(delta_value, str): |
| 1002 | acc_value += delta_value |
| 1003 | elif isinstance(acc_value, (int, float)) and isinstance(delta_value, (int, float)): |
| 1004 | acc_value += delta_value |
| 1005 | elif is_dict(acc_value) and is_dict(delta_value): |
| 1006 | acc_value = accumulate_delta(acc_value, delta_value) |
| 1007 | elif is_list(acc_value) and is_list(delta_value): |
| 1008 | # for lists of non-dictionary items we'll only ever get new entries |
| 1009 | # in the array, existing entries will never be changed |
| 1010 | if all(isinstance(x, (str, int, float)) for x in acc_value): |
| 1011 | acc_value.extend(delta_value) |
| 1012 | continue |
| 1013 | |
| 1014 | for delta_entry in delta_value: |
| 1015 | if not is_dict(delta_entry): |
| 1016 | raise TypeError(f"Unexpected list delta entry is not a dictionary: {delta_entry}") |
| 1017 | |
| 1018 | try: |
| 1019 | index = delta_entry["index"] |
| 1020 | except KeyError as exc: |
| 1021 | raise RuntimeError(f"Expected list delta entry to have an `index` key; {delta_entry}") from exc |
| 1022 | |
| 1023 | if not isinstance(index, int): |
| 1024 | raise TypeError(f"Unexpected, list delta entry `index` value is not an integer; {index}") |
| 1025 | |
| 1026 | try: |
| 1027 | acc_entry = acc_value[index] |
| 1028 | except IndexError: |
| 1029 | acc_value.insert(index, delta_entry) |
| 1030 | else: |
| 1031 | if not is_dict(acc_entry): |
| 1032 | raise TypeError("not handled yet") |
| 1033 | |
| 1034 | acc_value[index] = accumulate_delta(acc_entry, delta_entry) |
| 1035 | |
| 1036 | acc[key] = acc_value |
| 1037 |
no test coverage detected