12Modify the PyDBObj and PyDBArray classes to return read only objects to prevent
13accidental changes to the conditions data.
15This module does not contain any public functions or variables, it just
16modifies the ROOT interfaces for PyDBObj and PyDBArray to only return read only
29_ROOT_kIsPublic = 0x00000200
31_ROOT_kIsStatic = 0x00004000
33_ROOT_kIsConstMethod = 0x10000000
37def 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 upon
import of the ROOT module.
46 def pythonization_impl(fn):
48 The real decorator. This structure is adopted to deal
with parameters
50 Function that implements some pythonization.
51 The function must accept two parameters: the
class
52 to be pythonized
and the name of that
class.
55 cppyy.py.add_pythonization(fn, namespace)
58 return pythonization_impl
61def _make_tobject_const(obj):
63 Make a TObject const: Disallow setting any attributes and calling any
64 methods which are
not declared
as const. This affects any reference to this
65 object
in python
and stays permanent. Once called this particular instance
66 will be readonly everywhere
and will remain like this.
68 This
is done by replacing all setter functions
with function objects that
69 just
raise an attribute error when called. The
class will be still the same
77 non_const = [m.GetName()
for m
in obj.Class().GetListOfMethods()
if (m.Property() & _ROOT_kIsPublic)
78 and not (m.Property() & (_ROOT_kIsConstMethod | _ROOT_kIsStatic))]
79 except AttributeError:
80 raise ValueError(f
"Object does not have a valid dictionary: {obj!r}")
83 for name
in non_const:
84 def __proxy(*args, **argk):
85 """raise attribute error when called"""
86 raise AttributeError(f
"{obj} is readonly and method '{name}' is not const")
88 setattr(obj, name, __proxy)
94def _PyDBArray__iter__(self):
95 """Provide iteration over Belle2::PyDBArray. Needs to be done here since we
96 want to make all returned classes read only"""
97 for i
in range(len(self)):
101@pythonization(namespace="Belle2")
102def _pythonize(klass, name):
103 """Adjust the python interface of some Py* classes"""
104 if not name.startswith(
"Py"):
107 if name ==
"PyDBObj":
110 klass.obj =
lambda self: _make_tobject_const(self._obj())
113 klass.__getattr__ =
lambda self, name: getattr(self.obj(), name)
116 klass.__iter__ =
lambda self: iter(self.obj())
117 elif name ==
"PyDBArray":
119 klass.__getitem__ =
lambda self, i: _make_tobject_const(self._get(i))
121 klass.__iter__ = _PyDBArray__iter__
122 elif name ==
"PyStoreObj":
125 klass.__iter__ =
lambda self: iter(self.obj())