20 from pathlib
import Path
22 from GaudiPluginService.cpluginsvc
import GAUDI_DEFAULT_PLUGIN_PATH
25 ignored_files = set(os.environ.get(
"CONFIGURABLE_DB_IGNORE",
"").split(
","))
26 for path
in GAUDI_DEFAULT_PLUGIN_PATH:
27 if not path
or not os.path.isdir(path):
30 f.absolute().as_posix()
31 for f
in Path(path).glob(
"*.confdb2")
32 if f.absolute().as_posix()
not in ignored_files
35 for db
in [shelve.open(f,
"r")
for f
in dbfiles]:
37 self.
_dbs.setdefault(key, db)
40 return self.
_dbs[key][key]
43 return key
in self.
_dbs
46 return iter(self.
_dbs)
50if "GAUDICONFIG2_DB" in os.environ:
52 "from {} import {} as _DB".
format(*os.environ[
"GAUDICONFIG2_DB"].rsplit(
".", 1))
58_TRANS_TABLE = str.maketrans(
"<>&*,: ().",
"__rp__s___")
63 Translate a C++ type name (with templates etc.) to Python identifier.
65 return name.replace(
", ",
",").translate(_TRANS_TABLE)
70 Split a C++ qualified namespace in the tuple (top_namespace, rest) starting
71 searching the separator from pos.
73 >>> split_namespace('std::chrono::time_point')
74 ('std', 'chrono::time_point')
77 tpos = typename.find(
"<")
78 pos = typename.find(
"::")
81 if pos > 0
and (tpos < 0
or pos < tpos):
83 tail = typename[pos + 2 :]
92 Helper to expose Configurables classes (from Configurables database) as
93 a tree of subpackages, each mapped to a namespace.
98 @param modulename: name of the module
99 @param root: name of the root modules (that pointing to the root C++
100 namespace), None is ewuivalent to pass modulename as root
102 self.
_log = logging.getLogger(modulename)
103 self.
_log.debug(
"initializing module %r (with root %r)", modulename, root)
108 assert (
not root)
or modulename.startswith(
110 ),
"modulename should be (indirect submodule of root)"
112 self.
_namespace = modulename[len(root) + 1 :].replace(
".",
"::")
if root
else ""
113 self.
_log.debug(
"%r mapping namespace %r", modulename, self.
_namespace or "::")
119 if alt_name != cname:
122 self.
_alt_names[cname.replace(
" ",
"")] = cname
127 sys.modules[modulename] = self
138 Extract from the Configurables DB the namespaces and classes names in
139 the namespace this instance represents.
141 self.
_log.debug(
"getting list of entries under %r", self.
_namespace)
143 prefix_len = len(prefix)
148 if name.startswith(prefix):
156 "found %d namespaces and %d classes", len(namespaces), len(classes)
158 return (namespaces, classes)
162 Helper to instantiate on demand Configurable classes.
166 from ._configurables
import makeConfigurableClass
168 self.
_log.debug(
"generating %r (%s)", name, fullname)
169 entry = makeConfigurableClass(
173 __cpp_type__=fullname,
176 elif name.replace(
" ",
"")
in self.
_alt_names:
177 entry = getattr(self, self.
_alt_names[name.replace(
" ",
"")])
178 elif name ==
"__spec__":
181 entry = importlib.machinery.ModuleSpec(
182 name=self.__package__,
185 elif name ==
"__package__":
188 raise AttributeError(
191 setattr(self, name, entry)
196 Return a configurable from the fully qualified type name (relative to
197 the current namespace).any
201 return getattr(self, head).
getByType(tail)
203 return getattr(self, tail)
GAUDI_API std::string format(const char *,...)
MsgStream format utility "a la sprintf(...)".
getByType(self, typename)
__init__(self, modulename, root=None)
_normalize_cpp_type_name(name)
split_namespace(typename)