-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathutils.py
More file actions
63 lines (51 loc) · 2.05 KB
/
Copy pathutils.py
File metadata and controls
63 lines (51 loc) · 2.05 KB
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
60
61
62
63
import collections
from importlib import import_module
def import_string(dotted_path):
"""
Copied from Django's django.utils.module_loading.import_string to be able
to work framework independently.
Import a dotted module path and return the attribute/class designated by the
last name in the path. Raise ImportError if the import failed.
"""
try:
module_path, class_name = dotted_path.rsplit(".", 1)
except ValueError as err: # pragma: no cover
raise ImportError("%s doesn't look like a module path" % dotted_path) from err
module = import_module(module_path)
try:
return getattr(module, class_name)
except AttributeError as err: # pragma: no cover
raise ImportError(
'Module "%s" does not define a "%s" attribute/class'
% (module_path, class_name)
) from err
def dict_merge(dct, merge_dct, add_keys=True):
"""
Recursive dict merge. Inspired by :meth:``dict.update()``, instead of
updating only top-level keys, dict_merge recurses down into dicts nested
to an arbitrary depth, updating keys. The ``merge_dct`` is merged into
``dct``.
This version will return a copy of the dictionary and leave the original
arguments untouched.
The optional argument ``add_keys``, determines whether keys which are
present in ``merge_dict`` but not ``dct`` should be included in the
new dict.
:param dict dct: Dict onto which the merge is executed
:param dict merge_dct: Dict which is merged into dct
:param bool add_keys: whether to add new keys
:returns: The updated dict
:rtype: dict
"""
dct = dct.copy()
if not add_keys: # pragma: no cover
merge_dct = {k: merge_dct[k] for k in set(dct).intersection(set(merge_dct))}
for k, v in merge_dct.items():
if (
k in dct
and isinstance(dct[k], dict)
and isinstance(merge_dct[k], collections.Mapping)
):
dct[k] = dict_merge(dct[k], v, add_keys=add_keys)
else:
dct[k] = v
return dct