54 Basic node class, so we can get all the egregious flags from a
55 flags object, and use, and pass round, the individual nodes, as
56 actual nodes without all the nonsense limitations of using the
60 def __init__(self, name="root", flags=None, root=None ):
61 object.__setattr__(self,
"_lockstate", _UNLOCKED)
62 object.__setattr__(self,
"_name", name)
63 object.__setattr__(self,
"_children", {})
64 object.__setattr__(self,
"_flags", flags)
65 object.__setattr__(self,
"_root", root)
69 if name
in self.
_children :
raise AttributeError(f
"node {name} already exists")
71 if type(current).__name__ ==
"CfgFlag":
74 object.__setattr__(self, name, value)
77 value = object.__getattribute__(self, name)
78 if type(value).__name__ ==
"CfgFlag":
79 flags = object.__getattribute__(self,
"_flags")
80 return value.get(flags)
84 """ will attempt a dynamic load from flags if need be """
89 if name
in self.
_root._children :
return self.
_root._children[name]
91 if name
in self.
_root._children :
return self.
_root._children[name]
96 raise AttributeError(f
"no attribute {name}")
110 def lock(self, lockstate=_LOCKED):
111 for node
in self.
nodes() : node.lock(lockstate)
112 object.__setattr__(self,
"_lockstate", lockstate)
117 object.__setattr__(self,
"_lockstate", _UNLOCKED)
118 for node
in self.
nodes(): node.unlock()
121 self.
lock(_LOCKED_FOREVER)
130 if self.
_lockstate == _LOCKED_FOREVER :
raise RuntimeError(f
"Node {self._name} is permanently locked; ")
133 if self.
_lockstate == _LOCKED :
raise RuntimeError(f
"Node {self._name} is locked; ")
134 if self.
_lockstate == _LOCKED_FOREVER :
raise RuntimeError(f
"Node {self._name} is permanently locked; ")
137 """ load dynamic flags - can only load flags on the root node """
142 if flags
is None :
raise AttributeError(f
"no attribute {name}")
144 object.__setattr__(self,
"_lockstate", _UNLOCKED)
146 if name
in flags._loaded :
return self.
_stragglers(flags)
147 if name
in flags._dynaflags :
return self.
_addDynaFlags(name)
148 for key
in flags._dynaflags :
153 if lockstate != _UNLOCKED : self.
lock(lockstate)
157 self._flags._loadDynaFlags(name)
161 for key, val
in self._flags._flagdict.items() :
171 if self.
_root is rootnode :
return
172 object.__setattr__(self,
"_root", rootnode )
173 for node
in self.
nodes() : node._setrootnode(rootnode)
178 def add(self, attr_name, value):
179 """ add an attribute to this node """
180 setattr(self, attr_name, value)
183 """ addFlag method like that in the egregious flags """
185 if flags
is not None and self._flags
is None : node._flags = flags
186 names = tag.split(
".")
187 for name
in names[:-1]:
188 node = node._addNewNode(name, flags )
189 if unlock : object.__setattr__( node,
"_lockstate", _UNLOCKED )
190 if flags
is not None : node._flags = flags
191 if names[-1]
in node.__dict__ :
return False
193 setattr(node, names[-1], value)
198 raise KeyError(f
"flag {tag} already exists")
204 if isinstance(item, Node) :
return self.
_addNode(item)
205 if isinstance(item, str) :
return self.
_addNewNode(item, flags)
206 raise TypeError(f
"Cannot construct node from type {type(item).__name__}, value {item}")
209 """ add a new child node """
211 if name
in self.
__dict__:
raise AttributeError(f
"attribute {name} already exists")
215 if flags
is not None : node._flags = flags
219 """ an en existing node as a child node """
222 if name
in self.
__dict__:
raise AttributeError(f
"attribute {name} already exists")
225 if node._root
and rootnode
is not node._root :
226 raise RuntimeError(f
"cannot add node {name} from a different tree")
228 if not node._root : node._setrootnode( rootnode )
232 return hasattr( self, name )
241 parts = name.split(
'.')
243 for part
in parts[:-1]:
244 if not node.hasNode(part) :
return False
246 return node.hasFlag(parts[-1])
252 for key, value
in self.
__dict__.items():
253 if not key.startswith(
"_"):
254 yield key, getattr(self, key)
258 raise RuntimeError(f
"So such child: {name}")
263 elif name
in self.
__dict__ : object.__delattr__(self, name)
264 else :
raise AttributeError(f
"Node {self._name} has no member {name}")
268 raise RuntimeError(f
"name {newname} already in node")
276 """Return an independent copy" of this node"""
278 if name
is not None : newnode =
Node(name)
279 else: newnode =
Node(self._name)
281 for key, value
in self.
__dict__.items():
282 if key
in {
"_name",
"_children",
"_lockstate",
"_root" } :
continue
283 setattr(newnode, key, value)
285 for node
in self.
nodes():
288 newnode._addNode(child)
294 print( f
"{spacer}{self._name} (Node)" )
295 if spacer==
"" : spacer =
"|__ "
296 else: spacer=f
" {spacer}"
297 for key, value
in self.
__dict__.items():
298 if key
in {
"_name",
"_children",
"_lockstate",
"_flags",
"_root"} :
continue
299 print( f
"{spacer}{key}\t: {value}" )
300 for node
in self.
nodes() : node.print( spacer )
308 warnings.warn(
"cloneAndReplace() is unnecessary for Node flags; "
309 "use the appropriate Node directly",
310 RuntimeWarning, stacklevel=2 )
313 return self.
_rootnode()._flags.cloneAndReplace( targetname, flagname )
317 """ check whether the flags have an actual item with this name
318 NB using hasFlag(name) is really dengerous, as that seems to
319 actually evaluate any actual functions ? shouldn't
320 something like that be called testFlag() ?
322 return name
not in flags._flagdict
327 """ take an egregious flags list and convert to a lovely tree
328 or, if it is a lovely tree already, just hand it back
331 if isinstance( flags, Node ) :
return flags
335 for tag, value
in flags._flagdict.items():
336 root.addFlag( tag, value, flags )
344 """ take a lovely tree and convert to an egregious flags list,
345 only adding items that are not in the original flags list """
347 for key, value
in node.__dict__.items():
348 if key
in {
"_name",
"_children",
"_lockstate",
"_flags",
"_root" } :
continue
349 name = f
"{domain}.{key}"
350 if notDefined(flags,name) : flags.addFlag( name, value )
352 for n
in node.nodes() :
359 """ Escape hatch in case the user needs to access a node
360 from the top node that has the Same Name, as a node
362 return flags._rootnode()
virtual void lock()=0
Interface to allow an object to lock itself when made const in SG.
node(node *n=0, const std::string &d="", TObject *t=0)
void name(const std::string &n)
lock(self, lockstate=_LOCKED)
addFlag(self, tag, value, flags=None)
_setrootnode(self, rootnode)
addNode(self, item, flags=None)
_addNewNode(self, str name, flags=None)
__init__(self, name="root", flags=None, root=None)
cloneAndReplace(self, targetname, flagname)
__setattr__(self, name, value)
_addDynaFlags(self, name)
_addFlagImpl(self, tag, value, flags=None, unlock=False)
_stragglers(self, flags, dbg="")
_addFlagUnlock(self, tag, value, flags=None)
add(self, attr_name, value)
__getattribute__(self, name)
return self._root._loadflags(name) _root
_fail_if_locked_forever(self)
raise AttributeError(f) _children
raise AttributeError(f) __dict__
rename(self, name, newname)
T * get(TKey *tobj)
get a TObject* from a TKey* (why can't a TObject be a TKey?)
decode_flags(flags, domain=None)
update_flags(flags, node, domain="")