-
Notifications
You must be signed in to change notification settings - Fork 0
/
utils.py
59 lines (43 loc) · 1.8 KB
/
utils.py
1
2
3
4
5
6
7
8
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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# encoding: utf-8
"""
"""
__author__ = "Richard Smith"
__date__ = "13 Sep 2021"
__copyright__ = "Copyright 2018 United Kingdom Research and Innovation"
__license__ = "BSD - see LICENSE file in top-level package directory"
__contact__ = "[email protected]"
# Taken from https://github.com/cedadev/stac-generator/blob/master/stac_generator/core/utils.py
# Python imports
import collections
def dict_merge(*args, add_keys=True) -> dict:
assert len(args) >= 2, "dict_merge requires at least two dicts to merge"
# Make a copy of the root dict
rtn_dct = args[0].copy()
merge_dicts = args[1:]
for merge_dct in merge_dicts:
if add_keys is False:
merge_dct = {
key: merge_dct[key] for key in set(rtn_dct).intersection(set(merge_dct))
}
for k, v in merge_dct.items():
# This is a new key. Add as is.
if not rtn_dct.get(k):
rtn_dct[k] = v
# This is an existing key with mismatched types
elif k in rtn_dct and type(v) != type(rtn_dct[k]):
raise TypeError(
f"Overlapping keys exist with different types: original is {type(rtn_dct[k])}, new value is {type(v)}"
)
# Recursive merge the next level
elif isinstance(rtn_dct[k], dict) and isinstance(
merge_dct[k], collections.abc.Mapping
):
rtn_dct[k] = dict_merge(rtn_dct[k], merge_dct[k], add_keys=add_keys)
# If the item is a list, append items avoiding duplictes
elif isinstance(v, list):
for list_value in v:
if list_value not in rtn_dct[k]:
rtn_dct[k].append(list_value)
else:
rtn_dct[k] = v
return rtn_dct