1 """A Node is an object which autmatically manages it's owner(s).
3 A Node should alweys be stored in attribute members declared as
4 NodeReference or as member of a NodeMap or NodeList."""
14 def _addOwner(self,owner):
15 self._owners.append(weakref.ref(owner,self._delRef))
17 def _delOwner(self,owner):
18 for i in range(len(self._owners)):
19 if self._owners[i]() is owner:
23 def _delRef(self,ref):
24 for i in range(len(self._owners)):
25 if self._owners[i] is ref:
30 return ( x() for x in self._owners )
33 if self._owners and self._owners[0]() is not None:
34 return self._owners[0]()
37 owners = property(_owners, None, None, None)
38 owner = property(_owner, None, None, None)
44 return '__node_elt_%d' % id_index
46 def NodeReference(id=None):
47 if id is None : id = _make_id()
48 return property(lambda self, id=id: getattr(self,id,None),
49 lambda self, node, id=id: _NodeReference_set(self,node,id),
53 def _NodeReference_set(self, node, id):
54 old = getattr(self,id,None)
55 if old is not None : old._delOwner(self)
57 if node is not None : node._addOwner(self)
62 def __init__(self, owner):
64 self._owner = weakref.ref(owner)
66 def __setitem__(self, key, node):
69 else: v._delOwner(self._owner())
70 dict.__setitem__(self, key, node)
71 node._addOwner(self._owner())
73 def __delitem__(self, key):
76 else: v._delOwner(self._owner())
77 dict.__delitem__(self,key)
81 for v in self.itervalues() : v._delOwner(owner)
84 def setdefault(self, key, node):
85 if not self.has_key(key) : self[key] = node
93 try: k = self.iterkeys().next()
94 except StopIteration: raise KeyError, 'popitem(): dictionary is empty'
95 return (k, self.pop(k))
97 def update(self, *args, **kws):
98 for k,v in dict(*args,**kws).iteritems() : self[k] = v
100 def NodeMap(id=None):
101 if id is None : id = _make_id()
102 return property(lambda self, id=id : _NodeMap_get(self, id),
103 lambda self, elts, id=id : _NodeMap_set(self, elts, id),
106 def _NodeMap_get(self, id):
107 if not hasattr(self, id) : setattr(self, id, _NodeMap(self))
108 return getattr(self, id)
110 def _NodeMap_set(self, elts, id):
111 if hasattr(self, id) : getattr(self, id).clear()
112 else : setattr(self, id, _NodeMap(self))
113 getattr(self, id).update(elts)
116 class _NodeList(list):
118 def __init__(self, owner):
120 self._owner = weakref.ref(owner)
122 def __setitem__(self, index, node):
123 if type(index) is not slice:
124 self[index] # throw IndexError if index invalid
125 index = slice(index,index+1,None)
127 owner = self._owner()
128 for i in range(*index.indices(len(self))) : self[i]._delOwner(owner)
130 list.__setitem__(self, index, node)
132 for i in range(*index.indices(len(self))) : self[i]._addOwner(owner)
135 for n in node : n._addOwner(owner)
137 def __delitem__(self, index):
138 if type(index) is not slice:
139 self[index] # throw IndexError if index invalid
140 index = slice(index,index+1,None)
141 self.__setitem__(index,[])
143 def __setslice__(self, i, j, seq):
144 self[max(0, i):max(0, j):] = seq
146 def __delslice__(self, i, j):
147 del self[max(0, i):max(0, j):]
149 def append(self, node):
150 self[len(self):len(self)] = [node]
152 def extend(self, nodes):
153 self[len(self):len(self)] = nodes
155 def insert(self, index, node):
156 self[index:index] = [node]
158 def pop(self, index=None):
159 if index is None : index = len(self)-1
164 def remove(self, node):
165 del self[self.index(node)]
167 def NodeList(id=None):
168 if id is None : id = _make_id()
169 return property(lambda self, id=id : _NodeList_get(self, id),
170 lambda self, elts, id=id : _NodeList_set(self, elts, id),
173 def _NodeList_get(self, id):
174 if not hasattr(self, id) : setattr(self, id, _NodeList(self))
175 return getattr(self, id)
177 def _NodeList_set(self, elts, id):
178 if hasattr(self, id) : del getattr(self, id)[:]
179 else : setattr(self, id, _NodeList(self))
180 getattr(self, id).extend(elts)