CMS 3D CMS Logo

CMSSW_4_4_3_patch1/src/PhysicsTools/PythonAnalysis/python/iterators.py

Go to the documentation of this file.
00001 # decorator for adding iterators to container like objects
00002 # NOTE: EventBranch._readData has to be taken care of at another place!
00003 
00004 #import cmserror
00005 
00006 def addIterator(obj):
00007     """function for adding iterators to objects""" 
00008     if not hasattr(obj, "__iter__"):
00009         if hasattr(obj, "size"):
00010             obj.__iter__ = iteratorForSizedObjects
00011         else:
00012             try:
00013               begin, end = _findIterators(obj)
00014             except:
00015               return obj  
00016             if not hasattr(obj, "_begin") and hasattr(obj, "_end"):
00017                 obj._begin = begin
00018                 obj._end = end
00019                 obj.__iter__ = iteratorForBeginEnd
00020         #else:
00021         #    obj.__iter__ = EmptyIterator
00022     return obj
00023 
00024 
00025 def iteratorForSizedObjects(self):
00026     """dynamically added iterator"""
00027     entries = container.size()
00028     for entry in xrange(entries):
00029         yield obj[entry]
00030   
00031         
00032 def iteratorForBeginEnd(self):
00033     """dynamically added iterator"""
00034     it = self._begin
00035     while (it != self.end):
00036         yield begin.__deref__()  #*b
00037         begin.__preinc__()       #++b
00038 
00039 
00040 def emptyIterator(self):
00041     """empty iterator"""
00042     raise cmserror("Automatic iterator search failed for %s. Either it is no iterable or it has multiple iterator possibilites. Please use loop(begin, end) instead." %obj )
00043 
00044 
00045 # automatic detection of iterators.      
00046 def _findIterators(obj):
00047     objDict = obj.__dict__
00048     _beginNames = [name for name in objDict.keys() if "begin" in 
00049 name.lower()]
00050     _endNames = [name for name in objDict.keys() if "end" in name.lower()]
00051     if len(_beginNames)==1 and len(_endNames)== 1 and _beginNames[0].lower().replace("begin","") == _endNames[0].lower().replace("end",""):  
00052         return objDict[_beginNames[0]], objDict[_endNames[0]]
00053     else:
00054         return False
00055         
00056         
00057         
00058 ##########################
00059 if __name__ == "__main__":
00060 
00061     import unittest
00062     class TestIterators(unittest.TestCase):
00063     
00064         def testFindIterators(self):
00065             class A(object):
00066                 pass
00067             a = A()
00068             a.BeGin_foo = 1
00069             a.EnD_foo = 100
00070             self.assertEqual(_findIterators(a),(1,100))
00071             a.begin_bar = 1
00072             a.end_bar = 100
00073             self.failIf(_findIterators(a))
00074                   
00075         def testAddIterator(self):
00076             # test for size types
00077             class A(object):
00078                 size = 3
00079             a = A()
00080             a = addIterator(a)
00081             self.assert_(hasattr(a, "__iter__"))
00082             # test if __iter__ already there
00083             class B(object):
00084                 def __iter__(self):
00085                     return True
00086             b = B()
00087             b = addIterator(b)
00088             self.assert_(b.__iter__())
00089             
00090         
00091     unittest.main()
00092 
00093