mirror of
https://github.com/rdkit/rdkit.git
synced 2026-06-05 22:04:27 +08:00
197 lines
4.0 KiB
Python
Executable File
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)
|
|
|
|
|