12 Modify the PyDBObj and PyDBArray classes to return read only objects to prevent
13 accidental changes to the conditions data.
15 This module does not contain any public functions or variables, it just
16 modifies the ROOT interfaces for PyDBObj and PyDBArray to only return read only
29 _ROOT_kIsPublic = 0x00000200
31 _ROOT_kIsStatic = 0x00004000
33 _ROOT_kIsConstMethod = 0x10000000
37 def pythonization(lazy=True, namespace=""):
39 Pythonizor decorator to be used in pythonization modules for pythonizations.
40 These pythonizations functions are invoked upon usage of the class.
44 If lazy is true, the class is pythonized upon first usage, otherwise
45 upon import of the ROOT module.
47 def pythonization_impl(fn):
49 The real decorator. This structure is adopted to deal with parameters
51 Function that implements some pythonization.
52 The function must accept two parameters: the class
53 to be pythonized and the name of that class.
56 cppyy.py.add_pythonization(fn, namespace)
59 return pythonization_impl
62 def _make_tobject_const(obj):
64 Make a TObject const: Disallow setting any attributes and calling any
65 methods which are not declared as const. This affects any reference to this
66 object in python and stays permanent. Once called this particular instance
67 will be readonly everywhere and will remain like this.
69 This is done by replacing all setter functions with function objects that
70 just raise an attribute error when called. The class will be still the same
78 non_const = [m.GetName()
for m
in obj.Class().GetListOfMethods()
if (m.Property() & _ROOT_kIsPublic)
79 and not (m.Property() & (_ROOT_kIsConstMethod | _ROOT_kIsStatic))]
80 except AttributeError:
81 raise ValueError(
"Object does not have a valid dictionary: %r" % obj)
84 for name
in non_const:
85 def __proxy(*args, **argk):
86 """raise attribute error when called"""
87 raise AttributeError(f
"{obj} is readonly and method '{name}' is not const")
89 setattr(obj, name, __proxy)
95 def _PyDBArray__iter__(self):
96 """Provide iteration over Belle2::PyDBArray. Needs to be done here since we
97 want to make all returned classes read only"""
98 for i
in range(len(self)):
102 @pythonization(namespace="Belle2")
103 def _pythonize(klass, name):
104 """Adjust the python interface of some Py* classes"""
105 if not name.startswith(
"Py"):
108 if name ==
"PyDBObj":
111 klass.obj =
lambda self: _make_tobject_const(self._obj())
114 klass.__getattr__ =
lambda self, name: getattr(self.obj(), name)
117 klass.__iter__ =
lambda self: iter(self.obj())
118 elif name ==
"PyDBArray":
120 klass.__getitem__ =
lambda self, i: _make_tobject_const(self._get(i))
122 klass.__iter__ = _PyDBArray__iter__
123 elif name ==
"PyStoreObj":
126 klass.__iter__ =
lambda self: iter(self.obj())