-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathutils.py
104 lines (72 loc) · 2.6 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
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
# pylint: disable=invalid-name
from argparse import Namespace
import os
import shutil
import errors
def namespace(ns: Namespace, d: dict):
''' Creates a Namespace object ns in place for an arbitrarily deep input dictionary, d. '''
if isinstance(d, dict):
for k, v in d.items():
if isinstance(v, dict):
leaf_ns = Namespace()
ns.__dict__[k] = leaf_ns
namespace(leaf_ns, v)
else:
ns.__dict__[k] = v
def safe_copy(src, dst):
# Check that src exists
if not os.path.exists(src):
raise errors.FileNotFound(src)
# Check that dst path exists and is writeable
dst_path = os.path.dirname(dst)
if not os.path.exists(dst_path) and os.access(dst_path, os.W_OK):
raise errors.PathNotFound(dst_path)
shutil.copy2(src, dst)
def safe_link(src, dst):
# Check that src exists
if not os.path.exists(src):
raise errors.FileNotFound(src)
# Check that dst path exists and is writeable
dst_path = os.path.dirname(dst)
if not os.path.exists(dst_path) and os.access(dst_path, os.W_OK):
raise errors.PathNotFound(dst_path)
os.symlink(src, dst)
def to_number(string):
if string.isnumeric():
return int(string)
try:
ret = float(string)
except ValueError:
# Evaluate as f-string
ret = eval("f'{}'".format(string))
return ret
def update_dict(base, updates, quiet=False):
'''
Overwrites all values in base dictionary with values from updates. Turn off
print statements with queit=True.
Input:
base A dict that is to be updated.
updates A dict containing sections and keys corresponding to
those in base and potentially additional ones, that will be used to
update the base dict.
quiet An optional boolean flag to turn off output.
Output:
None
Result:
The base dict is updated in place.
'''
if not isinstance(base, dict) or not isinstance(updates, dict):
return
for key, value in updates.items():
print(key, value)
# If key is set to None, remove it from the dict
if value is None:
_ = base[key].pop(key, None)
# If it's a layered dict, recursively call update_dict
elif isinstance(value, dict) and isinstance(base.get(key), dict):
update_dict(base[key], value, quiet=quiet)
# Update dictionary values
else:
base[key] = value
if not quiet:
print(f'Setting {base[key]} = {value}')