22 pathvar = (
'DYLD_LIBRARY_PATH'
23 if sys.platform ==
'darwin' else 'LD_LIBRARY_PATH')
24 for path
in os.getenv(pathvar,
'').split(os.pathsep):
25 if not os.path.isdir(path):
28 os.path.join(path, f)
for f
in os.listdir(path)
29 if f.endswith(
'.confdb2')
30 and os.path.isfile(os.path.join(path, f))
33 for db
in [shelve.open(f,
'r')
for f
in dbfiles]:
35 if key
not in self.
_dbs:
39 return self.
_dbs[key][key]
42 return key
in self.
_dbs
45 return iter(self.
_dbs)
49 if 'GAUDICONFIG2_DB' in os.environ:
50 exec(
'from {} import {} as _DB'.
format(
51 *os.environ[
'GAUDICONFIG2_DB'].rsplit(
'.', 1)))
63 atexit.register(_fix_clean_up)
65 if sys.version_info >= (3, ):
66 maketrans = str.maketrans
68 from string
import maketrans
69 _TRANS_TABLE =
maketrans(
"<>&*,: ().",
"__rp__s___")
74 Translate a C++ type name (with templates etc.) to Python identifier.
76 return name.replace(
', ',
',').translate(_TRANS_TABLE)
81 Split a C++ qualified namespace in the tuple (top_namespace, rest) starting
82 searching the separator from pos.
84 >>> split_namespace('std::chrono::time_point')
85 ('std', 'chrono::time_point')
88 tpos = typename.find(
'<')
89 pos = typename.find(
'::')
92 if pos > 0
and (tpos < 0
or pos < tpos):
94 tail = typename[pos + 2:]
103 Helper to expose Configurables classes (from Configurables database) as
104 a tree of subpackages, each mapped to a namespace.
109 @param modulename: name of the module
110 @param root: name of the root modules (that pointing to the root C++
111 namespace), None is ewuivalent to pass modulename as root
113 self.
_log = logging.getLogger(modulename)
114 self.
_log.debug(
'initializing module %r (with root %r)', modulename,
120 assert ((
not root)
or modulename.startswith(root +
'.')), \
121 'modulename should be (indirect submodule of root)'
124 '.',
'::')
if root
else ''
125 self.
_log.debug(
'%r mapping namespace %r', modulename, self.
_namespace
132 if alt_name != cname:
135 self.
_alt_names[cname.replace(
' ',
'')] = cname
139 sys.modules[modulename] = self
141 for submodule
in self._namespaces:
149 Extract from the Configurables DB the namespaces and classes names in
150 the namespace this instance represents.
152 self.
_log.debug(
'getting list of entries under %r', self.
_namespace)
154 prefix_len = len(prefix)
159 if name.startswith(prefix):
166 self.
_log.debug(
'found %d namespaces and %d classes', len(namespaces),
168 return (namespaces, classes)
172 Helper to instantiate on demand Configurable classes.
175 fullname = (
'::'.join([self.
_namespace, name])
177 from ._configurables
import makeConfigurableClass
178 self.
_log.debug(
'generating %r (%s)', name, fullname)
183 __cpp_type__=fullname,
185 elif name.replace(
' ',
'')
in self.
_alt_names:
186 entry = getattr(self, self.
_alt_names[name.replace(
' ',
'')])
187 elif name ==
"__spec__":
189 entry = importlib.machinery.ModuleSpec(
190 name=self.__package__,
193 elif name ==
"__package__":
196 raise AttributeError(
'module {!r} has no attribute {!r}'.
format(
198 setattr(self, name, entry)
203 Return a configurable from the fully qualified type name (relative to
204 the current namespace).any
208 return getattr(self, head).
getByType(tail)
210 return getattr(self, tail)