ATLAS Offline Software
Loading...
Searching...
No Matches
Control/AthenaServices/python/Dso.py
Go to the documentation of this file.
1# Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
2
3# @file: AthenaServices/python/Dso.py
4# @purpose: simple interface to the rootmap files to easily locate reflex
5# dictionaries (and load them)
6# @author: Sebastien Binet <binet@cern.ch>
7# @date: September 2008
8
9
10__version__ = "$Revision: 1.12 $"
11__author__ = "Sebastien Binet <binet@cern.ch>"
12__doc__ = """\
13simple interface to the rootmap files to easily locate reflex dictionaries \
14(and load them)
15"""
16
17__all__ = [
18 'registry',
19 ]
20
21
22import os
23from PyUtils import Dso as _Dso
24from PyUtils.Dso import _aliases
25
26try:
27 # attempt at fixing up the pyroot iterators...
28 import RootUtils.PyROOTFixes # noqa: F401
29except ImportError:
30 pass
31
32_cpp_builtins = (
33 'char', 'unsigned char', 'signed char',
34 'signed',
35 'short int', 'short signed', 'short signed int',
36 'short', 'unsigned short', 'signed short',
37 'int', 'unsigned int',
38
39 'long int',
40 'long signed int',
41 'signed long int',
42
43 'long',
44 'long signed', 'signed long',
45 'unsigned long',
46 'unsigned long int',
47 'long unsigned int',
48
49 'long long',
50 'long long int',
51 'unsigned long long',
52 'longlong',
53
54 # no clue from where this one comes from, who's requesting it nor who
55 # got the alien naming scheme idea...
56 'ulonglong',
57
58 'float',
59 'double',
60 'long double',
61 'bool',
62 )
63
64
65
66class RflxEnums(object):
67 S = 4 # SCOPED
68 SF = 5 # SCOPED|FINAL
69 SQ = 6 # SCOPED|QUALIFIED
70 SFQ = 7 # SCOPED|FINAL|QUALIFIED
71 DICTSCOPE =SF
72
73class DsoDb(_Dso.PyDsoDb):
74 """
75 The repository of 'rootmap' files (location, content,...) and a set of
76 operations one can apply on them (load dict, query dicts,...)
77 """
78 def __init__(self):
79 super(DsoDb, self).__init__('AthenaDsoDb')
80 import AthenaCommon.Logging
81 self.msg = AthenaCommon.Logging.logging.getLogger("AthenaDsoDb")
82 #self.msg.setLevel(AthenaCommon.Logging.logging.VERBOSE)
83
84 # inject the known aliases NOW
85 for k,v in _aliases.iteritems():
86 try:
87 self.db[k] = self.db[v]
88 except KeyError:
89 self.msg.info("could not install alias [%s] -> [%s]", k,v)
90 # make sure we'll be able to load dicts
91 import cppyy
92 #self._load_dict = cppyy.loadDict
93 self._rflx_type = cppyy.gbl.RootType.ByName
94 return
95
96 def has_type (self, typename):
97 if typename in _cpp_builtins:
98 return True
99 # need to massage a bit the typename to match ROOT naming convention
100 typename = self._to_rootmap_name (typename)
101 return self.db.has_key (typename) or \
102 self.pf.has_key (typename)
103
104 def load_type (self, typename):
105 rflx_type = self.rflx_type(typename)
106 if not(rflx_type is None):
107 rflx_name = rflx_type.Name(RflxEnums.DICTSCOPE)
108 if rflx_name != '':
109 return rflx_name
110 return None
111
112 def rflx_type(self, typename):
113 _rootmap_name = self._to_rootmap_name (typename)
114 _rflx_name = self._to_rflx_name (typename)
115 self.msg.verbose("------- loading type [%s]...", typename)
116
117 if typename in _cpp_builtins:
118 self.msg.verbose(" ==> [ok] (builtin)")
119 return self._rflx_type (_rflx_name)
120
121 if not self.has_type (_rootmap_name):
122 self.msg.verbose(" ==> [err] (no '%s')",_rootmap_name)
123 return None
124 libs = (self.db.get(_rootmap_name) or
125 self.pf.get(_rootmap_name))
126 if libs is None or len(libs) <= 0:
127 return None
128 from ctypes import cdll
129 _load = cdll.LoadLibrary
130 from cppyy import loadDict as _load
131 lib = libs[0]
132 self.msg.verbose("... %s",lib)
133 _load (os.path.basename(lib.strip()))
134 self.msg.verbose("... %s [done]",lib)
135 self.msg.verbose(" ==> [ok]")
136
137 # give the non-massaged name to reflex as this is what it expects
138 # ...ROOT is sooo self-consistent...
139 rflx_type = self._rflx_type (_rflx_name)
140 if rflx_type.Name() != '':
141 return rflx_type
142 return None
143
144
145 def visit(self, typename, visitor=None, ctx=None):
146 self.msg.verbose("=== visiting %s", typename)
147 if ctx is None:
148 ctx = set()
149 if isinstance (typename, str):
150 rflx_type = self.load_type (typename)
151 typename = rflx_type.Name (RflxEnums.DICTSCOPE)
152 else:
153 rflx_type = typename
154
155 if not rflx_type:
156 self.msg.verbose("**warning** no dict for [%s] !!", typename)
157 return ctx
158
159 ctx.add (typename)
160 if visitor:
161 visitor (rflx_type)
162
163 if rflx_type.IsClass() or rflx_type.IsStruct():
164 for i in range(rflx_type.BaseSize()):
165 itype = rflx_type.BaseAt(i).ToType()
166 itype_name = itype.Name(RflxEnums.DICTSCOPE)
167 if itype_name != '' and not (itype_name in ctx):
168 self.load_type (itype_name)
169 ctx.add (itype_name)
170 ctx.update (self.visit (itype, visitor, ctx))
171
172 for i in range(rflx_type.DataMemberSize()):
173 itype = rflx_type.DataMemberAt (i).TypeOf()
174 itype = itype.RawType() if itype.IsPointer() else itype
175 itype_name = itype.Name(RflxEnums.DICTSCOPE)
176 if itype_name != '' and not (itype_name in ctx):
177 self.load_type (itype_name)
178 ctx.add (itype_name)
179 # restore original type
180 itype = rflx_type.DataMemberAt (i).TypeOf()
181 itype_name = itype.Name(RflxEnums.DICTSCOPE)
182 ctx.update (self.visit (itype, visitor, ctx))
183 return ctx
184
185 pass # class DsoDb
186
187
188registry = _Dso.DsoDb()
STL class.
T * get(TKey *tobj)
get a TObject* from a TKey* (why can't a TObject be a TKey?)
Definition hcg.cxx:130
bool verbose
Definition hcg.cxx:73