20 from pathlib
import Path
25 if sys.platform ==
"darwin"
26 else [
"GAUDI_PLUGIN_PATH",
"LD_LIBRARY_PATH"]
28 ignored_files = set(os.environ.get(
"CONFIGURABLE_DB_IGNORE",
"").split(
","))
29 for pathvar
in pathvars:
30 for path
in os.getenv(pathvar,
"").split(os.pathsep):
34 f.absolute().as_posix()
35 for f
in Path(path).glob(
"*.confdb2")
36 if f.absolute().as_posix()
not in ignored_files
39 for db
in [shelve.open(f,
"r")
for f
in dbfiles]:
41 self.
_dbs.setdefault(key, db)
44 return self.
_dbs[key][key]
47 return key
in self.
_dbs
50 return iter(self.
_dbs)
54if "GAUDICONFIG2_DB" in os.environ:
56 "from {} import {} as _DB".
format(*os.environ[
"GAUDICONFIG2_DB"].rsplit(
".", 1))
62_TRANS_TABLE = str.maketrans(
"<>&*,: ().",
"__rp__s___")
67 Translate a C++ type name (with templates etc.) to Python identifier.
69 return name.replace(
", ",
",").translate(_TRANS_TABLE)
74 Split a C++ qualified namespace in the tuple (top_namespace, rest) starting
75 searching the separator from pos.
77 >>> split_namespace('std::chrono::time_point')
78 ('std', 'chrono::time_point')
81 tpos = typename.find(
"<")
82 pos = typename.find(
"::")
85 if pos > 0
and (tpos < 0
or pos < tpos):
87 tail = typename[pos + 2 :]
96 Helper to expose Configurables classes (from Configurables database) as
97 a tree of subpackages, each mapped to a namespace.
102 @param modulename: name of the module
103 @param root: name of the root modules (that pointing to the root C++
104 namespace), None is ewuivalent to pass modulename as root
106 self.
_log = logging.getLogger(modulename)
107 self.
_log.debug(
"initializing module %r (with root %r)", modulename, root)
112 assert (
not root)
or modulename.startswith(
114 ),
"modulename should be (indirect submodule of root)"
116 self.
_namespace = modulename[len(root) + 1 :].replace(
".",
"::")
if root
else ""
117 self.
_log.debug(
"%r mapping namespace %r", modulename, self.
_namespace or "::")
123 if alt_name != cname:
126 self.
_alt_names[cname.replace(
" ",
"")] = cname
131 sys.modules[modulename] = self
142 Extract from the Configurables DB the namespaces and classes names in
143 the namespace this instance represents.
145 self.
_log.debug(
"getting list of entries under %r", self.
_namespace)
147 prefix_len = len(prefix)
152 if name.startswith(prefix):
160 "found %d namespaces and %d classes", len(namespaces), len(classes)
162 return (namespaces, classes)
166 Helper to instantiate on demand Configurable classes.
170 from ._configurables
import makeConfigurableClass
172 self.
_log.debug(
"generating %r (%s)", name, fullname)
173 entry = makeConfigurableClass(
177 __cpp_type__=fullname,
180 elif name.replace(
" ",
"")
in self.
_alt_names:
181 entry = getattr(self, self.
_alt_names[name.replace(
" ",
"")])
182 elif name ==
"__spec__":
185 entry = importlib.machinery.ModuleSpec(
186 name=self.__package__,
189 elif name ==
"__package__":
192 raise AttributeError(
195 setattr(self, name, entry)
200 Return a configurable from the fully qualified type name (relative to
201 the current namespace).any
205 return getattr(self, head).
getByType(tail)
207 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)