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
|
from collections import namedtuple
from configparser import ConfigParser, DEFAULTSECT
from .load import base_path
parser = ConfigParser()
tracked_classes = []
prop_attribs = namedtuple('prop_attribs', 'config_name required section')
all_props = []
attr_map = {}
_UNSET = object()
has_read = False
config_file = str(base_path / 'config.ini')
def load_config():
global has_read
if not has_read:
parser.read(config_file)
has_read = True
def prop_name(section, option):
return (section + '.' if section and section != DEFAULTSECT else '') + option
def section(section_name: str):
def x(c):
tracked_classes.append(c)
c._section = section_name
c._props = []
for p in dir(c):
prop = getattr(c, p)
try:
prop = attr_map.get(prop, prop)
except:
continue
if hasattr(prop, 'config_name'):
s = prop.section or section_name
prop_info = prop_attribs(prop.config_name, prop.required, s)
c._props.append(prop_info)
all_props.append(prop_info)
return c()
return x
def create_property(name, conv, section, fallback):
def get(self):
load_config()
s = section or getattr(self, '_section', None) or DEFAULTSECT
cv = parser.get(s, name, fallback=fallback)
if cv is _UNSET:
raise ValueError("Missing config option")
else:
return conv(cv)
p = property(get)
attrs = prop_attribs(name, fallback is _UNSET, section)
attr_map[p] = attrs
return p
def required(name: str, conv=str, section=None):
return create_property(name, conv, section, _UNSET)
def default(name: str, default_value, conv=str, section=None):
return create_property(name, conv, section, default_value)
def prompt_missing_configs():
load_config()
for p in all_props:
if parser.get(p.section, p.config_name, fallback=_UNSET) is _UNSET:
if not parser.has_section(p.section):
parser.add_section(p.section)
parser.set(p.section, p.config_name,
input(f"What value do you want for {prop_name(p.section, p.config_name)}: "))
with open(config_file, 'w') as fp:
parser.write(fp)
print('Wrote config.ini')
__all__ = ['default', 'required', 'section', 'prompt_missing_configs']
|