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 )
231 def has(self, name, value=None ):
232 if value
is None :
return hasattr( self, name )
233 return hasattr( self, name )
and getattr( self, name ) == value
242 parts = name.split(
'.')
244 for part
in parts[:-1]:
245 if not node.hasNode(part) :
return False
247 return node.hasFlag(parts[-1])
253 for key, value
in self.
__dict__.items():
254 if not key.startswith(
"_"):
255 yield key, getattr(self, key)
259 raise RuntimeError(f
"So such child: {name}")
264 elif name
in self.
__dict__ : object.__delattr__(self, name)
265 else :
raise AttributeError(f
"Node {self._name} has no member {name}")
269 raise RuntimeError(f
"name {newname} already in node")
277 """Return an independent copy" of this node"""
279 if name
is not None : newnode =
Node(name)
280 else: newnode =
Node(self._name)
282 for key, value
in self.
__dict__.items():
283 if key
in {
"_name",
"_children",
"_lockstate",
"_root" } :
continue
284 setattr(newnode, key, value)
286 for node
in self.
nodes():
289 newnode._addNode(child)
295 print( f
"{spacer}{self._name} (Node)" )
296 if spacer==
"" : spacer =
"|__ "
297 else: spacer=f
" {spacer}"
298 for key, value
in self.
__dict__.items():
299 if key
in {
"_name",
"_children",
"_lockstate",
"_flags",
"_root"} :
continue
300 print( f
"{spacer}{key}\t: {value}" )
301 for node
in self.
nodes() : node.print( spacer )
309 warnings.warn(
"cloneAndReplace() is unnecessary for Node flags; "
310 "use the appropriate Node directly",
311 RuntimeWarning, stacklevel=2 )
314 return self.
_rootnode()._flags.cloneAndReplace( targetname, flagname )
318 """ check whether the flags have an actual item with this name
319 NB using hasFlag(name) is really dengerous, as that seems to
320 actually evaluate any actual functions ? shouldn't
321 something like that be called testFlag() ?
323 return name
not in flags._flagdict
328 """ take an egregious flags list and convert to a lovely tree
329 or, if it is a lovely tree already, just hand it back
332 if isinstance( flags, Node ) :
return flags
336 for tag, value
in flags._flagdict.items():
337 root.addFlag( tag, value, flags )
345 """ take a lovely tree and convert to an egregious flags list,
346 only adding items that are not in the original flags list """
348 for key, value
in node.__dict__.items():
349 if key
in {
"_name",
"_children",
"_lockstate",
"_flags",
"_root" } :
continue
350 name = f
"{domain}.{key}"
351 if notDefined(flags,name) : flags.addFlag( name, value )
353 for n
in node.nodes() :
360 """ Escape hatch in case the user needs to access a node
361 from the top node that has the Same Name, as a node
363 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)
has(self, name, value=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="")