SND@LHC Software
Loading...
Searching...
No Matches
ShipGeoConfig.py
Go to the documentation of this file.
1from future import standard_library
2standard_library.install_aliases()
3import os
4import re
5import pickle
6from contextlib import contextmanager
7from future.utils import with_metaclass
8
9
10def expand_env(string):
11 """
12 Expand environment variables in string:
13 $HOME/bin -> /home/user/bin
14 """
15 while True:
16 m = re.search("(\${*(\w+)}*)", string)
17 if m is None:
18 break
19 (env_token, env_name) = m.groups()
20 assert env_name in os.environ, "Environment variable '%s' is not defined" % env_name
21 env_value = os.environ[env_name]
22 string = string.replace(env_token, env_value)
23 return string
24
25
26class _SingletonDict(type):
27 _instances = {}
28
29 def __call__(cls, *args, **kwargs):
30 if cls not in cls._instances:
31 cls._instances[cls] = super(_SingletonDict, cls).__call__(*args, **kwargs)
32 return cls._instances[cls]
33
34 def __getitem__(cls, key):
35 return cls._instances[cls][key]
36
37 def delitem(cls, key):
38 del(cls._instances[cls][key])
39
40
41class ConfigRegistry(with_metaclass(_SingletonDict, dict)):
42 """
43 Singleton registry of all Configurations
44 """
45 recent_config_name = None
46
47 @staticmethod
48 def loadpy(filename, **kwargs):
49 with open(expand_env(filename)) as fh:
50 return ConfigRegistry.loadpys(fh.read(), **kwargs)
51
52 @staticmethod
53 def loadpys(config_string, **kwargs):
54 string_unixlf = config_string.replace('\r', '')
55 exec(string_unixlf, kwargs)
56 return ConfigRegistry.get_latest_config()
57
58 @staticmethod
60 return ConfigRegistry[ConfigRegistry.recent_config_name]
61
62 def __init__(self):
63 self.__dict__ = self
64
65 @staticmethod
66 @contextmanager
67 def register_config(name=None, base=None):
68 registry = ConfigRegistry()
69 if base is not None:
70 assert base in registry, "no base configuration (%s) found in the registry" % base
71 config = registry[base].clone()
72 else:
73 config = Config()
74 yield config
75 if name is not None:
76 registry[name] = config
77 ConfigRegistry.recent_config_name = name
78
79 @staticmethod
80 def keys():
81 registry = ConfigRegistry()
82 return [k for k, v in registry.items()]
83
84 @staticmethod
85 def get(name):
86 return ConfigRegistry[name]
87
88 @staticmethod
89 def clean():
90 for k in ConfigRegistry.keys():
91 ConfigRegistry.delitem(k)
92
93
94class AttrDict(dict):
95 """
96 dict class that can address its keys as fields, e.g.
97 d['key'] = 1
98 assert d.key == 1
99 """
100 def __init__(self, *args, **kwargs):
101 super(AttrDict, self).__init__(*args, **kwargs)
102 self.__dict__ = self
103
104 def clone(self):
105 result = AttrDict()
106 for k, v in self.items():
107 if isinstance(v, AttrDict):
108 result[k] = v.clone()
109 else:
110 result[k] = v
111 return result
112
113
115 def __init__(self, *args, **kwargs):
116 super(Config, self).__init__(*args, **kwargs)
117
118 def loads(self, buff):
119 rv = pickle.loads(buff)
120 self.clear()
121 self.update(rv)
122 return self
123
124 def clone(self):
125 result = Config()
126 for k, v in self.items():
127 if isinstance(v, AttrDict):
128 result[k] = v.clone()
129 else:
130 result[k] = v
131 return result
132
133 def dumps(self):
134 return pickle.dumps(self)
135
136 def load(self, filename):
137 with open(expand_env(filename)) as fh:
138 self.loads(fh.read())
139 return self
140
141 def dump(self, filename):
142 with open(expand_env(filename), "w") as fh:
143 return fh.write(self.dumps())
144
145 def __str__(self):
146 return "ShipGeoConfig:\n " + "\n ".join(["%s: %s" % (k, self[k].__str__()) for k in sorted(self.keys()) if not k.startswith("_")])
__init__(self, *args, **kwargs)
register_config(name=None, base=None)
loadpys(config_string, **kwargs)
loadpy(filename, **kwargs)
__init__(self, *args, **kwargs)
dump(self, filename)
load(self, filename)
__call__(cls, *args, **kwargs)
expand_env(string)