Files
rdkit/Python/VLib/Node.py

197 lines
4.0 KiB
Python
Executable File

# $Id$
#
# Copyright (C) 2003-2006 Rational Discovery LLC
# All Rights Reserved
#
import sys
class VLibNode(object):
""" base class for all virtual library nodes,
defines minimal required interface
"""
def __init__(self,*args,**kwargs):
self._children = []
self._parents = []
#------------------------------------
#
# Iteration
#
def __iter__(self):
""" part of the iterator interface """
self.reset()
return self
def next(self):
""" part of the iterator interface
raises StopIteration on failure
"""
pass
def reset(self):
""" resets our iteration state
"""
for parent in self.GetParents():
parent.reset()
#------------------------------------
#
# Library graph operations
# Probably most of these won't need to be reimplemented in
# child classes
#
def AddChild(self,child,notify=1):
"""
>>> p1 = VLibNode()
>>> p2 = VLibNode()
>>> c1 = VLibNode()
>>> p1.AddChild(c1)
>>> len(c1.GetParents())
1
>>> len(p1.GetChildren())
1
>>> p2.AddChild(c1,notify=0)
>>> len(c1.GetParents())
1
>>> len(p2.GetChildren())
1
>>> c1.AddParent(p2,notify=0)
>>> len(c1.GetParents())
2
>>> len(p2.GetChildren())
1
"""
self._children.append(child)
if notify:
child.AddParent(self,notify=0)
def RemoveChild(self,child,notify=1):
"""
>>> p1 = VLibNode()
>>> c1 = VLibNode()
>>> p1.AddChild(c1)
>>> len(c1.GetParents())
1
>>> len(p1.GetChildren())
1
>>> p1.RemoveChild(c1)
>>> len(c1.GetParents())
0
>>> len(p1.GetChildren())
0
"""
self._children.remove(child)
if notify:
child.RemoveParent(self,notify=0)
def GetChildren(self):
return tuple(self._children)
def AddParent(self,parent,notify=1):
"""
>>> p1 = VLibNode()
>>> p2 = VLibNode()
>>> c1 = VLibNode()
>>> c1.AddParent(p1)
>>> len(c1.GetParents())
1
>>> len(p1.GetChildren())
1
>>> c1.AddParent(p2,notify=0)
>>> len(c1.GetParents())
2
>>> len(p2.GetChildren())
0
>>> p2.AddChild(c1,notify=0)
>>> len(c1.GetParents())
2
>>> len(p2.GetChildren())
1
"""
self._parents.append(parent)
if notify:
parent.AddChild(self,notify=0)
def RemoveParent(self,parent,notify=1):
"""
>>> p1 = VLibNode()
>>> c1 = VLibNode()
>>> p1.AddChild(c1)
>>> len(c1.GetParents())
1
>>> len(p1.GetChildren())
1
>>> c1.RemoveParent(p1)
>>> len(c1.GetParents())
0
>>> len(p1.GetChildren())
0
"""
self._parents.remove(parent)
if notify:
parent.RemoveChild(self,notify=0)
def GetParents(self):
return tuple(self._parents)
def Destroy(self,notify=1,propagateDown=0,propagateUp=0):
"""
>>> p1 = VLibNode()
>>> p2 = VLibNode()
>>> c1 = VLibNode()
>>> c2 = VLibNode()
>>> p1.AddChild(c1)
>>> p2.AddChild(c1)
>>> p2.AddChild(c2)
>>> len(c1.GetParents())
2
>>> len(c2.GetParents())
1
>>> len(p1.GetChildren())
1
>>> len(p2.GetChildren())
2
>>> c1.Destroy(propagateUp=1)
>>> len(p2.GetChildren())
0
>>> len(c1.GetParents())
0
>>> len(c2.GetParents())
0
"""
#sys.stderr.write('DESTROY: %s\n'%(str(self)))
if hasattr(self,'_destroyed'): return
self._destroyed=1
if notify:
for o in self.GetChildren():
o.RemoveParent(self,notify=0)
if propagateDown:
o.Destroy(notify=1,propagateDown=1,propagateUp=propagateUp)
for o in self.GetParents():
#sys.stderr.write('\tparent: %s\n'%(str(o)))
o.RemoveChild(self,notify=0)
if propagateUp:
o.Destroy(notify=1,propagateDown=propagateDown,propagateUp=1)
self._children = []
self._parents = []
#------------------------------------
#
# doctest boilerplate
#
def _test():
import doctest,sys
return doctest.testmod(sys.modules["__main__"])
if __name__ == '__main__':
import sys
failed,tried = _test()
sys.exit(failed)