CMS 3D CMS Logo

parseConfig.py

Go to the documentation of this file.
00001 #import cmsconfigure as cms
00002 import FWCore.ParameterSet.parsecf.pyparsing as pp
00003 import FWCore.ParameterSet.Config as cms
00004 from FWCore.ParameterSet.DictTypes import SortedKeysDict
00005 from Mixins import PrintOptions
00006 import copy
00007 # Questions
00008 #  If an include includes a parameter already defined is that an error?
00009 #  If a 'using' block includes a parameter already defined, is that an error?
00010 #    No, and the 'using' wins. But what is the intended behavior?
00011 #  If two includes include the same parameter, is that an error?
00012 #  if two 'using' blocks include the same parameter, is that an error?
00013 #  How does 'using' with a block differ from 'using' with a PSet?
00014 #    there is no difference except the PSet will wind up in the parameter set database
00015 #  if we have two 'block' statements with the same name in same scope is that an error?
00016 #    Answer: no and the second block wins
00017 #    NOTE: two of 'any' type with the same label is presently allowed!
00018 #    UPDATE: labels are not enforced to be unique in the C++ parser
00019 #    UPDATE of UPDATE: this has been fixed
00020 
00021 #Processing order
00022 #  1) check for multiple inclusion of the same block can be done once the block is 'closed'
00023 #     the check must be done recursively
00024 #     NOTE: circular inclusions of a file are an error
00025 #  2)
00026 
00027 #keeps track of which files we are parsing
00028 _fileStack = ["{config}"]
00029 
00030 def _validateLabelledList(params):
00031     """enforces the rule that no label can be used more than once
00032     and if an include is done more than once we remove the duplicates
00033     """
00034     l = params[:]
00035     l.sort( lambda x,y:cmp(x[0],y[0]))
00036     previous=None
00037     toRemove = []
00038     for item in l:
00039         if previous and item[0]==previous:
00040             if type(item[1]) == _IncludeNode:
00041                 toRemove.append(item[0])
00042             elif hasattr(item[1],'multiplesAllowed') and item[1].multiplesAllowed:
00043                 continue
00044             else:
00045                 raise RuntimeError("multiple items found with label:"+item[0])
00046         previous = item[0]
00047     for remove in toRemove:
00048         for index,item in enumerate(params):
00049             if item[0] == remove:
00050                 del params[index]
00051                 break
00052     return params
00053 
00054 
00055 class _DictAdapter(object):
00056     def __init__(self,d, addSource=False):
00057         """Lets a dictionary be looked up by attributes"""
00058         #copy 'd' since we need to be able to lookup a 'source' by
00059         # it's type to do replace but we do NOT want to add it by its
00060         # type to the final Process
00061         self.__dict__['d'] = d
00062         if addSource and self.d.has_key('source'):
00063             self.d[d['source'].type_()]=d['source']
00064     def __setattr__(self,name,value):
00065         self.d[name]=value
00066     def __getattr__(self,name):
00067         #print 'asked for '+name
00068         return self.d[name]
00069 
00070 class _DictCopyAdapter(object):
00071     def __init__(self,d):
00072         #copy 'd' since we need to be able to lookup a 'source' by
00073         # it's type to do replace but we do NOT want to add it by its
00074         # type to the final Process
00075         self.d = d.copy()
00076         if self.d.has_key('source'):
00077             self.d[d['source'].type_()]=d['source']
00078     def __getattr__(self,name):
00079         #print 'asked for '+name
00080         return self.d[name]
00081 
00082 
00083 #setup a factory to open the file, we can redirect this for testing
00084 class _IncludeFile(file):
00085     def __init__(self,filename):
00086         """Searches for the 'filename' using the appropriate paths"""
00087         import os.path
00088         from os import environ
00089         try:
00090             paths = environ['CMSSW_SEARCH_PATH']
00091         except KeyError:
00092             raise RuntimeError("The environment variable 'CMSSW_SEARCH_PATH' must be set for include to work")
00093         lpaths = paths.split(':')
00094         lpaths.append('/afs/cern.ch/cms/sdt/misc/oldConfig/CMSSW')
00095         lpaths.append('.')
00096         f = None
00097         for path in lpaths:
00098             path +='/'+filename
00099             if os.path.exists(path):
00100                 f=path
00101                 break
00102         if f is None:
00103             raise RuntimeError("Unable to find file '"+filename+"' using the search path ${'CMSSW_SEARCH_PATH'} \n"
00104                                +paths)
00105         super(_IncludeFile,self).__init__(path,'r')
00106 _fileFactory = _IncludeFile
00107 
00108 def _findAndHandleParameterIncludes(values):
00109         return _findAndHandleParameterIncludesRecursive(values,set(),set())
00110 def _findAndHandleParameterIncludesRecursive(values,otherFiles,recurseFiles):
00111     newValues = []
00112     for l,v in values:
00113         if isinstance(v,_IncludeNode):
00114             #newValues.extend(_handleParameterInclude(v.filename,otherFiles))
00115             newValues.extend(v.extract(l, otherFiles,
00116                                        recurseFiles,
00117                                        onlyParameters.parseFile,
00118                                        _validateLabelledList,
00119                                        _findAndHandleParameterIncludesRecursive))
00120         else:
00121             newValues.append((l,v))
00122     return newValues
00123 
00124 def _findAndHandleProcessBlockIncludes(values):
00125         return _findAndHandleProcessBlockIncludesRecursive(values,set(),set())
00126 def _findAndHandleProcessBlockIncludesRecursive(values,otherFiles,recurseFiles):
00127     newValues = []
00128     for l,v in values:
00129         if isinstance(v,_IncludeNode):
00130             #newValues.extend(_handleParameterInclude(v.filename,otherFiles))
00131             newValues.extend(v.extract(l, otherFiles,
00132                                        recurseFiles,
00133                                        onlyProcessBody.parseFile,
00134                                        _validateLabelledList,
00135                                        _findAndHandleProcessBlockIncludesRecursive))
00136         else:
00137             newValues.append((l,v))
00138     return newValues
00139 
00140 def _handleInclude(fileName,otherFiles,recurseFiles,parser,validator,recursor):
00141     """reads in the file with name 'fileName' making sure it does not recursively include itself
00142     by looking in 'otherFiles' then applies the 'parser' to the contents of the file,
00143     runs the validator and then applies the recursor to see if other files must now be included"""
00144     global _fileStack
00145     if fileName in recurseFiles:
00146         raise RuntimeError('the file '+fileName+' eventually includes itself')
00147     if fileName in otherFiles:
00148         return list()
00149     newRecurseFiles = recurseFiles.copy()
00150     newRecurseFiles.add(fileName)
00151     otherFiles.add(fileName)
00152     _fileStack.append(fileName)
00153     try:
00154         factory = _fileFactory
00155         f = factory(fileName)
00156         try:
00157             values = parser(f)
00158             values = validator(values)
00159             values =recursor(values,otherFiles,newRecurseFiles)
00160         except pp.ParseException, e:
00161             raise RuntimeError('include file '+fileName+' had the parsing error \n'+str(e))
00162         except Exception, e:
00163             raise RuntimeError('include file '+fileName+' had the error \n'+str(e))
00164         try:
00165             values = validator(values)
00166         except Exception, e:
00167             raise RuntimeError('after including all other files, include file '+fileName+' had the error \n'+str(e))
00168         return values
00169     finally:
00170         _fileStack.pop()
00171         
00172 def _handleUsing(using,otherUsings,process,allUsingLabels):
00173     """recursively go through the using blocks and return all the contained valued"""
00174     if using.value() in otherUsings:
00175         raise pp.ParseFatalException(using.s,using.loc,
00176     "the using.labelled '"+using.value()+"' recursively uses itself"+
00177     "\n from file "+using.file)
00178     allUsingLabels.add(using.value())
00179     values = []
00180     valuesFromOtherUsings=[]
00181     otherUsings = otherUsings.copy()
00182     otherUsings.add(using.value())
00183     if using.value() not in process:
00184         raise pp.ParseFatalException(using.s,using.loc,
00185                 "the using.labelled '"+using.value()+"' does not correspond to a known block or PSet"
00186                 +"\n from file "+using.file)
00187     d = process[using.value()].__dict__
00188     usingLabels=[]
00189     for label,param in (x for x in d.iteritems() if isinstance(x[1],cms._ParameterTypeBase)):
00190         if isinstance(param,cms.UsingBlock):
00191             newValues=_handleUsing(param,otherUsings,process,allUsingLabels)
00192             valuesFromOtherUsings.extend( newValues)
00193             values.extend(newValues)
00194             usingLabels.append(label)
00195         else:
00196             values.append((label,copy.deepcopy(param)))
00197     for label in usingLabels:
00198         #remove the using nodes
00199         delattr(process[using.value()],label)
00200     for plabel,param in valuesFromOtherUsings:
00201         item = process[using.value()]
00202         if hasattr(item,plabel):
00203             raise pp.ParseFatalException(using.s,using.loc,
00204                 "the using labelled '"+using.value()+"' tried to add the label '"+
00205                 plabel+"' which already exists in this block"
00206                 +"\n from file "+using.file)
00207         setattr(item,plabel,param)
00208     return values
00209 
00210 def _findAndHandleUsingBlocksRecursive(label,item,process,allUsingLabels):
00211     otherUsings = set( (label,))
00212     values = []
00213     usingLabels = []
00214     usingForValues = []
00215     for tempLabel,param in item.__dict__.iteritems():
00216         if isinstance(param,cms.UsingBlock):
00217             oldSize = len(values)
00218             values.extend(_handleUsing(param,otherUsings,process,allUsingLabels))
00219             usingLabels.append(tempLabel)
00220             usingForValues.extend([param]*(len(values)-oldSize))
00221         elif isinstance(param,cms._Parameterizable):
00222             _findAndHandleUsingBlocksRecursive(tempLabel,param,process,allUsingLabels)
00223         elif isinstance(param,cms.VPSet):
00224             for pset in param:
00225                 _findAndHandleUsingBlocksRecursive(tempLabel,pset,process,allUsingLabels)
00226     for tempLabel in usingLabels:
00227         delattr(item,tempLabel)
00228     for index,(plabel,param) in enumerate(values):
00229         if hasattr(item,plabel):
00230             using = usingForValues[index]
00231             raise pp.ParseFatalException(using.s,using.loc,
00232                 "the using labelled '"+using.value()+"' tried to add the label '"+
00233                 plabel+"' which already exists in this block"
00234                 +"\n from file "+using.file)
00235         setattr(item,plabel,param)
00236 
00237 def _findAndHandleProcessUsingBlock(values):
00238     d=dict(values)
00239     allUsingLabels = set()
00240     for label,item in d.iteritems():
00241         if isinstance(item,cms._Parameterizable):
00242             _findAndHandleUsingBlocksRecursive(label,item,d,allUsingLabels)
00243         elif isinstance(item,cms.VPSet):
00244             for pset in item:
00245                 _findAndHandleUsingBlocksRecursive(label,pset,d,allUsingLabels)
00246     return allUsingLabels
00247 
00248 def _flagUsingBlocks(values):
00249     """Only flags whether they're resolvable or not"""
00250     d=dict(values)
00251     for label,item in d.iteritems():
00252         if isinstance(item,cms._Parameterizable):
00253             _flagUsingBlocksRecursive(item,d)
00254         elif isinstance(item,cms.VPSet):
00255             for pset in item:
00256                 _flagUsingBlocksRecursive(pset,d)
00257 
00258 def _flagUsingBlocksRecursive(item, d):
00259     for label,param in item.__dict__.iteritems():
00260         if isinstance(param,cms.UsingBlock):
00261             if item.label in d.keys():
00262                 item.isResolved = True
00263         elif isinstance(param,cms._Parameterizable):
00264             _flagUsingBlocksRecursive(label,param,process)
00265         elif isinstance(param,cms.VPSet):
00266             for pset in param:
00267                 _flagUsingBlocksRecursive(label,pset,process)
00268 
00269 
00270 def _badLabel(s,loc,expr,err):
00271     """a mal formed label was detected"""
00272     raise pp.ParseFatalException(s,loc,"inappropriate label name")
00273 
00274 def _makeParameter(s,loc,toks):
00275     """create the appropriate parameter object from the tokens"""
00276     tracked = True
00277     if len(toks[0])==4:
00278         tracked = False
00279         del toks[0][0]
00280     if not hasattr(cms,toks[0][0]):
00281         raise pp.ParseFatalException(s,loc,'unknown parameter type '+toks[0][0])
00282     ptype = getattr(cms,toks[0][0])
00283     try:
00284         p = ptype._valueFromString(toks[0][2])
00285     except Exception,e:
00286         raise pp.ParseFatalException(s,loc,
00287                 "failed to parse parameter '"+toks[0][1]+"' because of error\n"+str(e))
00288     if not tracked:
00289         cms.untracked(p)
00290     return (toks[0][1],p)
00291 
00292 def _makeLabeledInputTag(s,loc,toks):
00293     """create an InputTag parameter from the tokens"""
00294     tracked = True
00295     if len(toks[0])==4:
00296         tracked = False
00297         del toks[0][0]
00298     if isinstance(toks[0][2], str):
00299         p = cms.InputTag(toks[0][2])
00300     else:
00301         values = list(iter(toks[0][2]))
00302         if len(values) == 1:
00303             values +=''
00304         p = cms.InputTag(*values)
00305     if not tracked:
00306         cms.untracked(p)
00307     return (toks[0][1],p)
00308 
00309 def _makeLabeledVInputTag(s,loc,toks):
00310     """create an VInputTag parameter from the tokens"""
00311     tracked = True
00312     if len(toks[0])==4:
00313         tracked = False
00314         del toks[0][0]
00315 
00316     values = list(iter(toks[0][2]))
00317     items = []
00318     for x in values:
00319         if isinstance(x, str):
00320             items.append(cms.InputTag(x))
00321         else:
00322             items.append(cms.InputTag(*x))
00323     #items = [cms.InputTag(*x) for x in values]
00324     p = cms.VInputTag(*items)
00325     if not tracked:
00326         cms.untracked(p)
00327     return (toks[0][1],p)
00328 
00329 def _makeLabeledEventID(s,loc,toks):
00330     """create an EventID parameter from the tokens"""
00331     tracked = True
00332     if len(toks[0])==4:
00333         tracked = False
00334         del toks[0][0]
00335     p = cms.EventID(int(toks[0][2][0]), int(toks[0][2][1]))
00336     if not tracked:
00337         cms.untracked(p)
00338     return (toks[0][1],p)
00339 
00340 def _makeLabeledVEventID(s,loc,toks):
00341     """create an VEventID parameter from the tokens"""
00342     tracked = True
00343     if len(toks[0])==4:
00344         tracked = False
00345         del toks[0][0]
00346     values = list(iter(toks[0][2]))
00347     items = [cms.EventID(*x) for x in values]
00348     p = cms.VEventID(*items)
00349     if not tracked:
00350         cms.untracked(p)
00351     return (toks[0][1],p)
00352 
00353 def _makeLabeledLuminosityBlockID(s,loc,toks):
00354     """create an EventID parameter from the tokens"""
00355     tracked = True
00356     if len(toks[0])==4:
00357         tracked = False
00358         del toks[0][0]
00359     p = cms.LuminosityBlockID(int(toks[0][2][0]), int(toks[0][2][1]))
00360     if not tracked:
00361         cms.untracked(p)
00362     return (toks[0][1],p)
00363 
00364 
00365 def _makeDictFromList(values):
00366     values = _validateLabelledList(values)
00367     values = _findAndHandleParameterIncludes(values)
00368     values = _validateLabelledList(values)
00369     return dict(values)
00370 
00371 def _makePSetFromList(values):
00372     d = _makeDictFromList(values)
00373     p = cms.PSet(*[],**d)
00374     return p
00375     
00376 def _makePSet(s,loc,toks):
00377     """create a PSet from the tokens"""
00378     values = list(iter(toks[0]))
00379     try:
00380         return _makePSetFromList(values)
00381     except Exception, e:
00382         raise pp.ParseFatalException(s,loc,"PSet contains the error \n"+str(e))
00383         
00384 
00385 def _makeLabeledPSet(s,loc,toks):
00386     """create an PSet parameter from the tokens"""
00387     tracked = True
00388     if len(toks[0])==4:
00389         tracked = False
00390         del toks[0][0]
00391     p=_makePSet(s,loc,[toks[0][2]])
00392     if not tracked:
00393         cms.untracked(p)
00394     return (toks[0][1],p)
00395 
00396 class _ObjectHolder(object):
00397     """If I return a VPSet directly to the parser it appears to 'eat it'"""
00398     def __init__(self,hold):
00399         self.hold = hold
00400 
00401 def _makeVPSetFromList(values):
00402     items = [_makePSetFromList(x) for x in values]
00403     p = cms.VPSet(*items)
00404     return p    
00405 def _makeVPSet(s,loc,toks):
00406     """create an VPSet from the tokens"""
00407     values = list(iter(toks[0]))
00408     try:
00409         p = _makeVPSetFromList(values)
00410         return _ObjectHolder(p)
00411     except Exception, e:
00412         raise pp.ParseFatalException(s,loc,"VPSet contains the error \n"+str(e))
00413 
00414 def _makeLabeledVPSet(s,loc,toks):
00415     """create an VPSet parameter from the tokens"""
00416     tracked = True
00417     if len(toks[0])==4:
00418         tracked = False
00419         del toks[0][0]
00420     p = _makeVPSet(s,loc,(toks[0][2],)).hold
00421     if not tracked:
00422         cms.untracked(p)
00423     return (toks[0][1],p)
00424 
00425 def _makeLabeledSecSource(s,loc,toks):
00426     tracked = True
00427     if len(toks[0])==4:
00428         tracked = False
00429         del toks[0][0]
00430     ss=toks[0][2]
00431     if not tracked:
00432         cms.untracked(ss)
00433     return (toks[0][1],ss)
00434 
00435 
00436 #This is ugly but I need to know the labels used by all using statements
00437 # in order to efficiently process the 
00438 _allUsingLabels = set()
00439 def _makeUsing(s,loc,toks):
00440     global _allUsingLabels
00441     _allUsingLabels.add(toks[0][1])
00442     #global _fileStack
00443     #file = _fileStack[-1]
00444     #TEMP:usings are hard, lets wait
00445     #raise pp.ParseFatalException(s,loc,"using not yet implemented")
00446     options = PrintOptions()
00447     return ('using_'+toks[0][1],cms.UsingBlock(toks[0][1], s, loc, _fileStack[-1]))
00448 
00449 class _IncludeNode(cms._ParameterTypeBase):
00450     """For injection purposes, pretend this is a new parameter type
00451        then have a post process step which strips these out
00452     """
00453     def __init__(self,filename):
00454         self.filename = filename
00455     def parse(self, parser, validator):
00456         """Only the top-level nodes.  No recursion"""
00457         global _fileStack
00458         _fileStack.append(self.filename)
00459         try:
00460             #factory = _fileFactory
00461             #f = factory(fileName)
00462             f = _fileFactory(self.filename)
00463             try:
00464                 values = parser(f)
00465                 values = validator(values)
00466             except pp.ParseException, e:
00467                 raise RuntimeError('include file '+self.filename+' had the parsing error \n'+str(e))
00468             except Exception, e:
00469                 raise RuntimeError('include file '+self.filename+' had the error \n'+str(e))
00470             return values
00471         finally:
00472             _fileStack.pop()
00473 
00474 
00475 
00476     def extract(self, label, otherFiles,recurseFiles,parser,validator,recursor):
00477         """reads in the file with name 'fileName' making sure it does not recursively include itself
00478         by looking in 'otherFiles' then applies the 'parser' to the contents of the file,
00479         runs the validator and then applies the recursor to see if other files must now be included"""
00480         fileName = self.filename
00481         if fileName in recurseFiles:
00482             raise RuntimeError('the file '+fileName+' eventually includes itself')
00483         if fileName in otherFiles:
00484             return list()
00485         newRecurseFiles = recurseFiles.copy()
00486         newRecurseFiles.add(fileName)
00487         otherFiles.add(fileName)
00488         values = self.parse(parser, validator)
00489         values =recursor(values,otherFiles,newRecurseFiles)
00490         try:
00491             values = validator(values)
00492         except pp.ParseException, e:
00493            raise RuntimeError('after including all other files,include file '+fileName+' had the parsing error \n'+str(e))
00494         except Exception, e:
00495             raise RuntimeError('after including all other files, include file '+fileName+' had the error \n'+str(e))
00496         return values
00497 
00498     def pythonFileRoot(self):
00499         # translate, e.g., "SimMuon/DT/data/my-mod.cfi" to "SimMuon/DT/data/my_mod_cfi"
00500         return self.filename.replace('.','_').replace('-','_')
00501     def pythonFileName(self):
00502         return self.pythonFileRoot().replace('/data/','/python/').replace('/test/','/python/test/')+".py"
00503     def pythonModuleName(self):
00504         # we want something like "SimMuon.DT.mod_cfi"
00505         return self.pythonFileRoot().replace('/','.').replace('.data.','.')
00506     def dumpPython(self, options):
00507         if options.isCfg: 
00508             #return "import "+self.pythonModuleName()+"\nprocess.extend("+self.pythonModuleName()+")\n"
00509             return "process.load(\"" + self.pythonModuleName() + "\")\n"
00510         else:
00511             return "from "+self.pythonModuleName()+" import *"
00512     def createFile(self, overwrite):
00513         import os
00514         import os.path
00515         pythonName = self.pythonFileName()
00516         cmsswSrc = os.path.expandvars("$CMSSW_BASE/src/")
00517         cmsswReleaseSrc = os.path.expandvars("$CMSSW_RELEASE_BASE/src/")
00518         if overwrite or (not os.path.exists(cmsswSrc+pythonName) and \
00519                          not os.path.exists(cmsswReleaseSrc+pythonName)):
00520             # need to check out my own version
00521             cwd = os.getcwd()
00522             os.chdir(cmsswSrc)
00523             pythonDir = os.path.dirname(pythonName)
00524             #os.system("cvs co "+pythonDir)
00525             if overwrite and os.path.exists(pythonName):
00526                 os.remove(pythonName)
00527             if not os.path.exists(pythonName):
00528                 # have to make it myself
00529                 if not os.path.exists(pythonDir):
00530                     #print "Making " + pythonDir
00531                     os.makedirs(pythonDir)
00532                     #os.system("scramv1 build")
00533                 f=open(pythonName, 'w')
00534                 f.write(dumpCff(self.filename))
00535                 f.close()
00536                 os.chdir(pythonDir)
00537             os.chdir(cwd)
00538           
00539 
00540 class _IncludeFromNode(_IncludeNode):
00541     """An IncludeNode with a label, so it will only
00542        extract the named node, plus any IncludeNodes,
00543        which are presumed to be blocks"""
00544     def __init__(self,fromLabel, filename):
00545         super(_IncludeFromNode,self).__init__(filename)
00546         self._fromLabel = fromLabel
00547     def extract(self, newLabel, otherFiles,recurseFiles,parser,validator,recursor):
00548         import copy
00549         # First, expand everything, so blocks 
00550         # don't worry about re-parsing
00551         wasHere = (self.filename in otherFiles)
00552         if wasHere:
00553             otherFiles.remove(self.filename)
00554         expandedValues = _IncludeNode.extract(self, newLabel, otherFiles,recurseFiles,parser,validator,recursor)
00555         # one possible fix to the issue of whether the original gets included
00556         if not wasHere:
00557             otherFiles.remove(self.filename)
00558         found = False
00559         for l,v in expandedValues:
00560            if l == self._fromLabel:
00561                found = True
00562                # I don't know how to replace it, so I'll just have to copy
00563                # second possbile fix is to comment this out
00564                expandedValues.remove((l,v))
00565                expandedValues.append((newLabel, copy.deepcopy(v)))
00566         if not found:
00567             raise RuntimeError("the file "+self.filename+" does not contain a "+self._fromLabel
00568                                          +"\n from file "+_fileStack[-1])
00569         return expandedValues
00570     def dumpPythonAs(self, newLabel, options):
00571         result = "import "+self.pythonModuleName() +"\n"
00572         result += newLabel + " = "
00573         result += self.pythonModuleName() + '.' + self._fromLabel+".clone()\n"
00574         return result
00575 
00576 
00577 def _makeInclude(s,loc,toks):
00578     return (toks[0][0],_IncludeNode(toks[0][0]))
00579 
00580 letterstart =   pp.Word(pp.alphas,pp.srange("[a-zA-Z0-9\-_]"))
00581 #dotdelimited    ([a-zA-Z]+[a-zA-Z0-9\-_]*+\.)+[a-zA-Z]+[a-zA-Z0-9\-_]*
00582 #bangstart      \![a-zA-Z]+[a-zA-Z0-9\-_]*
00583 
00584 #==================================================================
00585 # Parameters
00586 #==================================================================
00587 
00588 #simple parameters are ones whose values do not have any delimiters
00589 parameterValue = pp.Word(pp.alphanums+'.'+':'+'-'+'+')
00590 simpleParameterType = pp.Keyword("bool")|pp.Keyword("int32")|pp.Keyword("uint32")|pp.Keyword("int64")|pp.Keyword("uint64")|pp.Keyword("double")
00591 vSimpleParameterType = pp.Keyword("vint32")^pp.Keyword("vuint32")^pp.Keyword("vint64")^pp.Keyword("vuint64")^pp.Keyword("vdouble")
00592 any = parameterValue | letterstart
00593 
00594 _scopeBegin = pp.Suppress('{')
00595 _scopeEnd = pp.Suppress('}')
00596 label = letterstart.copy()
00597 label.setFailAction(_badLabel)
00598 untracked = pp.Optional('untracked')
00599 #use the setFailAction to catch cases where internal to a label is an unsupported character ' bad$la = ' 
00600 _equalTo = pp.Suppress('=').setFailAction(_badLabel)
00601 
00602 simpleParameter = pp.Group(untracked+simpleParameterType+label
00603                            +_equalTo+any).setParseAction(_makeParameter)
00604 vsimpleParameter = pp.Group(untracked+vSimpleParameterType+label+_equalTo
00605                             +_scopeBegin
00606                               +pp.Group(pp.Optional(pp.delimitedList(any)))
00607                             +_scopeEnd
00608                             ).setParseAction(_makeParameter)
00609 
00610 def _handleString(s,loc,toks):
00611     #let python itself handle the string to get the substitutions right
00612     return eval(toks[0])
00613 quotedString = pp.quotedString.copy().setParseAction(_handleString)
00614 #quotedString = pp.quotedString.copy().setParseAction(pp.removeQuotes)
00615 stringParameter = pp.Group(untracked+pp.Keyword('string')+label+_equalTo+
00616                            quotedString).setParseAction(_makeParameter)
00617 vstringParameter =pp.Group(untracked+pp.Keyword("vstring")+label+_equalTo
00618                            +_scopeBegin
00619                              +pp.Group(pp.Optional(pp.delimitedList(quotedString)))
00620                            +_scopeEnd
00621                           ).setParseAction(_makeParameter)
00622 
00623 fileInPathParameter = pp.Group(untracked+pp.Keyword('FileInPath')+label+_equalTo+
00624                            quotedString).setParseAction(_makeParameter)
00625 
00626 inputTagFormat = pp.Group(letterstart+pp.Optional(pp.Suppress(':')+pp.Optional(pp.NotAny(pp.White())+pp.Word(pp.alphanums),"")+
00627                           pp.Optional(pp.Suppress(':')+pp.Optional(pp.NotAny(pp.White())+pp.Word(pp.alphanums)))))
00628 anyInputTag = inputTagFormat|quotedString
00629 
00630 #inputTagParameter = pp.Group(untracked+pp.Keyword('InputTag')+label+_equalTo+
00631 #                             inputTagFormat
00632 #                             ).setParseAction(_makeLabeledInputTag)
00633 inputTagParameter = pp.Group(untracked+pp.Keyword('InputTag')+label+_equalTo+
00634                              anyInputTag
00635                              ).setParseAction(_makeLabeledInputTag)
00636 
00637 
00638 vinputTagParameter =pp.Group(untracked+pp.Keyword("VInputTag")+label+_equalTo
00639                              +_scopeBegin
00640                                +pp.Group(pp.Optional(pp.delimitedList(anyInputTag)))
00641                              +_scopeEnd
00642                           ).setParseAction(_makeLabeledVInputTag)
00643 
00644 eventIDParameter = pp.Group(untracked+pp.Keyword("EventID")+label+_equalTo 
00645                    + pp.Group( pp.Word(pp.nums) + pp.Suppress(':') + pp.Word(pp.nums) ) 
00646                    ).setParseAction(_makeLabeledEventID)
00647 
00648 luminosityBlockIDParameter = pp.Group(untracked+pp.Keyword("LuminosityBlockID")+label+_equalTo
00649                    + pp.Group( pp.Word(pp.nums) + pp.Suppress(':') + pp.Word(pp.nums) )
00650                    ).setParseAction(_makeLabeledLuminosityBlockID)
00651 
00652 #since PSet and VPSets can contain themselves, we must declare them as 'Forward'
00653 PSetParameter = pp.Forward()
00654 VPSetParameter = pp.Forward()
00655 secsourceParameter = pp.Forward()
00656 block = pp.Forward()
00657 # need to tolerate internal blocks?
00658 def _makeLabeledBlock(s,loc,toks):
00659     """create a PSet parameter from the tokens"""
00660     p=_makePSet(s,loc,[toks[0][2]])
00661     # They were tracked in the old system
00662     #p=cms.untracked(p)
00663     return (toks[0][1],p)
00664 
00665 using = pp.Group(pp.Keyword("using")+letterstart).setParseAction(_makeUsing)
00666 include = pp.Group(pp.Keyword("include").suppress()+quotedString).setParseAction(_makeInclude)
00667 
00668 # blocks and includes need to be included in case they're in fragments
00669 parameter = simpleParameter|stringParameter|vsimpleParameter|fileInPathParameter|vstringParameter|inputTagParameter|vinputTagParameter|eventIDParameter|luminosityBlockIDParameter|PSetParameter|VPSetParameter|secsourceParameter|block|include
00670 
00671 scopedParameters = _scopeBegin+pp.Group(pp.ZeroOrMore(parameter|using|include))+_scopeEnd
00672 #now we can actually say what PSet and VPSet are
00673 block <<  pp.Group(untracked+pp.Keyword("block")+label+_equalTo+scopedParameters
00674                 ).setParseAction(_makeLabeledBlock)
00675 
00676 PSetParameter << pp.Group(untracked+pp.Keyword("PSet")+label+_equalTo+scopedParameters
00677                           ).setParseAction(_makeLabeledPSet)
00678 VPSetParameter << pp.Group(untracked+pp.Keyword("VPSet")+label+_equalTo
00679                            +_scopeBegin
00680                                +pp.Group(pp.Optional(pp.delimitedList(scopedParameters)))
00681                            +_scopeEnd
00682                           ).setParseAction(_makeLabeledVPSet)
00683 
00684 parameters = pp.OneOrMore(parameter)
00685 parameters.ignore(pp.cppStyleComment)
00686 parameters.ignore(pp.pythonStyleComment)
00687 
00688 
00689 #==================================================================
00690 # Plugins
00691 #==================================================================
00692 
00693 class _MakePlugin(object):
00694     def __init__(self,plugin):
00695         self.__plugin = plugin
00696     def __call__(self,s,loc,toks):
00697         global _fileStack
00698         type = toks[0][0]
00699         values = list(iter(toks[0][1]))
00700         try:
00701             values = _validateLabelledList(values)
00702             values = _findAndHandleParameterIncludes(values)
00703             values = _validateLabelledList(values)
00704         except Exception, e:
00705             raise pp.ParseFatalException(s,loc,type+" contains the error "+str(e)
00706                                          +"\n from file "+_fileStack[-1])
00707         d = dict(values)
00708         return self.__plugin(*[type],**d)
00709 class _MakeFrom(object):
00710     def __init__(self,plugin):
00711         self.__plugin = plugin
00712     def __call__(self,s,loc,toks):
00713         global _fileStack
00714         label = toks[0][0]
00715         inc = toks[0][1]
00716         return _IncludeFromNode(label, inc[0])
00717 
00718 def _replaceKeywordWithType(s,loc,toks):
00719     type = toks[0][1].type_()
00720     return (type,toks[0][1])
00721 
00722 def _MakeESPrefer(s, loc, toks):
00723     value = None
00724     label = 'es_prefer_'+toks[0][1]
00725     if len(toks[0]) == 4:
00726         # type, label
00727         value = cms.ESPrefer(toks[0][2], toks[0][1]) 
00728     elif len(toks[0])==3:
00729         value = cms.ESPrefer(toks[0][1])
00730     else:
00731         print "Strange parse of es_prefer "+str(toks)
00732     return (label,value)
00733 
00734     
00735 typeWithParameters = pp.Group(letterstart+scopedParameters)
00736 
00737 #secsources are parameters but they behave like Plugins
00738 secsourceParameter << pp.Group(untracked+pp.Keyword("secsource")+label+_equalTo
00739                                +typeWithParameters.copy().setParseAction(_MakePlugin(cms.SecSource))
00740                           ).setParseAction(_makeLabeledSecSource)
00741 
00742 source = pp.Group(pp.Keyword("source")+_equalTo
00743                   +typeWithParameters.copy().setParseAction(_MakePlugin(cms.Source))
00744                  )
00745 looper = pp.Group(pp.Keyword("looper")+_equalTo
00746                   +typeWithParameters.copy().setParseAction(_MakePlugin(cms.Looper))
00747                  )
00748 
00749 service = pp.Group(pp.Keyword("service")+_equalTo
00750                    +typeWithParameters.copy().setParseAction(_MakePlugin(cms.Service))
00751                   ).setParseAction(_replaceKeywordWithType)
00752 
00753 es_prefer = pp.Group(pp.Keyword("es_prefer")+pp.Optional(letterstart)+_equalTo+label+scopedParameters).setParseAction(_MakeESPrefer)
00754 
00755 
00756 #for now, pretend all modules are filters since filters can function like
00757 # EDProducer's or EDAnalyzers
00758 module = pp.Group(pp.Suppress(pp.Keyword("module"))+label+_equalTo
00759                   +typeWithParameters.copy().setParseAction(_MakePlugin(cms.EDFilter))|
00760                   pp.Suppress(pp.Keyword("module"))+label+_equalTo
00761                   +pp.Group(label+pp.Group(pp.Keyword("from").suppress()+quotedString).setParseAction(_makeInclude)).setParseAction(_MakeFrom(cms.EDFilter)))
00762 
00763 def _guessTypeFromClassName(regexp,type):
00764     return pp.Group(pp.Suppress(pp.Keyword('module'))+label+_equalTo
00765                              +pp.Group(pp.Regex(regexp)
00766                                        +scopedParameters
00767                                       ).setParseAction(_MakePlugin(type))
00768                              )
00769 outputModuleGuess = _guessTypeFromClassName(r"[a-zA-Z]\w*OutputModule",cms.OutputModule)
00770 producerGuess = _guessTypeFromClassName(r"[a-zA-Z]\w*Prod(?:ucer)?",cms.EDProducer)
00771 analyzerGuess = _guessTypeFromClassName(r"[a-zA-Z]\w*Analyzer",cms.EDAnalyzer)
00772 
00773 def _labelOptional(alabel,type,appendToLabel=''):
00774     def useTypeIfNoLabel(s,loc,toks):
00775         if len(toks[0])==2:
00776             alabel = toks[0][0]
00777             del toks[0][0]
00778         else:
00779             alabel = toks[0][0].type_()
00780         alabel +=appendToLabel
00781         return (alabel,toks[0][0])
00782     #NOTE: must use letterstart instead of label else get exception when no label
00783     return pp.Group(pp.Suppress(pp.Keyword(alabel))+pp.Optional(letterstart)+_equalTo
00784                               +typeWithParameters.copy().setParseAction(_MakePlugin(type))|
00785                               pp.Keyword(alabel).suppress()+pp.Optional(letterstart)+_equalTo+pp.Group(label+pp.Group(pp.Keyword("from").suppress()+quotedString).setParseAction(_makeInclude)).setParseAction(_MakeFrom(type))
00786                              ).setParseAction(useTypeIfNoLabel)
00787 
00788 es_module = _labelOptional("es_module",cms.ESProducer)
00789 es_source = _labelOptional("es_source",cms.ESSource)
00790 
00791 plugin = source|looper|service|outputModuleGuess|producerGuess|analyzerGuess|module|es_module|es_source|es_prefer
00792 plugin.ignore(pp.cppStyleComment)
00793 plugin.ignore(pp.pythonStyleComment)
00794 
00795 #==================================================================
00796 # Paths
00797 #==================================================================
00798 #NOTE: I can't make the parser change a,b,c into (a,b),c only a,(b,c)
00799 # so instead, I reverse the order of the tokens and then do the parsing
00800 # and then build the parse tree from right to left
00801 pathexp = pp.Forward()
00802 # Really want either ! or -
00803 _pathAtom = pp.Combine(pp.Optional("!")+pp.Optional("-")+letterstart)
00804 #_pathAtom = pp.Combine(pp.Optional("!")+letterstart)
00805 worker = (_pathAtom)^pp.Group(pp.Suppress(')')+pathexp+pp.Suppress('('))
00806 pathseq = pp.Forward()
00807 pathseq << pp.Group(worker + pp.ZeroOrMore(','+pathseq))
00808 pathexp << pp.Group(pathseq + pp.ZeroOrMore('&'+pathexp))
00809 
00810 class _LeafNode(object):
00811     def __init__(self,label):
00812         self.__isNot = False
00813         self.__isIgnore = False
00814         self._label = label
00815         if self._label[0]=='!':
00816             self._label=self._label[1:]
00817             self.__isNot = True
00818         elif self._label[0]=='-':
00819             self._label=self._label[1:]
00820             self.__isIgnore = True
00821 
00822     def __str__(self):
00823         v=''
00824         if self.__isNot:
00825             v='!'
00826         elif self.__isIgnore:
00827             v += '-'
00828         return v+self._label
00829     def make(self,process):
00830         #print getattr(process,self.__label).label()
00831         v = getattr(process,self._label)
00832         if self.__isNot:
00833             v= ~v
00834         elif self.__isIgnore:
00835             v= cms.ignore(v)
00836         return v
00837     def getLeaves(self, leaves):
00838         leaves.append(self)
00839     def dumpPython(self, options):
00840         result = ''
00841         if self.__isNot:
00842             result += '~'
00843         elif self.__isIgnore:
00844             result += 'cms.ignore('
00845         if options.isCfg:
00846             result += "process."
00847         result += self._label
00848         if self.__isIgnore:
00849             result += ')'
00850         return result
00851 
00852 class _AidsOp(object):
00853     def __init__(self,left,right):
00854         self.__left = left
00855         self.__right = right
00856     def __str__(self):
00857         return '('+str(self.__left)+','+str(self.__right)+')'
00858     def getLeaves(self, leaves):
00859         self.__left.getLeaves(leaves)
00860         self.__right.getLeaves(leaves)
00861     def dumpPython(self, options):
00862         return self.__left.dumpPython(options)+'*'+self.__right.dumpPython(options)
00863     def make(self,process):
00864         left = self.__left.make(process)
00865         right = self.__right.make(process)
00866         return left*right
00867 
00868 class _FollowsOp(object):
00869     def __init__(self,left,right):
00870         self.__left = left
00871         self.__right = right
00872     def __str__(self):
00873         return '('+str(self.__left)+'&'+str(self.__right)+')'
00874     def getLeaves(self, leaves):
00875         self.__left.getLeaves(leaves)
00876         self.__right.getLeaves(leaves)
00877     def dumpPython(self, options):
00878         return self.__left.dumpPython(options)+'+'+self.__right.dumpPython(options)
00879     def make(self,process):
00880         left = self.__left.make(process)
00881         right = self.__right.make(process)
00882         return left+right
00883 
00884 def _buildTree(tree):
00885     #print 'tree = '+str(tree)
00886     if isinstance(tree,type('')):
00887         return _LeafNode(tree)
00888     if len(tree) == 1:
00889         return _buildTree(tree[0])
00890     assert(len(tree) == 3)
00891     left = _buildTree(tree[0])
00892     right = _buildTree(tree[2])
00893     theOp = _FollowsOp
00894     if ',' == tree[1]:
00895         theOp = _AidsOp
00896 #    return [right,tree[1],left]
00897     return theOp(right,left)
00898 
00899 def _parsePathInReverse(s,loc,toks):
00900     backwards = list(toks[0])
00901     backwards.reverse()
00902     return [_buildTree(pathexp.parseString(' '.join(backwards)))]
00903 
00904 class _ModuleSeries(object):
00905     def __init__(self,topNode,s,loc,toks):
00906         global _fileStack
00907         #NOTE: nee to record what file we are from as well
00908         self.topNode = topNode
00909         self.forErrorMessage = (s,loc,toks,_fileStack[-1])
00910     def make(self,process):
00911         try:
00912             nodes = self.topNode.make(process)
00913             return self.factory()(nodes)
00914         except AttributeError, e:
00915             raise pp.ParseFatalException(self.forErrorMessage[0],
00916                                          self.forErrorMessage[1],
00917                                          self.type()+" '"
00918                                          +self.forErrorMessage[2][0][0]+
00919                                          "' contains the error: "
00920                                          +str(e)
00921                                          +"\n from file "+self.forErrorMessage[3])
00922         except Exception, e:
00923             raise pp.ParseFatalException(self.forErrorMessage[0],
00924                                          self.forErrorMessage[1],
00925                                          self.type()
00926                                          +" '"+self.forErrorMessage[2][0][0]
00927                                          +"' contains the error: "+str(e)
00928                                          +"\n from file "+self.forErrorMessage[3])
00929     def __str__(self):
00930         return str(self.topNode)
00931     def __repr__(self):
00932         options = PrintOptions()
00933         # probably don't want "process." everywhere
00934         options.isCfg = False
00935         return self.dumpPython(options)
00936     def getLeaves(self, leaves):
00937         self.topNode.getLeaves(leaves)
00938     def dumpPython(self, options):
00939         return "cms."+self.factory().__name__+"("+self.topNode.dumpPython(options)+")"
00940 
00941 
00942 class _Sequence(_ModuleSeries):
00943     def factory(self):
00944         return cms.Sequence
00945     def type(self):
00946         return 'sequence'
00947 class _Path(_ModuleSeries):
00948     def factory(self):
00949         return cms.Path
00950     def type(self):
00951         return 'path'
00952 class _EndPath(_ModuleSeries):
00953     def factory(self):
00954         return cms.EndPath
00955     def type(self):
00956         return 'endpath'
00957 
00958     
00959 class _MakeSeries(object):
00960     def __init__(self,factory):
00961         self.factory = factory
00962     def __call__(self,s,loc,toks):
00963         return (toks[0][0],self.factory(toks[0][1],s,loc,toks))
00964 # really want either ! or -, not both
00965 pathtoken = (pp.Combine(pp.Optional("!")+pp.Optional("-")+letterstart))|'&'|','|'('|')'
00966 pathbody = pp.Group(letterstart+_equalTo
00967                     +_scopeBegin
00968                     +pp.Group(pp.OneOrMore(pathtoken)).setParseAction(_parsePathInReverse)
00969                     +_scopeEnd)
00970 path = pp.Keyword('path').suppress()+pathbody.copy().setParseAction(_MakeSeries(_Path))
00971 endpath = pp.Keyword('endpath').suppress()+pathbody.copy().setParseAction(_MakeSeries(_EndPath))
00972 sequence = pp.Keyword('sequence').suppress()+pathbody.copy().setParseAction(_MakeSeries(_Sequence))
00973 
00974 
00975 class _Schedule(object):
00976     """Stand-in for a Schedule since we can't build the real Schedule
00977     till the Paths have been created"""
00978     def __init__(self,labels):
00979         self.labels = labels
00980     def dumpPython(self, options):
00981         result = "cms.Schedule("
00982         # might have to add the word 'process' to each'
00983         newLabels = list()
00984         if options.isCfg:
00985             for label in self.labels:
00986                 newLabels.append('process.'+label)
00987             result += ','.join(newLabels)
00988         result += ')\n'
00989 
00990         return result
00991 
00992 
00993 def _makeSchedule(s,loc,toks):
00994     """create the appropriate parameter object from the tokens"""
00995     values = list(iter(toks[0][0]))
00996     p = _Schedule(values)
00997     return ('schedule',p)
00998     
00999 schedule = pp.Group(pp.Keyword('schedule').suppress()+_equalTo+
01000                            _scopeBegin
01001                              +pp.Group(pp.Optional(pp.delimitedList(label)))
01002                            +_scopeEnd
01003                           ).setParseAction(_makeSchedule)
01004 
01005 #==================================================================
01006 # Other top level items
01007 #==================================================================
01008 
01009 class _ReplaceNode(object):
01010     """Handles the 'replace' command"""
01011     def __init__(self,path,setter,s,loc):
01012         global _fileStack
01013         self.path = path
01014         self.setter = setter
01015         self.forErrorMessage =(s,loc,_fileStack[-1])
01016         self.multiplesAllowed = setter.multiplesAllowed
01017     def getValue(self):
01018         return self.setter.value
01019     value = property(fget = getValue,
01020                      doc='returns the value of the replace command (for testing)')
01021     def rootLabel(self):
01022         return self.path[0]
01023     def do(self,process):
01024         if hasattr(self.setter, 'setProcess'):
01025             self.setter.setProcess(process)
01026         try:
01027             self._recurse(self.path,process)
01028         except Exception,e:
01029             raise pp.ParseException(self.forErrorMessage[0],
01030                                     self.forErrorMessage[1],
01031                                     "The replace statement '"+'.'.join(self.path)
01032                                     +"' had the error \n"+str(e)
01033                                     +"\n from file "+self.forErrorMessage[2]
01034                                     )
01035     def _setValue(self,obj,attr):
01036         self.setter.setValue(obj,attr)
01037     def _recurse(self,path,obj):
01038         if len(path) == 1:
01039             self._setValue(obj,path[0])
01040             return
01041         self._recurse(path[1:],getattr(obj,path[0]))
01042     def __repr__(self):
01043         options = PrintOptions()
01044         return self.dumpPython(options)
01045     def dumpPython(self, options):
01046         # translate true/false to True/False
01047         s = self.getValue()
01048         return '.'.join(self.path)+self.setter.dumpPython(options)
01049 
01050 class _ReplaceSetter(object):
01051     """Used to 'set' an unknown type of value from a Replace node"""
01052     def __init__(self,value):
01053         self.value = value
01054         #one one replace of this type is allowed per configuration
01055         self.multiplesAllowed = False
01056     def setValue(self,obj,attr):
01057         theAt = getattr(obj,attr)
01058         #want to change the value, not the actual parameter
01059         #setattr(obj,attr,theAt._valueFromString(self.value).value())
01060         #by replacing the actual parameter we isolate ourselves from
01061         # 'replace' commands done by others on shared using blocks
01062         v=theAt._valueFromString(self.value)
01063         v.setIsTracked(theAt.isTracked())
01064         setattr(obj,attr,v)
01065     def dumpPython(self, options):
01066        # FIXME not really a repr, because of the = sign
01067        return " = "+self._pythonValue(self.value, options)
01068     @staticmethod
01069     def _pythonValue(value, options):
01070         #if it's a number, we don't want quotes
01071         result = str(value)
01072         nodots = result.replace('.','')
01073         if nodots.isdigit() or (len(nodots) > 0 and nodots[0] == '-') or (len(nodots) > 1 and (nodots[0:2] == '0x' or nodots[0:2] == '0X')):
01074             pass
01075         elif result == 'true':
01076             result = 'True'
01077         elif result == 'false':
01078             result = 'False'
01079         elif len(value) == 0:
01080             result = repr(value)
01081         elif result[0] == '[':
01082             l = eval(result)
01083             isVInputTag = False
01084             result = ''
01085             indented = False
01086             for i, x in enumerate(l):
01087                 if i == 0:
01088                     if hasattr(x, "_nPerLine"):
01089                         nPerLine = x._nPerLine
01090                     else:
01091                         nPerLine = 5
01092                 else:
01093                     result += ', '
01094                     if i % nPerLine == 0:
01095                         if not indented:
01096                             indented = True
01097                             options.indent()
01098                         result += '\n'+options.indentation()
01099                 element = _ReplaceSetter._pythonValue(x, options) 
01100                 if element.find('InputTag') != -1:
01101                    isVInputTag = True
01102                 result += element
01103             if indented:
01104                 options.unindent()
01105             if isVInputTag:
01106                result = "cms.VInputTag("+result+")"
01107             else:
01108                result = "["+result+"]"
01109         # some frontier address strings have colons and slashes 
01110         #elif result.find(':') != -1 and result.find('/') == -1:
01111         #    result = repr(cms.InputTag._valueFromString(result))
01112         else:
01113             # need the quotes
01114             result = repr(value)
01115         return result
01116 
01117  
01118 
01119 class _ParameterReplaceSetter(_ReplaceSetter):
01120     """Base used to 'set' a PSet or VPSet replace node""" 
01121     def setValue(self,obj,attr):
01122         #need to preserve 'trackiness'
01123         theAt = getattr(obj,attr)
01124         self.value.setIsTracked(theAt.isTracked())
01125         setattr(obj,attr,self.value)
01126     @staticmethod
01127     def _pythonValue(value, options):
01128         return value.dumpPython(options)
01129 
01130 class _VPSetReplaceSetter(_ParameterReplaceSetter):
01131     """Used to 'set' a VPSet replace node"""
01132     def __init__(self,value):
01133         super(_VPSetReplaceSetter,self).__init__(_makeVPSetFromList(value))
01134 class _PSetReplaceSetter(_ParameterReplaceSetter):
01135     """Used to 'set' a VPSet replace node"""
01136     def __init__(self,value):
01137         super(_PSetReplaceSetter,self).__init__(_makePSetFromList(value))
01138 
01139 class _SimpleListTypeExtendSetter(_ReplaceSetter):
01140     """replace command to extends a list"""
01141     def __init__(self,value):
01142         super(type(self),self).__init__(value)
01143         self.multiplesAllowed = True
01144     def setValue(self,obj,attr):
01145         theAt=getattr(obj,attr)
01146         theAt.extend(theAt._valueFromString(self.value))
01147     def dumpPython(self, options):
01148         return ".extend("+self._pythonValue(self.value, options)+")"
01149 
01150 
01151 class _SimpleListTypeAppendSetter(_ReplaceSetter):
01152     """replace command to append to a list"""
01153     def __init__(self,value):
01154         super(type(self),self).__init__(value)
01155         self.multiplesAllowed = True
01156     def setValue(self,obj,attr):
01157         theAt=getattr(obj,attr)
01158         theAt.append(theAt._valueFromString([self.value])[0])
01159     def dumpPython(self, options):
01160         return ".append("+self._pythonValue(self.value, options)+")"
01161 
01162 
01163 
01164 class _VPSetExtendSetter(_VPSetReplaceSetter):
01165     """replace command to extend a VPSet"""
01166     def __init__(self,value):
01167         super(type(self),self).__init__(value)
01168         self.multiplesAllowed = True
01169     def setValue(self,obj,attr):
01170         theAt=getattr(obj,attr)
01171         theAt.extend(self.value)
01172     def dumpPython(self, options):
01173         return ".extend("+self._pythonValue(self.value, options)+")"
01174 
01175 
01176 
01177 class _VPSetAppendSetter(_PSetReplaceSetter):
01178     """replace command to append a PSet to a VPSet"""
01179     def __init__(self,value):
01180         super(type(self),self).__init__(value)
01181         self.multiplesAllowed = True
01182     def setValue(self,obj,attr):
01183         theAt=getattr(obj,attr)
01184         theAt.append(self.value)
01185     def dumpPython(self, options):
01186         return ".append("+self._pythonValue(self.value, options)+")"
01187 
01188 
01189 
01190 class _IncrementFromVariableSetter(_ReplaceSetter):
01191     """replace command which gets its value from another parameter"""
01192     def __init__(self,value):
01193         self.valuePath = value
01194         super(type(self),self).__init__('.'.join(value))
01195         self.multiplesAllowed = True
01196         self.oldValue = None
01197     def setProcess(self,process):
01198         if self.oldValue is None:
01199             self.oldValue = self.value
01200             attr=None
01201             path = self.valuePath
01202             attr = process
01203             while path:
01204                 attr = getattr(attr,path[0])
01205                 path = path[1:]
01206             self.value = attr
01207     def setValue(self,obj,attr):
01208         theAt = getattr(obj,attr)
01209         #determine if the types are compatible
01210         try:
01211             if type(theAt) is type(self.value):
01212                 theAt.extend(self.value)
01213             #see if theAt is a container and self.value can be added to it 
01214             else:
01215                 theAt.append(self.value.value())
01216         except Exception, e:
01217             raise RuntimeError("replacing with "+self.oldValue+" failed because\n"+str(e))
01218     def dumpPython(self, options):
01219         v = str(self.value)
01220         if options.isCfg:
01221             v = 'process.'+v
01222         # assume variables ending in s are plural
01223         if v[0] == '[':
01224            return ".extend("+v+")"
01225         elif v.endswith('s'):
01226            return ".extend("+v+")"
01227         else:
01228            return ".append("+v+")"
01229 
01230         
01231 
01232 class _MakeSetter(object):
01233     """Uses a 'factory' to create the proper Replace setter"""
01234     def __init__(self,setter):
01235         self.setter = setter
01236     def __call__(self,s,loc,toks):
01237         value = toks[0]
01238         if isinstance(value,pp.ParseResults):
01239             value = value[:]
01240         return self.setter(value)
01241 
01242 def _makeReplace(s,loc,toks):
01243     try:
01244         path = toks[0][0]
01245         setter = toks[0][1]
01246         return ('.'.join(path),_ReplaceNode(list(path),setter,s,loc))
01247     except Exception, e:
01248         global _fileStack
01249         raise pp.ParseException(s,loc,"replace statement '"
01250                                 +'.'.join(list(path))
01251                                 +"' had the error \n"
01252                                 +str(e)
01253                                 +"\n from file "+_fileStack[-1])
01254 
01255 _replaceValue = (pp.Group(_scopeBegin+_scopeEnd
01256                          ).setParseAction(_MakeSetter(_ReplaceSetter))|
01257                     (scopedParameters.copy()
01258                     ).setParseAction(_MakeSetter(_PSetReplaceSetter))|
01259                     (_scopeBegin+pp.Group(pp.delimitedList(scopedParameters))
01260                      +_scopeEnd).setParseAction(_MakeSetter(_VPSetReplaceSetter))|
01261                     (quotedString|
01262                      (_scopeBegin+pp.Group(pp.delimitedList(quotedString))+_scopeEnd)|
01263                      (_scopeBegin+pp.Group(pp.Optional(pp.delimitedList(any)))+_scopeEnd)|
01264                     any).setParseAction(_MakeSetter(_ReplaceSetter)))
01265 _replaceExtendValue = (
01266                      scopedParameters.copy().setParseAction(_MakeSetter(_VPSetAppendSetter)) |
01267                      (_scopeBegin+pp.Group(pp.delimitedList(scopedParameters))
01268                       +_scopeEnd).setParseAction(_MakeSetter(_VPSetExtendSetter))|
01269                      ((_scopeBegin+pp.Group(pp.delimitedList(quotedString))+_scopeEnd)|
01270                       (_scopeBegin+pp.Group(pp.Optional(pp.delimitedList(any)))+_scopeEnd)
01271                      ).setParseAction(_MakeSetter(_SimpleListTypeExtendSetter)) |
01272                      (pp.Group(letterstart+pp.OneOrMore(pp.Literal('.').suppress()+letterstart)).setParseAction(
01273                         _MakeSetter(_IncrementFromVariableSetter))) |
01274                      ((quotedString|any).setParseAction(_MakeSetter(_SimpleListTypeAppendSetter))) 
01275                   )
01276 _plusEqualTo = pp.Suppress('+=')
01277 #NOTE: can't use '_equalTo' since it checks for a 'valid' label and gets confused
01278 # when += appears
01279 _eqTo = pp.Suppress("=")
01280 replace = pp.Group(pp.Keyword('replace').suppress()+
01281                    pp.Group(letterstart+
01282                             pp.OneOrMore(pp.Literal('.').suppress()+letterstart)
01283                             )+
01284                    ((_plusEqualTo+_replaceExtendValue
01285                     ) | (
01286                     _eqTo+_replaceValue))
01287                   ).setParseAction(_makeReplace) 
01288 
01289 class _ProcessAdapter(object):
01290     def __init__(self,seqs,process):
01291         self.__dict__['_seqs'] = seqs
01292         self.__dict__['_process'] = process
01293     def seqs(self):
01294         return self.__dict__['_seqs']
01295     def process(self):
01296         return self.__dict__['_process']
01297     def __getattr__(self,name):
01298         if hasattr(self.process(), name):
01299             return getattr(self.process(),name)
01300         setattr(self.process(),name,self.seqs()[name].make(self))
01301         return getattr(self.process(),name)
01302     def __setattr__(self,name,value):
01303         if hasattr(self.process(),name):
01304             return
01305         setattr(self.process(),name,value)
01306 def _finalizeProcessFragment(values,usingLabels):
01307     try:
01308         values = _validateLabelledList(values)
01309         values = _findAndHandleProcessBlockIncludes(values)
01310         values = _validateLabelledList(values)
01311     except Exception, e:
01312         raise RuntimeError("the configuration contains the error \n"+str(e))
01313     #now deal with series
01314     d = SortedKeysDict(values)
01315     dct = dict(d)
01316     replaces=[]
01317     sequences = {}
01318     series = []
01319     for label,item in values:
01320         if isinstance(item,_ReplaceNode):
01321             replaces.append(item)
01322             #replace statements are allowed to have multiple identical labels
01323             if label in d:
01324                 del d[label]
01325             if label in dct:
01326                 del dct[label]
01327         elif isinstance(item,_Sequence):
01328             sequences[label]=item
01329             del dct[label]
01330         elif isinstance(item,_ModuleSeries):
01331             series.append((label,item))
01332             del dct[label]
01333     try:
01334         #pset replaces must be done first since PSets can be used in a 'using'
01335         # statement so we want their changes to be reflected
01336         adapted = _DictAdapter(dict(d),True)
01337         #what order do we process replace and using directives?
01338         # running a test on the C++ cfg parser it appears replace
01339         # always happens before using
01340         for replace in replaces:
01341             if isinstance(getattr(adapted,replace.rootLabel()),cms.PSet):
01342                 replace.do(adapted)
01343         _findAndHandleProcessUsingBlock(values)
01344         for replace in replaces:
01345             if not isinstance(getattr(adapted,replace.rootLabel()),cms.PSet):
01346                 replace.do(adapted)
01347         # maybe the user said something like 'replace a.b = {using bl}
01348         _findAndHandleProcessUsingBlock(values)
01349     except Exception, e:
01350         raise RuntimeError("the configuration contains the error \n"+str(e))    
01351     #FIX: now need to create Sequences, Paths, EndPaths from the available
01352     # information
01353     #now we don't want 'source' to be added to 'd' but we do not want
01354     # copies either
01355     adapted = _DictAdapter(d)
01356     pa = _ProcessAdapter(sequences,_DictAdapter(dct))
01357     for label,obj in sequences.iteritems():
01358         if label not in dct:
01359             d[label]=obj.make(pa)
01360             dct[label]=d[label]
01361         else:
01362             d[label] = dct[label]
01363     for label,obj in series:
01364         d[label]=obj.make(adapted)
01365     return d
01366 #==================================================================
01367 # Process
01368 #==================================================================
01369 def _getCompressedNodes(s,loc, values):
01370     """Inlines the using statements, but not the Includes or Replaces"""
01371     compressedValues = []
01372     for l,v in values:
01373         compressedValues.append((l,v))
01374 
01375     try:
01376         compressedValues = _validateLabelledList(compressedValues)
01377         expandedValues = _findAndHandleProcessBlockIncludes(compressedValues)
01378         expandedValues = _validateLabelledList(expandedValues)
01379         #_findAndHandleProcessUsingBlock(expandedValues)
01380     except Exception, e:
01381         raise pp.ParseFatalException(s,loc,"the process contains the error \n"+str(e))
01382 
01383     return compressedValues
01384 
01385 def _dumpCfg(s,loc,toks):
01386     label = toks[0][0]
01387     p=cms.Process(label)
01388 
01389     values = _getCompressedNodes(s, loc, list(iter(toks[0][1])) )
01390     options = PrintOptions()
01391     options.isCfg = True
01392     result = "import FWCore.ParameterSet.Config as cms\n\nprocess = cms.Process(\""+label+"\")\n"
01393     result += dumpPython(values, options)
01394     return result
01395 
01396 def _makeProcess(s,loc,toks):
01397     """create a Process from the tokens"""
01398     #print toks
01399     label = toks[0][0]
01400     p=cms.Process(label)
01401     values = list(iter(toks[0][1]))
01402     try:
01403         values = _validateLabelledList(values)
01404         values = _findAndHandleProcessBlockIncludes(values)
01405         values = _validateLabelledList(values)
01406     except Exception, e:
01407         raise RuntimeError("the process contains the error \n"+str(e)
01408                           )
01409 
01410 
01411     #now deal with series
01412     d = dict(values)
01413     sequences={}
01414     series=[] #order matters for a series
01415     replaces=[]
01416     prefers = {}
01417     schedule = None
01418 
01419 
01420     #sequences must be added before path or endpaths
01421     #sequences may contain other sequences so we need to do recursive construction
01422     try:
01423         for label,item in values:
01424             if isinstance(item,_Sequence):
01425                 sequences[label]=item
01426                 del d[label]
01427             elif isinstance(item,_ModuleSeries):
01428                 series.append((label,item))
01429                 del d[label]
01430             elif isinstance(item,_ReplaceNode):
01431                 replaces.append(item)
01432                 #replace statements are allowed to have multiple identical labels
01433                 if label in d: del d[label]
01434             elif isinstance(item,_Schedule):
01435                 if schedule is None:
01436                     schedule = item
01437                     del d[label]
01438                 else:
01439                     raise RuntimeError("multiple 'schedule's are present, only one is allowed")
01440             elif isinstance(item,cms.ESPrefer):
01441                 prefers[label[0:-7]]=item
01442                 del d[label]
01443         #pset replaces must be done first since PSets can be used in a 'using'
01444         # statement so we want their changes to be reflected
01445         adapted = _DictCopyAdapter(d)
01446         #what order do we process replace and using directives?
01447         # running a test on the C++ cfg parser it appears replace
01448         # always happens before using
01449         for replace in replaces:
01450             if isinstance(getattr(adapted,replace.rootLabel()),cms.PSet):
01451                 replace.do(adapted)
01452         _findAndHandleProcessUsingBlock(values)
01453         for replace in replaces:
01454             if not isinstance(getattr(adapted,replace.rootLabel()),cms.PSet):
01455                 replace.do(adapted)
01456         #NEED to call this a second time so replace statements applying to modules
01457         # where the replace statements contain using statements will have the
01458         # using statements replaced by their actual values
01459         _findAndHandleProcessUsingBlock(values)
01460 
01461 
01462         # adding modules to the process involves cloning.
01463         # but for the usings we only know the original object
01464         # so we do have to keep a lookuptable
01465         # FIXME  <- !!
01466         global _lookuptable
01467         _lookuptable = {}
01468         
01469         for label,obj in d.iteritems():
01470             setattr(p,label,obj)
01471             if not isinstance(obj,list): _lookuptable[obj] = label
01472         for label,obj in prefers.iteritems():
01473             setattr(p,label,obj)
01474         pa = _ProcessAdapter(sequences,p)
01475         for label,obj in sequences.iteritems():
01476             setattr(pa,label,obj.make(pa))
01477         for label,obj in series:
01478             setattr(p,label,obj.make(p))
01479         if schedule is not None:
01480             pathlist = []
01481             for label in schedule.labels:
01482                pathlist.append( getattr(p,label))
01483             p.schedule = cms.Schedule(*pathlist)
01484     except Exception, e:
01485         raise RuntimeError("the process contains the error \n"+str(e))    
01486 #    p = cms.PSet(*[],**d)
01487     return p
01488 
01489 
01490 processNode = plugin|PSetParameter|VPSetParameter|block|include|path|endpath|sequence|schedule|replace
01491 processBody = pp.OneOrMore(processNode)
01492 processBody.ignore(pp.cppStyleComment)
01493 processBody.ignore(pp.pythonStyleComment)
01494 
01495 
01496 #.cfi
01497 onlyPlugin = plugin|pp.empty+pp.StringEnd()
01498 #.cff
01499 onlyProcessBody = processBody|pp.empty+pp.StringEnd()
01500 onlyProcessBody.ignore(pp.cppStyleComment)
01501 onlyProcessBody.ignore(pp.pythonStyleComment)
01502 onlyParameters = parameters|pp.empty+pp.StringEnd()
01503 onlyFragment =processBody|parameters|plugin|pp.empty+pp.StringEnd()
01504 onlyFragment.ignore(pp.cppStyleComment)
01505 onlyFragment.ignore(pp.pythonStyleComment)
01506 #.cfg
01507 process = pp.Group(pp.Suppress('process')+label+_equalTo+
01508                    _scopeBegin+
01509                      pp.Group(processBody)+
01510                    _scopeEnd).setParseAction(_makeProcess)+pp.StringEnd()
01511 process.ignore(pp.cppStyleComment)
01512 process.ignore(pp.pythonStyleComment)
01513 
01514 cfgDumper = pp.Group(pp.Suppress('process')+label+_equalTo+
01515                    _scopeBegin+
01516                      pp.Group(processBody)+
01517                    _scopeEnd).setParseAction(_dumpCfg)+pp.StringEnd()
01518 cfgDumper.ignore(pp.cppStyleComment)
01519 cfgDumper.ignore(pp.pythonStyleComment)
01520 
01521 
01522 def dumpDict(d):
01523     result = 'import FWCore.ParameterSet.Config as cms\n\n'
01524     options = PrintOptions()
01525     options.isCfg = False
01526     return result+dumpPython(d, options)
01527 
01528 
01529 def dumpPython(d, options):
01530     # play it safe: includes first, then others, then replaces
01531     includes = ''
01532     replaces = ''
01533     others = ''
01534     sequences = ''
01535     schedules = ''
01536     prefix = ''
01537     if options.isCfg:
01538         prefix = 'process.'
01539     for key,value in d:
01540         newLabel = prefix+key
01541         # dashes aren't allowed in python identifier
01542         newLabel.replace('-','_')
01543         if isinstance(value,_IncludeFromNode):
01544             value.createFile(False)
01545             includes += value.dumpPythonAs(newLabel, options)
01546         elif isinstance(value,_IncludeNode):
01547             value.createFile(False)
01548             includes += value.dumpPython(options)+"\n"
01549         elif isinstance(value,_ReplaceNode):
01550             replaces += prefix+value.dumpPython(options)+"\n"
01551         elif isinstance(value,_ModuleSeries):
01552             sequences += newLabel+" = "+value.dumpPython(options)+"\n"
01553         elif isinstance(value,_Schedule):
01554             schedules += newLabel+" = "+value.dumpPython(options)+"\n"
01555         elif isinstance(value, cms.ESPrefer):
01556             others += value.dumpPythonAs(key, options)
01557         else:
01558             others += newLabel+" = "+value.dumpPython(options)+"\n"
01559     return includes+others+sequences+schedules+replaces+"\n"
01560 
01561 class _ConfigReturn(object):
01562     def __init__(self,d):
01563         for key,value in d.iteritems():
01564             setattr(self, key, value)
01565     def commentedOutRepr(self):
01566         # make sure all the top-level Labelables are labelled
01567         for key,value in self.__dict__.iteritems():
01568             if isinstance(value, cms._Labelable):
01569                 value.setLabel(key)
01570         result = 'import FWCore.ParameterSet.Config as cms\n'
01571         # play it safe: includes first, then others, then replaces
01572         return dumpDict(self.__dict__.iteritems())
01573 
01574 def parseCfgFile(fileName):
01575     """Read a .cfg file and create a Process object"""
01576     #NOTE: should check for file first in local directory
01577     # and then using FileInPath
01578 
01579     global _allUsingLabels
01580     global _fileStack
01581     _allUsingLabels = set()
01582     oldFileStack = _fileStack
01583     _fileStack = [fileName]
01584     import os.path
01585     try:
01586         if os.path.exists(fileName):
01587             f=open(fileName)
01588         else:
01589             f=_fileFactory(fileName)
01590         return process.parseFile(f)[0]
01591     finally:
01592         _fileStack = oldFileStack
01593 
01594 def parseCffFile(fileName):
01595     """Read a .cff file and return a dictionary"""
01596     global _fileStack
01597     _fileStack.append(fileName)
01598     try:
01599         t=onlyFragment.parseFile(_fileFactory(fileName))
01600         global _allUsingLabels
01601         #_allUsingLabels = set() # do I need to reset here?
01602         d=_finalizeProcessFragment(t,_allUsingLabels)
01603         return _ConfigReturn(d)
01604     finally:
01605         _fileStack.pop()
01606 
01607 def parseConfigString(aString):
01608     """Read an old style config string and return a dictionary"""
01609     t=onlyFragment.parseString(aString)
01610     global _allUsingLabels
01611     d=_finalizeProcessFragment(t,_allUsingLabels)
01612     return _ConfigReturn(d)
01613                     
01614 def dumpCfg(fileName):
01615     return cfgDumper.parseFile(_fileFactory(fileName))[0]
01616 
01617 
01618 def dumpCff(fileName):
01619     # we need to process the Usings, but leave the Includes and Replaces
01620     values = onlyFragment.parseFile(_fileFactory(fileName))
01621     # copy from whatever got returned into a list
01622     compressedValues = _getCompressedNodes(fileName, 0, values)
01623     # make sure all the top-level Labelables are labelled
01624     for key,value in compressedValues:
01625         if isinstance(value, cms._Labelable):
01626             value.setLabel(key)
01627 
01628     _validateSequences(compressedValues)
01629 
01630     return dumpDict(compressedValues)
01631 
01632 def _validateSequences(values):
01633     """ Takes the usual list of pairs, and for each
01634     sequence, checks see if the keys are defined yet.
01635     Adds a placeholders for missing keys"""
01636     keys = set()
01637     leaves = list()
01638     expandedValues = _findAndHandleProcessBlockIncludes(values)
01639     for key, value in expandedValues:
01640         keys.add(key)
01641         if isinstance(value, _ModuleSeries):
01642            value.getLeaves(leaves)
01643     for leaf in leaves:
01644         if not leaf._label in keys:
01645             leaf._label = "cms.SequencePlaceholder(\""+leaf._label+"\")"
01646 
01647 def processFromString(configString):
01648     """Reads a string containing the equivalent content of a .cfg file and
01649     creates a Process object"""
01650     global _allUsingLabels
01651     global _fileStack
01652     _allUsingLabels = set()
01653     oldFileStack = _fileStack
01654     _fileStack = ["{string}"]
01655     try:
01656         return process.parseString(configString)[0]
01657     finally:
01658         _fileStack = oldFileStack
01659 
01660 def importConfig(fileName):
01661     """Use the file extension to decide how to parse the file"""
01662     ext = fileName[fileName.rfind('.'):]
01663     if ext == '.cfg':
01664         return parseCfgFile(fileName)
01665     if ext != '.cff' and ext != '.cfi':
01666         raise RuntimeError("the file '"+fileName+"' has an unknown extension")
01667     return parseCffFile(fileName)
01668     
01669 if __name__=="__main__":
01670     import unittest
01671     import StringIO
01672     class TestFactory(object):
01673         def __init__(self,name, contents):
01674             self._name=name
01675 
01676             self._contents = contents
01677         def __call__(self, filename):
01678             if self._name != filename:
01679                 raise RuntimeError("wrong file name, expected "+self._name+' saw '+filename)
01680             return StringIO.StringIO(self._contents)
01681 
01682     class TestModuleCommand(unittest.TestCase):
01683         def setUp(self):
01684             """Nothing to do """
01685             #print 'testing'
01686         def testPlaceholder(self):
01687             t=path.parseString('path p = {out}')
01688             _validateSequences(t)
01689             self.assertEqual(repr(t[0][1]), "cms.Path(cms.SequencePlaceholder(\"out\"))")
01690 
01691         def testLetterstart(self):
01692             t = letterstart.parseString("abcd")
01693             self.assertEqual(len(t),1)
01694             self.assertEqual(t[0],"abcd")
01695             t = letterstart.parseString("a1cd")
01696             self.assertEqual(len(t),1)
01697             self.assertEqual(t[0],"a1cd")
01698             t = letterstart.parseString("a_cd")
01699             self.assertEqual(t[0],"a_cd")
01700             t = letterstart.parseString("a-cd")
01701             self.assertEqual(t[0],"a-cd")
01702             self.assertRaises(pp.ParseBaseException,letterstart.parseString,("1abc"))
01703         def testParameters(self):
01704             t=onlyParameters.parseString("bool blah = True")
01705             d =dict(iter(t))
01706             self.assertEqual(type(d['blah']),cms.bool)
01707             self.assertEqual(d['blah'].value(),True)
01708             t=onlyParameters.parseString("bool blah = 1")
01709             d =dict(iter(t))
01710             self.assertEqual(type(d['blah']),cms.bool)
01711             self.assertEqual(d['blah'].value(),True)
01712             t=onlyParameters.parseString("bool blah = False")
01713             d =dict(iter(t))
01714             self.assertEqual(type(d['blah']),cms.bool)
01715             self.assertEqual(d['blah'].value(),False)
01716             t=onlyParameters.parseString("bool blah = 2")
01717             d =dict(iter(t))
01718             self.assertEqual(type(d['blah']),cms.bool)
01719             self.assertEqual(d['blah'].value(),True)
01720             t=onlyParameters.parseString("vint32 blah = {}")
01721             d=dict(iter(t))
01722             self.assertEqual(type(d['blah']),cms.vint32)
01723             self.assertEqual(len(d['blah']),0)
01724             t=onlyParameters.parseString("vint32 blah = {1}")
01725             d=dict(iter(t))
01726             self.assertEqual(type(d['blah']),cms.vint32)
01727             self.assertEqual(d['blah'],[1])
01728             t=onlyParameters.parseString("vint32 blah = {1,2}")
01729             d=dict(iter(t))
01730             self.assertEqual(type(d['blah']),cms.vint32)
01731             self.assertEqual(d['blah'],[1,2])
01732             t=onlyParameters.parseString("string blah = 'a string'")
01733             d=dict(iter(t))
01734             self.assertEqual(type(d['blah']),cms.string)
01735             self.assertEqual(d['blah'].value(),'a string')
01736             t=onlyParameters.parseString('string blah = "a string"')
01737             d=dict(iter(t))
01738             self.assertEqual(type(d['blah']),cms.string)
01739             self.assertEqual(d['blah'].value(),'a string')
01740             t=onlyParameters.parseString('string blah = "\\0"')
01741             d=dict(iter(t))
01742             self.assertEqual(type(d['blah']),cms.string)
01743             self.assertEqual(d['blah'].value(),'\0')
01744 
01745             t=onlyParameters.parseString("vstring blah = {}")
01746             d=dict(iter(t))
01747             self.assertEqual(type(d['blah']),cms.vstring)
01748             self.assertEqual(len(d['blah']),0)
01749             t=onlyParameters.parseString("vstring blah = {'abc'}")
01750             d=dict(iter(t))
01751             self.assertEqual(type(d['blah']),cms.vstring)
01752             self.assertEqual(d['blah'],['abc'])
01753             t=onlyParameters.parseString("vstring blah = {'abc','def'}")
01754             d=dict(iter(t))
01755             self.assertEqual(type(d['blah']),cms.vstring)
01756             self.assertEqual(d['blah'],['abc','def'])
01757             
01758             t = onlyParameters.parseString("InputTag blah = tag")
01759             d=dict(iter(t))
01760             self.assertEqual(type(d['blah']),cms.InputTag)
01761             self.assertEqual(d['blah'].moduleLabel,'tag')
01762             self.assertEqual(d['blah'].productInstanceLabel,'')
01763             t = onlyParameters.parseString("InputTag blah = tag:")
01764             d=dict(iter(t))
01765             self.assertEqual(type(d['blah']),cms.InputTag)
01766             self.assertEqual(d['blah'].moduleLabel,'tag')
01767             self.assertEqual(d['blah'].productInstanceLabel,'')
01768 
01769             t = onlyParameters.parseString("InputTag blah =tag:youIt")
01770             # FAILS!
01771             #  = onlyParameters.parseString("InputTag blah = \"tag:youIt\"")
01772             d=dict(iter(t))
01773             self.assertEqual(type(d['blah']),cms.InputTag)
01774             self.assertEqual(d['blah'].moduleLabel,'tag')
01775             self.assertEqual(d['blah'].productInstanceLabel,'youIt')
01776 
01777             t = onlyParameters.parseString("InputTag blah = tag::proc")
01778             d=dict(iter(t))
01779             self.assertEqual(type(d['blah']),cms.InputTag)
01780             self.assertEqual(d['blah'].moduleLabel,'tag')
01781             self.assertEqual(d['blah'].processName,'proc')
01782                                                  
01783             t = onlyParameters.parseString("InputTag blah = tag:youIt:Now")
01784             d=dict(iter(t))
01785             self.assertEqual(type(d['blah']),cms.InputTag)
01786             self.assertEqual(d['blah'].moduleLabel,'tag')
01787             self.assertEqual(d['blah'].productInstanceLabel,'youIt')
01788             self.assertEqual(d['blah'].processName,'Now')
01789 
01790             t=onlyParameters.parseString("VInputTag blah = {}")
01791             d=dict(iter(t))
01792             self.assertEqual(type(d['blah']),cms.VInputTag)
01793             self.assertEqual(len(d['blah']),0)
01794             t=onlyParameters.parseString("VInputTag blah = {abc}")
01795             d=dict(iter(t))
01796             self.assertEqual(type(d['blah']),cms.VInputTag)
01797             self.assertEqual(d['blah'],[cms.InputTag('abc')])
01798             t=onlyParameters.parseString("VInputTag blah = {abc, def}")
01799             d=dict(iter(t))
01800             self.assertEqual(type(d['blah']),cms.VInputTag)
01801             self.assertEqual(d['blah'],[cms.InputTag('abc'),cms.InputTag('def')])
01802             t=onlyParameters.parseString("VInputTag blah = {'abc', def}")
01803             d=dict(iter(t))
01804             self.assertEqual(type(d['blah']),cms.VInputTag)
01805             self.assertEqual(d['blah'],[cms.InputTag('abc'),cms.InputTag('def')])
01806 
01807 
01808             t=onlyParameters.parseString("EventID eid= 1:2")
01809             d=dict(iter(t))
01810             self.assertEqual(type(d['eid']),cms.EventID)
01811             self.assertEqual(d['eid'].run(), 1)
01812             self.assertEqual(d['eid'].event(), 2)
01813             t=onlyParameters.parseString("LuminosityBlockID lbid= 1:2")
01814             d=dict(iter(t))
01815             self.assertEqual(type(d['lbid']),cms.LuminosityBlockID)
01816             self.assertEqual(d['lbid'].run(), 1)
01817             self.assertEqual(d['lbid'].luminosityBlock(), 2)
01818 
01819 
01820             
01821             t=onlyParameters.parseString("PSet blah = {}")
01822             d=dict(iter(t))
01823             self.assertEqual(type(d['blah']),cms.PSet)
01824 
01825             t=onlyParameters.parseString("PSet blah = {int32 ick = 1 }")
01826             d=dict(iter(t))
01827             self.assertEqual(type(d['blah']),cms.PSet)
01828             self.assertEqual(d['blah'].ick.value(), 1)            
01829 
01830             t=onlyParameters.parseString("""PSet blah = {
01831                                          int32 ick = 1
01832                                          }""")
01833             d=dict(iter(t))
01834             self.assertEqual(type(d['blah']),cms.PSet)
01835             self.assertEqual(d['blah'].ick.value(), 1)            
01836 
01837             t=onlyParameters.parseString("""PSet blah = {
01838                                          InputTag t1 = abc: 
01839                                          InputTag t2 = def:GHI
01840                                          }""")
01841             d=dict(iter(t))
01842             self.assertEqual(type(d['blah']),cms.PSet)
01843 
01844             t=onlyParameters.parseString("VPSet blah = {}")
01845             d=dict(iter(t))
01846             self.assertEqual(type(d['blah']),cms.VPSet)
01847             
01848             t=onlyParameters.parseString("VPSet blah = { {} }")
01849             d=dict(iter(t))
01850             self.assertEqual(type(d['blah']),cms.VPSet)
01851             self.assertEqual(len(d['blah']),1)
01852 
01853             t=onlyParameters.parseString("VPSet blah = { {int32 ick = 1 } }")
01854             d=dict(iter(t))
01855             self.assertEqual(type(d['blah']),cms.VPSet)
01856             self.assertEqual(len(d['blah']),1)
01857             t=onlyParameters.parseString("VPSet blah = { {int32 ick = 1 }, {int32 ick =2} }")
01858             d=dict(iter(t))
01859             self.assertEqual(type(d['blah']),cms.VPSet)
01860             self.assertEqual(len(d['blah']),2)
01861             
01862             t=onlyParameters.parseString("secsource blah = Foo {int32 ick=1}")
01863             d=dict(iter(t))
01864             self.assertEqual(type(d['blah']),cms.SecSource)
01865 
01866         def testValidation(self):
01867             self.assertRaises(pp.ParseFatalException,onlyParameters.parseString,("""
01868 PSet blah = {
01869   int32 ick = 1
01870   int32 ick = 2
01871 }"""),**dict())
01872             global _fileFactory
01873             oldFactory = _fileFactory
01874             try:
01875                 _fileFactory = TestFactory('blah.cfi', 'int32 blah = 1')
01876                 t=onlyParameters.parseString("""
01877 PSet blah = {
01878   include "blah.cfi"
01879   include "blah.cfi"
01880 }""")
01881                 d = dict(iter(t))
01882                 self.assertEqual(getattr(d['blah'],"blah").value(), 1)
01883                 _fileFactory = TestFactory('blah.cfi', 'int32 blah = 1')
01884                 self.assertRaises(pp.ParseFatalException,onlyParameters.parseString,("""
01885 PSet blah = {
01886   include "blah.cfi"
01887    int32 blah = 2
01888 }"""),**dict())
01889             finally:
01890                 _fileFactory=oldFactory
01891         def testUsing(self):
01892             #self.assertRaises(pp.ParseFatalException,onlyParameters.parseString,("PSet blah = {using ick}"),**dict())
01893             t=onlyParameters.parseString("PSet blah = {using ick}")
01894             d=dict(iter(t))
01895             self.assertEqual(type(d['blah']),cms.PSet)
01896             self.assertEqual(d['blah'].using_ick.value(), 'ick')
01897         def testInclude(self):
01898             #for testing use a different factory
01899             import StringIO
01900             global _fileFactory
01901             oldFactory = _fileFactory
01902             try:
01903                 _fileFactory = TestFactory('Sub/Pack/data/foo.cff', 'int32 blah = 1')
01904                 t=onlyParameters.parseString("PSet blah = {include 'Sub/Pack/data/foo.cff'}")
01905                 d=dict(iter(t))
01906                 self.assertEqual(type(d['blah']),cms.PSet)
01907                 self.assertEqual(getattr(d['blah'],"blah").value(), 1)
01908                 
01909                 _fileFactory = TestFactory('Sub/Pack/data/foo.cfi', 'module foo = TestProd {}')
01910                 t=onlyProcessBody.parseString("include 'Sub/Pack/data/foo.cfi'")
01911                 d=dict(iter(t))
01912                 self.assertEqual(d['Sub/Pack/data/foo.cfi'].filename, 'Sub/Pack/data/foo.cfi')
01913                 t = _findAndHandleProcessBlockIncludes(t)
01914                 d=dict(iter(t))
01915                 self.assertEqual(type(d['foo']),cms.EDProducer)
01916                 
01917                 #test ending with a comment
01918                 _fileFactory = TestFactory('Sub/Pack/data/foo.cfi', """module c = CProd {}
01919 #""")
01920                 t=onlyProcessBody.parseString("""module b = BProd {}
01921                                               include 'Sub/Pack/data/foo.cfi'""")
01922                 d=dict(iter(t))
01923                 self.assertEqual(d['Sub/Pack/data/foo.cfi'].filename, 'Sub/Pack/data/foo.cfi')
01924                 t = _findAndHandleProcessBlockIncludes(t)
01925 
01926                 _fileFactory = TestFactory('Sub/Pack/data/foo.cfi', "include 'Sub/Pack/data/foo.cfi'")
01927                 t=onlyProcessBody.parseString("include 'Sub/Pack/data/foo.cfi'")
01928                 d=dict(iter(t))
01929                 self.assertEqual(d['Sub/Pack/data/foo.cfi'].filename, 'Sub/Pack/data/foo.cfi')
01930                 self.assertRaises(RuntimeError,_findAndHandleProcessBlockIncludes,t)
01931                 #t = _findAndHandleProcessBlockIncludes(t)
01932 
01933                 _fileFactory = TestFactory('Sub/Pack/data/foo.cff', '#an empty file')
01934                 t=onlyParameters.parseString("PSet blah = {include 'Sub/Pack/data/foo.cff'}")
01935                 d=dict(iter(t))
01936                 self.assertEqual(type(d['blah']),cms.PSet)
01937 
01938                 #test block
01939                 _fileFactory = TestFactory('Sub/Pack/data/foo.cff', """block c = { ##
01940                                            ##
01941                                            double EBs25notContainment = 0.965}
01942 """)
01943                 t=onlyProcessBody.parseString("""module b = BProd {using c}
01944                                               include 'Sub/Pack/data/foo.cff'""")
01945                 d=dict(iter(t))
01946                 self.assertEqual(d['Sub/Pack/data/foo.cff'].filename, 'Sub/Pack/data/foo.cff')
01947                 t = _findAndHandleProcessBlockIncludes(t)
01948                 
01949                 _fileFactory = TestFactory('Sub/Pack/data/foo.cff',
01950                                            """path p = {doesNotExist}""")
01951                 try:
01952                     process.parseString("""process T = { include 'Sub/Pack/data/foo.cff' }""")
01953                 except Exception,e:
01954                     self.assertEqual(str(e),
01955 """the process contains the error 
01956 path 'p' contains the error: 'Process' object has no attribute 'doesNotExist'
01957  from file Sub/Pack/data/foo.cff (at char 4), (line:1, col:5)""")
01958                 else:
01959                     self.fail("failed to throw exception")
01960             finally:
01961                 _fileFactory = oldFactory
01962         def testParseCffFile(self):
01963             import StringIO
01964             global _fileFactory
01965             oldFactory = _fileFactory
01966             try:
01967                 _fileFactory = TestFactory('Sub/Pack/data/foo.cff',
01968                                            """module a = AProducer {}
01969                                            sequence s1 = {s}
01970                                            sequence s = {a}""")
01971                 p=parseCffFile('Sub/Pack/data/foo.cff')
01972                 self.assertEqual(p.a.type_(),'AProducer')
01973                 self.assertEqual(type(p.s1),cms.Sequence)
01974                 self.assertTrue(p.s1._seq is p.s)
01975                 pr=cms.Process('Test')
01976                 pr.extend(p)
01977                 self.assertEqual(str(pr.s),'a')
01978                 pr.dumpConfig()
01979             finally:
01980                 _fileFactory = oldFactory
01981             
01982         def testPlugin(self):
01983             t=plugin.parseString("source = PoolSource { }")
01984             d=dict(iter(t))
01985             self.assertEqual(type(d['source']),cms.Source)
01986             self.assertEqual(d['source'].type_(),"PoolSource")
01987             
01988             t=plugin.parseString("source = PoolSource { }")
01989             d=dict(iter(t))
01990             self.assertEqual(type(d['source']),cms.Source)
01991             self.assertEqual(d['source'].type_(),"PoolSource")
01992 
01993             t=plugin.parseString("service = MessageLogger { }")
01994             d=dict(iter(t))
01995             self.assertEqual(type(d['MessageLogger']),cms.Service)
01996             self.assertEqual(d['MessageLogger'].type_(),"MessageLogger")
01997             
01998             t=plugin.parseString("module foo = FooMod { }")
01999             d=dict(iter(t))
02000             self.assertEqual(type(d['foo']),cms.EDFilter)
02001             self.assertEqual(d['foo'].type_(),"FooMod")
02002             
02003             t=plugin.parseString("module out = AsciiOutputModule { }")
02004             d=dict(iter(t))
02005             self.assertEqual(type(d['out']),cms.OutputModule)
02006             self.assertEqual(d['out'].type_(),"AsciiOutputModule")
02007 
02008             t=plugin.parseString("module foo = FooProd { }")
02009             d=dict(iter(t))
02010             self.assertEqual(type(d['foo']),cms.EDProducer)
02011             self.assertEqual(d['foo'].type_(),"FooProd")
02012             
02013             t=plugin.parseString("module foo = FooProducer { }")
02014             d=dict(iter(t))
02015             self.assertEqual(type(d['foo']),cms.EDProducer)
02016             self.assertEqual(d['foo'].type_(),"FooProducer")
02017 
02018             t=plugin.parseString("es_module = NoLabel {}")
02019             d=dict(iter(t))
02020             self.assertEqual(type(d['NoLabel']),cms.ESProducer)
02021             self.assertEqual(d['NoLabel'].type_(),"NoLabel")
02022  
02023             t=plugin.parseString("es_module foo = WithLabel {}")
02024             d=dict(iter(t))
02025             self.assertEqual(type(d['foo']),cms.ESProducer)
02026             self.assertEqual(d['foo'].type_(),"WithLabel")
02027             
02028             t=plugin.parseString("""module mix = MixingModule {
02029             secsource input = PoolRASource {
02030                vstring fileNames = {}
02031                }
02032             }
02033             """)
02034             global _fileFactory
02035             oldFactory = _fileFactory
02036             try:
02037                 _fileFactory = TestFactory('Sub/Pack/data/foo.cfi', 'module foo = TestProd {}')
02038                 t=plugin.parseString("module bar = foo from 'Sub/Pack/data/foo.cfi'")
02039                 t = _findAndHandleProcessBlockIncludes(t)
02040                 d = dict(iter(t))
02041                 self.assertEqual(type(d['bar']),cms.EDProducer)
02042                 self.assertEqual(d['bar'].type_(),"TestProd")
02043                 
02044                 
02045                 _fileFactory = TestFactory('Sub/Pack/data/foo.cfi', 'es_module foo = TestProd {}')
02046                 t=plugin.parseString("es_module bar = foo from 'Sub/Pack/data/foo.cfi'")
02047                 t = _findAndHandleProcessBlockIncludes(t)
02048                 d=dict(iter(t))
02049                 self.assertEqual(type(d['bar']),cms.ESProducer)
02050                 self.assertEqual(d['bar'].type_(),"TestProd")
02051             finally:
02052                 _fileFactory = oldFactory
02053 
02054             self.assertRaises(pp.ParseFatalException,
02055                               plugin.parseString,
02056                               ("""es_module foo = WithLabel {
02057                                  uint32 a = 1
02058                                  int32 a = 1
02059                                  }"""))
02060         def testProcess(self):
02061             global _allUsingLabels
02062             _allUsingLabels = set()
02063             t=process.parseString(
02064 """
02065 process RECO = {
02066    source = PoolSource {
02067      untracked vstring fileNames = {"file:foo.root"}
02068    }
02069    module out = PoolOutputModule {
02070      untracked string fileName = "blah.root"
02071    }
02072    path p = {out}
02073 }""")
02074             self.assertEqual(t[0].source.type_(),"PoolSource")
02075             self.assertEqual(t[0].out.type_(),"PoolOutputModule")
02076             self.assertEqual(type(t[0].p),cms.Path)
02077             self.assertEqual(str(t[0].p),'out')
02078             #print t[0].dumpConfig()
02079             import StringIO
02080             global _fileFactory
02081             oldFactory = _fileFactory
02082             try:
02083                 _fileFactory = TestFactory('Sub/Pack/data/foo.cfi',
02084                                            'module foo = FooProd {}')
02085                 _allUsingLabels = set()
02086                 t=process.parseString(
02087 """
02088 process RECO = {
02089    source = PoolSource {
02090      untracked vstring fileNames = {"file:foo.root"}
02091    }
02092    include "Sub/Pack/data/foo.cfi"
02093    path p = {foo}
02094 }""")
02095                 self.assertEqual(t[0].foo.type_(),"FooProd")
02096             finally:
02097                 _fileFactory = oldFactory
02098 
02099             _allUsingLabels = set()
02100             t=process.parseString(
02101 """
02102 process RECO = {
02103    source = PoolSource {
02104      untracked vstring fileNames = {"file:foo.root"}
02105    }
02106    module out = PoolOutputModule {
02107      untracked string fileName = "blah.root"
02108    }
02109    endpath e = {out}
02110    module foo = FooProd {}
02111    module bar = BarProd {}
02112    module fii = FiiProd {}
02113    path p = {s&fii}
02114    sequence s = {foo,bar}
02115 }""")
02116             self.assertEqual(str(t[0].p),'foo*bar+fii')
02117             self.assertEqual(str(t[0].s),'foo*bar')
02118             t[0].dumpConfig()
02119 
02120             _allUsingLabels = set()
02121             t=process.parseString(
02122 """
02123 process RECO = {
02124    source = PoolSource {
02125      untracked vstring fileNames = {"file:foo.root"}
02126    }
02127    module out = PoolOutputModule {
02128      untracked string fileName = "blah.root"
02129    }
02130    endpath e = {out}
02131    module foo = FooProd {}
02132    module bar = BarProd {}
02133    module fii = FiiProd {}
02134    path p = {s&!fii}
02135    sequence s = {foo,bar}
02136 }""")
02137             self.assertEqual(str(t[0].p),'foo*bar+~fii')
02138             self.assertEqual(str(t[0].s),'foo*bar')
02139             t[0].dumpConfig()
02140             
02141             s="""
02142 process RECO = {
02143     module foo = FooProd {}
02144     path p = {fo}
02145 }
02146 """
02147             self.assertRaises(RuntimeError,process.parseString,(s),**dict())
02148             try:
02149                 _allUsingLabels = set()
02150                 t=process.parseString(s)
02151             except Exception, e:
02152                 print e
02153 
02154             _allUsingLabels = set()
02155             t=process.parseString("""
02156 process RECO = {
02157    block outputStuff = {
02158       vstring outputCommands = {"drop *"}
02159    }
02160    block toKeep = {
02161       vstring outputCommands = {"keep blah_*_*_*"}
02162    }
02163    replace outputStuff.outputCommands += toKeep.outputCommands
02164 }
02165 """)
02166             self.assertEqual(t[0].outputStuff.outputCommands,["drop *","keep blah_*_*_*"])
02167 
02168             _allUsingLabels = set()
02169             t=process.parseString("""
02170 process RECO = {
02171   module i = iterativeCone5CaloJets from "FWCore/ParameterSet/test/chainIncludeModule.cfi"
02172 }
02173 """)
02174             self.assertEqual(t[0].i.jetType.value(), "CaloJet")
02175 
02176 
02177             _allUsingLabels = set()
02178             t=process.parseString("""
02179 process RECO = {
02180   include "FWCore/ParameterSet/test/chainIncludeBlock.cfi"
02181   replace CaloJetParameters.inputEMin = 0.1
02182   module i = iterativeConeNoBlock from "FWCore/ParameterSet/test/chainIncludeModule2.cfi"
02183 }
02184 """)
02185             self.assertEqual(t[0].i.jetType.value(), "CaloJet")
02186             self.assertEqual(t[0].i.inputEMin.value(), 0.1)
02187 
02188 
02189 
02190             _allUsingLabels = set()
02191             t=process.parseString("""
02192 process RECO = {
02193    block outputStuff = {
02194       vstring outputCommands = {"drop *"}
02195    }
02196    block toKeep1 = {
02197       vstring outputCommands = {"keep blah1_*_*_*"}
02198    }
02199    block toKeep2 = {
02200       vstring outputCommands = {"keep blah2_*_*_*"}
02201    }
02202    block toKeep3 = {
02203       vstring outputCommands = {"keep blah3_*_*_*"}
02204    }
02205    replace outputStuff.outputCommands += toKeep1.outputCommands
02206    replace outputStuff.outputCommands += toKeep2.outputCommands
02207    replace outputStuff.outputCommands += toKeep3.outputCommands
02208 }
02209 """)
02210             self.assertEqual(t[0].outputStuff.outputCommands,["drop *",
02211                                                               "keep blah1_*_*_*",
02212                                                               "keep blah2_*_*_*",
02213                                                               "keep blah3_*_*_*"])
02214 
02215             _allUsingLabels = set()
02216             t=process.parseString("""
02217 process RECO = {
02218    block outputStuff = {
02219       vstring outputCommands = {"drop *"}
02220    }
02221    block toKeep1 = {
02222       vstring outputCommands = {"keep blah1_*_*_*"}
02223    }
02224    block toKeep2 = {
02225       vstring outputCommands = {"keep blah2_*_*_*"}
02226    }
02227    block toKeep3 = {
02228       vstring outputCommands = {"keep blah3_*_*_*"}
02229    }
02230    replace outputStuff.outputCommands += toKeep1.outputCommands
02231    replace outputStuff.outputCommands += toKeep2.outputCommands
02232    replace outputStuff.outputCommands += toKeep3.outputCommands
02233 
02234     module out = PoolOutputModule {
02235         using outputStuff
02236     }
02237 }
02238 """)
02239             self.assertEqual(t[0].out.outputCommands,["drop *",
02240                                                               "keep blah1_*_*_*",
02241                                                               "keep blah2_*_*_*",
02242                                                               "keep blah3_*_*_*"])
02243             t=process.parseString("""
02244 process RECO = {
02245    block FEVTEventContent = {
02246       vstring outputCommands = {"drop *"}
02247    }
02248    block FEVTSIMEventContent = {
02249       vstring outputCommands = {"drop *"}
02250    }
02251    block toKeep1 = {
02252       vstring outputCommands = {"keep blah1_*_*_*"}
02253    }
02254    block toKeep2 = {
02255       vstring outputCommands = {"keep blah2_*_*_*"}
02256    }
02257    block toKeep3 = {
02258       vstring outputCommands = {"keep blah3_*_*_*"}
02259    }
02260    
02261    block toKeepSim1 = {
02262       vstring outputCommands = {"keep blahs1_*_*_*"}
02263    }
02264    block toKeepSim2 = {
02265       vstring outputCommands = {"keep blahs2_*_*_*"}
02266    }
02267    block toKeepSim3 = {
02268       vstring outputCommands = {"keep blahs3_*_*_*"}
02269    }
02270    
02271    replace FEVTEventContent.outputCommands += toKeep1.outputCommands
02272    replace FEVTEventContent.outputCommands += toKeep2.outputCommands
02273    replace FEVTEventContent.outputCommands += toKeep3.outputCommands
02274 
02275    replace FEVTSIMEventContent.outputCommands += FEVTEventContent.outputCommands
02276 
02277    replace FEVTSIMEventContent.outputCommands += toKeepSim1.outputCommands
02278    replace FEVTSIMEventContent.outputCommands += toKeepSim2.outputCommands
02279    replace FEVTSIMEventContent.outputCommands += toKeepSim3.outputCommands
02280 
02281 }
02282 """)
02283             self.assertEqual(t[0].FEVTEventContent.outputCommands,["drop *",
02284                                                               "keep blah1_*_*_*",
02285                                                               "keep blah2_*_*_*",
02286                                                               "keep blah3_*_*_*"])
02287 
02288             self.assertEqual(t[0].FEVTSIMEventContent.outputCommands,["drop *",
02289                                                                       "drop *",
02290                                                             "keep blah1_*_*_*",
02291                                                               "keep blah2_*_*_*",
02292                                                               "keep blah3_*_*_*",
02293                                                             "keep blahs1_*_*_*",
02294                                                               "keep blahs2_*_*_*",
02295                                                               "keep blahs3_*_*_*"])
02296 
02297             t=process.parseString("""
02298 process RECO = {
02299    block FEVTEventContent = {
02300       vstring outputCommands = {"drop *"}
02301    }
02302    block FEVTSIMEventContent = {
02303       vstring outputCommands = {"drop *"}
02304    }
02305    block toKeep1 = {
02306       vstring outputCommands = {"keep blah1_*_*_*"}
02307    }
02308    block toKeep2 = {
02309       vstring outputCommands = {"keep blah2_*_*_*"}
02310    }
02311    block toKeep3 = {
02312       vstring outputCommands = {"keep blah3_*_*_*"}
02313    }
02314    
02315    block toKeepSim1 = {
02316       vstring outputCommands = {"keep blahs1_*_*_*"}
02317    }
02318    block toKeepSim2 = {
02319       vstring outputCommands = {"keep blahs2_*_*_*"}
02320    }
02321    block toKeepSim3 = {
02322       vstring outputCommands = {"keep blahs3_*_*_*"}
02323    }
02324    
02325    replace FEVTEventContent.outputCommands += toKeep1.outputCommands
02326    replace FEVTEventContent.outputCommands += toKeep2.outputCommands
02327    replace FEVTEventContent.outputCommands += toKeep3.outputCommands
02328 
02329    replace FEVTSIMEventContent.outputCommands += FEVTEventContent.outputCommands
02330 
02331    replace FEVTSIMEventContent.outputCommands += toKeepSim1.outputCommands
02332    replace FEVTSIMEventContent.outputCommands += toKeepSim2.outputCommands
02333    replace FEVTSIMEventContent.outputCommands += toKeepSim3.outputCommands
02334 
02335    module out = PoolOutputModule {
02336       using FEVTSIMEventContent
02337    }
02338 }
02339 """)
02340             self.assertEqual(t[0].FEVTEventContent.outputCommands,["drop *",
02341                                                               "keep blah1_*_*_*",
02342                                                               "keep blah2_*_*_*",
02343                                                               "keep blah3_*_*_*"])
02344 
02345             self.assertEqual(t[0].FEVTSIMEventContent.outputCommands,["drop *",
02346                                                                       "drop *",
02347                                                             "keep blah1_*_*_*",
02348                                                               "keep blah2_*_*_*",
02349                                                               "keep blah3_*_*_*",
02350                                                             "keep blahs1_*_*_*",
02351                                                               "keep blahs2_*_*_*",
02352                                                               "keep blahs3_*_*_*"])
02353             self.assertEqual(t[0].out.outputCommands,
02354                              t[0].FEVTSIMEventContent.outputCommands)
02355 
02356 
02357 #NOTE: standard cfg parser can't do the following
02358             _allUsingLabels = set()
02359             s="""
02360 process RECO = {
02361    block outputStuff = {
02362       vstring outputCommands = {"drop *"}
02363    }
02364    block aTest = {
02365       vstring outputCommands = {"keep blah_*_*_*"}
02366    }    
02367    block toKeep = {
02368       using aTest
02369    }
02370    replace outputStuff.outputCommands += toKeep.outputCommands
02371 }
02372 """
02373             self.assertRaises(RuntimeError,process.parseString,(s),**dict())
02374             #self.assertEqual(t[0].outputStuff.outputCommands,["drop *","keep blah_*_*_*"])
02375             
02376             _allUsingLabels = set()
02377             t=process.parseString("""
02378 process RECO = {
02379    block outputStuff = {
02380       vstring outputCommands = {"drop *"}
02381    }
02382    block toKeep = {
02383       vstring outputCommands = {"keep blah_*_*_*"}
02384    }
02385    
02386    block final = {
02387         using outputStuff
02388     }
02389    replace outputStuff.outputCommands += toKeep.outputCommands
02390 }
02391 """)
02392             self.assertEqual(t[0].outputStuff.outputCommands,["drop *","keep blah_*_*_*"])
02393             self.assertEqual(t[0].final.outputCommands,["drop *","keep blah_*_*_*"])
02394 
02395             _allUsingLabels = set()
02396             t=process.parseString("""
02397 process TEST = {
02398     service = MessageLogger {
02399         untracked vstring destinations = {"dummy"}
02400         untracked PSet default = {
02401                untracked int32 limit = -1
02402         }
02403         untracked PSet dummy = {}
02404     }
02405     replace MessageLogger.default.limit = 10
02406     replace MessageLogger.destinations += {"goofy"}
02407     replace MessageLogger.dummy = { untracked string threshold = "WARNING" }
02408 }""")
02409             self.assertEqual(t[0].MessageLogger.default.limit.value(),10)
02410             self.assertEqual(t[0].MessageLogger.destinations,["dummy","goofy"])
02411             self.assertEqual(t[0].MessageLogger.dummy.threshold.value(),"WARNING")
02412 
02413             _allUsingLabels = set()
02414             t=process.parseString("""
02415 process TEST = {
02416   PSet first = {
02417     int32 foo = 1
02418     int32 fii = 2
02419   }
02420   
02421   module second = AModule {
02422     using first
02423   }
02424   
02425   replace first.foo = 2
02426   
02427   replace second.fii = 3
02428 }
02429 """)
02430             self.assertEqual(t[0].first.foo.value(), 2)
02431             self.assertEqual(t[0].first.fii.value(),2)
02432             self.assertEqual(t[0].second.foo.value(),2)
02433             self.assertEqual(t[0].second.fii.value(),3)
02434             
02435             _allUsingLabels = set()
02436             t=process.parseString("""
02437 process TEST = {
02438     es_module = UnnamedProd {
02439         int32 foo = 10
02440     }
02441     
02442     es_module me = NamedProd {
02443         int32 fii = 5
02444     }
02445     
02446     replace UnnamedProd.foo = 1
02447     
02448     replace me.fii = 10
02449 }
02450 """)
02451             self.assertEqual(t[0].UnnamedProd.foo.value(),1)
02452             self.assertEqual(t[0].me.fii.value(),10)
02453             
02454             _allUsingLabels = set()
02455             t=process.parseString("""
02456 process RECO = {
02457    block outputStuff = {
02458       vstring outputCommands = {"drop *"}
02459    }
02460    block toKeep = {
02461       vstring outputCommands = {"keep blah_*_*_*"}
02462    }
02463    replace outputStuff.outputCommands += toKeep.outputCommands
02464    
02465    source = PoolSource {
02466      untracked vstring fileNames = {"file:foo.root"}
02467      untracked vint32 foos = {1}
02468    }
02469    module out = PoolOutputModule {
02470      using outputStuff
02471      untracked string fileName = "blah.root"
02472    }
02473    replace PoolSource.fileNames = {"file:bar.root"}
02474    replace out.fileName = 'blih.root'
02475    replace PoolSource.foos += 2
02476    replace PoolSource.foos += 3
02477 }""")
02478             self.assertEqual(t[0].source.fileNames,["file:bar.root"])
02479             self.assertEqual(t[0].out.fileName.value(),"blih.root")
02480             self.assertEqual(t[0].source.foos,[1,2,3])
02481             self.assertEqual(t[0].outputStuff.outputCommands,["drop *","keep blah_*_*_*"])
02482             self.assertEqual(t[0].out.outputCommands,["drop *","keep blah_*_*_*"])
02483 
02484             _allUsingLabels = set()
02485             t=process.parseString("""
02486 process RECO = {
02487     module foo = FooProd {using b}
02488     PSet b = {uint32 i = 1}
02489     PSet c = {using b}
02490     block p1 = { int32 x = 2
02491                  int32 y = 9
02492     }
02493     PSet p2 = { using p1 }
02494     module m1 = MProd { using p2 }
02495     module m2 = MProd { using p2 }
02496     block b1 = {double y = 1.1 }
02497     block b2 = {double x = 2.2 }
02498 }
02499 """)
02500             self.assertEqual(t[0].foo.i.value(),1)
02501             self.assertEqual(t[0].c.i.value(),1)
02502             self.assert_(not hasattr(t[0].foo,'using_b') )
02503             self.assertEqual(t[0].p2.x.value(),2)
02504             self.assertEqual(t[0].m1.x.value(),2)
02505             self.assertEqual(t[0].m2.x.value(),2)
02506             #print t[0].dumpConfig()
02507 
02508             _allUsingLabels = set()
02509             s="""
02510 process RECO = {
02511     module foo = FooProd {using b}
02512     PSet b = {using c}
02513     PSet c = {using b}
02514 }
02515 """
02516             self.assertRaises(RuntimeError,process.parseString,(s),**dict())
02517 
02518             _allUsingLabels = set()
02519             s="""
02520 process RECO = {
02521     module foo = FooProd {using b
02522         uint32 alreadyHere = 1
02523     }
02524     PSet b = {uint32 alreadyHere = 2}
02525 }
02526 """
02527             self.assertRaises(RuntimeError,process.parseString,(s),**dict())
02528             #this was failing because of order in which the using was applied
02529 
02530             _allUsingLabels = set()
02531             t=process.parseString("""
02532 process USER = 
02533 {
02534         source = PoolInput
02535         {
02536                 string filename = "here"
02537         }
02538 
02539         block p1 = {
02540                     int32 x = 2
02541                     int32 y = 9
02542                    }
02543         PSet  p2 = {
02544                     using p1
02545                    }
02546 
02547         module m1 = MidpointJetProducer
02548         {
02549                 using p2
02550         }
02551 
02552         module m2 = MidpointJetProducer
02553         {
02554                 using p2
02555         }
02556 
02557         block b1 = { double y = 1.1 }
02558         block b2 = { double x = 2.2 }
02559 
02560         block G = {
02561           int32 g = 0
02562         }
02563 
02564         block H = {
02565           using G
02566         }
02567 
02568         block I = {
02569           using J
02570         }
02571 
02572         block J = {
02573           int32 j = 0
02574         }
02575 
02576         replace J.j = 1
02577 
02578         module A = UnconfigurableModule { }
02579         module B = UnconfigurableModule { }
02580         module C = UnconfigurableModule { }
02581         module D = UnconfigurableModule { }
02582         module E = UnconfigurableModule { }
02583         module F = UnconfigurableModule { }
02584         module filter = UnconfigurableFilter { }
02585 
02586         sequence s0a = { A}
02587         sequence s0b = { A,B}
02588         sequence s0c = { A&B}
02589         sequence s1 = { A,B&C,(D,E)&F }
02590         sequence s2 = { C&(A,B), m1,m2,s1 }
02591         sequence s3 = {s0a}
02592 
02593         path t1 = { (A,B&C,D),s0a,filter }
02594         path t2 = { A,B,C,D }
02595         path t3 = {s3&F}
02596         endpath te = { A&B }
02597         
02598         schedule = {t1,t2}
02599 
02600 }
02601 """)
02602             self.assertEqual(t[0].p2.x.value(), 2)
02603             self.assertEqual(t[0].m1.x.value(),2)
02604             self.assertEqual(t[0].m2.x.value(),2)
02605             self.assertEqual(t[0].J.j.value(),1)
02606             self.assertEqual(t[0].I.j.value(),1)
02607             #make sure dump succeeds
02608             t[0].dumpConfig()
02609 
02610             _allUsingLabels = set()
02611             t=process.parseString("""
02612 process USER = 
02613 {
02614     block a = {int32 i = 1}
02615     PSet b = {PSet c = {using a
02616        VPSet e={{using a} } } }
02617     VPSet d = {{using a}, {}}
02618 }""")
02619             self.assertEqual(t[0].b.c.i.value(),1)
02620             self.assertEqual(t[0].d[0].i.value(),1)
02621             self.assertEqual(t[0].b.c.e[0].i.value(), 1)
02622             #make sure dump succeeds
02623             t[0].dumpConfig()
02624 
02625             _allUsingLabels = set()
02626             t=process.parseString("""
02627 process USER = 
02628 {
02629     block a = {int32 i = 1}
02630     PSet b = { PSet c = {}
02631                VPSet g = {} }
02632     replace b.c = {using a
02633        VPSet e={{using a} } }
02634     VPSet d = {{using a}, {}}
02635 }""")
02636             self.assertEqual(t[0].b.c.i.value(),1)
02637             self.assertEqual(t[0].d[0].i.value(),1)
02638             self.assertEqual(t[0].b.c.e[0].i.value(), 1)
02639             #make sure dump succeeds
02640             t[0].dumpConfig()
02641 
02642             _allUsingLabels = set()
02643             t=process.parseString("""
02644 process USER = 
02645 {
02646     block a = {int32 i = 1}
02647     PSet b = { PSet c = {} }
02648     replace b.c = { PSet d = { using a }
02649        VPSet e={{using a} } }
02650 }""")
02651             self.assertEqual(t[0].b.c.d.i.value(),1)
02652             self.assertEqual(t[0].b.c.e[0].i.value(), 1)
02653             #make sure dump succeeds
02654             t[0].dumpConfig()
02655 
02656             t=process.parseString("""
02657 process USER = 
02658 {
02659     block a = {int32 i = 1}
02660     module b = BWorker { PSet c = {} }
02661     replace b.c = { PSet d = { using a }
02662        VPSet e={{using a} } }
02663 }""")
02664             self.assertEqual(t[0].b.c.d.i.value(),1)
02665             self.assertEqual(t[0].b.c.e[0].i.value(), 1)
02666             #make sure dump succeeds
02667             t[0].dumpConfig()
02668 
02669             t=process.parseString("""
02670 process p = {
02671 
02672   block roster = {
02673     string thirdBase = 'Some dude'
02674     PSet outfielders = {
02675       string rightField = 'Some dude'
02676     }
02677   }
02678 
02679   module bums = Ballclub {
02680     using roster
02681   }
02682 
02683 
02684   module allstars = Ballclub {
02685     using roster
02686   }
02687 
02688   replace allstars.thirdBase = 'Chuck Norris'
02689   replace allstars.outfielders.rightField = 'Babe Ruth'
02690 }""")
02691             self.assertEqual(t[0].bums.thirdBase.value(), 'Some dude')
02692             self.assertEqual(t[0].bums.outfielders.rightField.value(), 'Some dude')
02693             self.assertEqual(t[0].allstars.thirdBase.value(), 'Chuck Norris')
02694             self.assertEqual(t[0].allstars.outfielders.rightField.value(), 'Babe Ruth')
02695 
02696             _allUsingLabels = set()
02697 
02698             input= """process RECO = {
02699    es_prefer label = FooESProd {
02700    }
02701    es_module label = FooESProd {
02702    }
02703 }"""
02704 
02705             t=process.parseString(input)
02706             self.assertEqual(t[0].label.type_(),"FooESProd")
02707             print t[0].dumpConfig()
02708             #self.checkRepr(t[0].dumpConfig(), input)
02709             _allUsingLabels = set()
02710             t=process.parseString(
02711 """
02712 process RECO = {
02713    es_prefer = FooESProd {
02714    }
02715    es_module = FooESProd {
02716    }
02717 }""")
02718             self.assertEqual(t[0].FooESProd.type_(),"FooESProd")
02719             print t[0].dumpConfig()
02720 
02721             
02722         def testPath(self):
02723             p = cms.Process('Test')
02724             p.out = cms.OutputModule('PoolOutputModule')
02725             p.a = cms.EDProducer('AProd')
02726             p.b = cms.EDProducer('BProd')
02727             p.c = cms.EDProducer('CProd')
02728             t=path.parseString('path p = {out}')
02729             self.assertEqual(str(t[0][1]),'out')
02730             pth = t[0][1].make(p)
02731             self.assertEqual(str(pth),'out')
02732             #setattr(p,t[0][0],pth)
02733             #print getattr(p,t[0][0])
02734             #print pth
02735 #            print t[0][1]
02736             t=path.parseString('path p = {a,b}')
02737             self.assertEqual(str(t[0][1]),'(a,b)')            
02738             self.checkRepr(t[0][1], 'cms.Path(a*b)')
02739             options = PrintOptions()
02740             options.isCfg = True
02741             self.assertEqual(t[0][1].dumpPython(options), 'cms.Path(process.a*process.b)')
02742             pth = t[0][1].make(p)
02743             self.assertEqual(str(pth),'a*b')
02744             #print pth
02745 #            print t[0][1]
02746             t=path.parseString('path p = {a&b}')
02747             self.assertEqual(str(t[0][1]),'(a&b)')
02748             pth = t[0][1].make(p)
02749             self.assertEqual(str(pth),'a+b')
02750 #            print t[0][1]
02751             t=path.parseString('path p = {a,b,c}')
02752             self.assertEqual(str(t[0][1]),'((a,b),c)')
02753             pth = t[0][1].make(p)
02754             self.assertEqual(str(pth),'a*b*c')
02755 #            print t[0][1]
02756             t=path.parseString('path p = {a&b&c}')
02757             self.assertEqual(str(t[0][1]),'((a&b)&c)')
02758             pth = t[0][1].make(p)
02759             self.assertEqual(str(pth),'a+b+c')
02760 #            print t[0][1]
02761             t=path.parseString('path p = {a&b,c}')
02762             self.assertEqual(str(t[0][1]),'(a&(b,c))')
02763             pth = t[0][1].make(p)
02764             self.assertEqual(str(pth),'a+b*c')
02765 #            print t[0][1]
02766             t=path.parseString('path p = {a,b&c}')
02767             self.assertEqual(str(t[0][1]),'((a,b)&c)')
02768             pth = t[0][1].make(p)
02769             self.assertEqual(str(pth),'a*b+c')
02770 #            print t[0][1]
02771             t=path.parseString('path p = {(a,b)&c}')
02772             self.assertEqual(str(t[0][1]),'((a,b)&c)')
02773             pth = t[0][1].make(p)
02774             self.assertEqual(str(pth),'a*b+c')
02775 #            print t[0][1]
02776             t=path.parseString('path p = {(a&b),c}')
02777             self.assertEqual(str(t[0][1]),'((a&b),c)')
02778             pth = t[0][1].make(p)
02779             self.assertEqual(str(pth),'(a+b)*c')
02780 #            print t[0][1]
02781             t=path.parseString('path p = {a,(b&c)}')
02782             self.assertEqual(str(t[0][1]),'(a,(b&c))')
02783             pth = t[0][1].make(p)
02784             self.assertEqual(str(pth),'a*(b+c)')
02785 #            print t[0][1]
02786             t=path.parseString('path p = {a&(b,c)}')
02787             self.assertEqual(str(t[0][1]),'(a&(b,c))')
02788             pth = t[0][1].make(p)
02789             self.assertEqual(str(pth),'a+b*c')
02790 #            print t[0][1]
02791             p.d = cms.Sequence(p.a*p.b)
02792             t=path.parseString('path p = {d,c}')
02793             self.assertEqual(str(t[0][1]),'(d,c)')
02794             pth = t[0][1].make(p)
02795             self.assertEqual(str(pth),'a*b*c')
02796 #            print t[0][1]
02797             t=path.parseString('path p = {a&!b}')
02798             self.assertEqual(str(t[0][1]),'(a&!b)')
02799             pth = t[0][1].make(p)
02800             self.assertEqual(str(pth),'a+~b')
02801 #            print t[0][1]
02802             t=path.parseString('path p = {!a&!b&!c}')
02803             self.assertEqual(str(t[0][1]),'((!a&!b)&!c)')
02804             pth = t[0][1].make(p)
02805             self.assertEqual(str(pth),'~a+~b+~c')
02806 
02807             t=path.parseString('path p = {a&-b}')
02808             self.assertEqual(str(t[0][1]),'(a&-b)')
02809             pth = t[0][1].make(p)
02810             self.assertEqual(str(pth),'a+cms.ignore(b)')
02811 
02812         @staticmethod
02813         def strip(value):
02814             """strip out whitespace & newlines"""
02815             return  value.replace(' ','').replace('\n','')
02816         def checkRepr(self, obj, expected):
02817             # strip out whitespace & newlines
02818             observe = self.strip(repr(obj))
02819             expect = self.strip(expected)    
02820             self.assertEqual(observe, expect)
02821         def testReplace(self):
02822             process = cms.Process("Test")
02823             process.a = cms.EDProducer('FooProd', b=cms.uint32(2))
02824             t=replace.parseString('replace a.b = 1')
02825             self.assertEqual(t[0][0],'a.b')
02826             self.assertEqual(t[0][1].path, ['a','b'])
02827             self.assertEqual(t[0][1].value,'1')
02828             self.checkRepr(t[0][1], "a.b = 1")
02829             t[0][1].do(process)
02830             self.assertEqual(process.a.b.value(),1)
02831             #print t
02832             process = cms.Process("Test")
02833             process.a = cms.EDProducer('FooProd', b=cms.PSet(c=cms.double(2)))
02834             t=replace.parseString('replace a.b.c = 1')
02835             self.assertEqual(t[0][0],'a.b.c')
02836             self.assertEqual(t[0][1].path, ['a','b','c'])
02837             self.assertEqual(t[0][1].value,'1')
02838             self.checkRepr(t[0][1], "a.b.c = 1")
02839             self.assertEqual(type(process.a.b),cms.PSet)
02840             t[0][1].do(process)
02841             self.assertEqual(type(process.a.b),cms.PSet)
02842             self.assertEqual(process.a.b.c.value(),1.0)
02843             #print t
02844             t=replace.parseString('replace a.b.c = 1.359')
02845             self.assertEqual(t[0][0],'a.b.c')
02846             self.assertEqual(t[0][1].path, ['a','b','c'])
02847             self.assertEqual(t[0][1].value,'1.359')
02848             self.checkRepr(t[0][1], "a.b.c = 1.359")
02849             t[0][1].do(process)
02850             self.assertEqual(type(process.a.b),cms.PSet)
02851             self.assertEqual(process.a.b.c.value(),1.359)
02852             #print t
02853             process = cms.Process("Test")
02854             process.a = cms.EDProducer('FooProd', b=cms.untracked.PSet())
02855             self.assertEqual(process.a.b.isTracked(),False)
02856             t=replace.parseString('replace a.b = {untracked string threshold ="DEBUG"}')
02857             t[0][1].do(process)
02858             self.assertEqual(type(process.a.b),cms.PSet)
02859             self.assertEqual(process.a.b.isTracked(),False)
02860             self.assertEqual(process.a.b.threshold.value(),"DEBUG")
02861             self.assertEqual(process.a.b.threshold.isTracked(),False)
02862             #print t
02863             process = cms.Process("Test")
02864             process.a = cms.EDProducer('FooProd', b=cms.PSet(c=cms.untracked.double(2)))
02865             self.assertEqual(process.a.b.c.value(),2.0)
02866             self.assertEqual(process.a.b.c.isTracked(),False)
02867             t=replace.parseString('replace a.b.c = 1')
02868             self.checkRepr(t[0][1], "a.b.c = 1")
02869             t[0][1].do(process)
02870             self.assertEqual(type(process.a.b),cms.PSet)
02871             self.assertEqual(process.a.b.c.value(),1.0)
02872             self.assertEqual(process.a.b.c.isTracked(),False)
02873 
02874             t=replace.parseString('replace a.b = "all that"')
02875             self.assertEqual(t[0][0],'a.b')
02876             self.assertEqual(t[0][1].path, ['a','b'])
02877             self.assertEqual(t[0][1].value,'all that')
02878             process = cms.Process("Test")
02879             process.a = cms.EDProducer('FooProd', b=cms.string('thing'))
02880             self.checkRepr(t[0][1], "a.b = \'all that\'")
02881             t[0][1].do(process)
02882             self.assertEqual(process.a.b.value(),'all that')            #print t
02883 
02884             t=replace.parseString('replace a.b = {}')
02885             self.assertEqual(t[0][0],'a.b')
02886             self.assertEqual(t[0][1].path, ['a','b'])
02887             self.assertEqual(t[0][1].value,[])
02888             self.checkRepr(t[0][1], "a.b = []")
02889 
02890             #print t
02891             t=replace.parseString('replace a.b = {1, 3, 6}')
02892             self.assertEqual(t[0][0],'a.b')
02893             self.assertEqual(t[0][1].path, ['a','b'])
02894             self.assertEqual(t[0][1].value,['1','3','6'])
02895             process = cms.Process("Test")
02896             process.a = cms.EDProducer('FooProd', b=cms.vint32())
02897             self.checkRepr(t[0][1], "a.b = [1, 3, 6]")
02898 
02899             t[0][1].do(process)
02900             self.assertEqual(len(process.a.b),3)
02901             #print t
02902             t=replace.parseString('replace a.b = {"all", "that"}')
02903             self.assertEqual(t[0][0],'a.b')
02904             self.assertEqual(t[0][1].path, ['a','b'])
02905             self.assertEqual(t[0][1].value,['all','that'])
02906             self.checkRepr(t[0][1], "a.b = [\'all\', \'that\']")
02907             t=replace.parseString('replace a.b = {"all that"}')
02908             self.assertEqual(t[0][0],'a.b')
02909             self.assertEqual(t[0][1].path, ['a','b'])
02910             self.assertEqual(t[0][1].value,['all that'])
02911 
02912             t=replace.parseString('replace a.b = { int32 i = 1 }')
02913             self.assertEqual(t[0][0],'a.b')
02914             self.assertEqual(t[0][1].path, ['a','b'])
02915             self.assertEqual(type(t[0][1].value),cms.PSet)
02916             self.assertEqual(t[0][1].value.i.value(), 1) 
02917             self.checkRepr(t[0][1], "a.b = cms.PSet(i=cms.int32(1))")
02918             process = cms.Process("Test")
02919             process.a = cms.EDProducer('FooProd', b=cms.PSet(j=cms.uint32(5)))
02920             t[0][1].do(process)
02921             self.assertEqual(process.a.b.i.value(),1)
02922             self.assertEqual(getattr(process.a.b,'j',None),None)
02923             #print t
02924 #            print t[0][1].value
02925             t=replace.parseString('replace a.b = { { int32 i = 1 } }')
02926             self.assertEqual(t[0][0],'a.b')
02927             self.assertEqual(t[0][1].path, ['a','b'])
02928             self.assertEqual(type(t[0][1].value),cms.VPSet)
02929             self.assertEqual(t[0][1].value[0].i.value(), 1) 
02930             self.checkRepr(t[0][1], "a.b = cms.VPSet(cms.PSet(i=cms.int32(1)))")
02931             process = cms.Process("Test")
02932             process.a = cms.EDProducer('FooProd', b=cms.VPSet((cms.PSet(j=cms.uint32(5)))))
02933             t[0][1].do(process)
02934             self.assertEqual(process.a.b[0].i.value(),1)
02935             
02936             process = cms.Process("Test")
02937             process.a = cms.EDProducer('FooProd', b=cms.vuint32(2))
02938             t=replace.parseString('replace a.b += 1')
02939             self.assertEqual(t[0][0],'a.b')
02940             self.assertEqual(t[0][1].path, ['a','b'])
02941             self.assertEqual(t[0][1].value,'1')
02942             self.checkRepr(t[0][1], "a.b.append(1)")
02943             t[0][1].do(process)
02944             self.assertEqual(list(process.a.b),[2,1])
02945 
02946             process = cms.Process("Test")
02947             process.a = cms.EDProducer('FooProd', b=cms.vuint32(2))
02948             t=replace.parseString('replace a.b += {1,3}')
02949             self.assertEqual(t[0][0],'a.b')
02950             self.assertEqual(t[0][1].path, ['a','b'])
02951             self.assertEqual(t[0][1].value,['1','3'])
02952             self.checkRepr(t[0][1], "a.b.extend([1,3])")
02953             t[0][1].do(process)
02954             self.assertEqual(list(process.a.b),[2,1,3])
02955             
02956             t=replace.parseString('replace a.b += "all that"')
02957             self.assertEqual(t[0][0],'a.b')
02958             self.assertEqual(t[0][1].path, ['a','b'])
02959             self.assertEqual(t[0][1].value,'all that')
02960             self.checkRepr(t[0][1], "a.b.append(\'all that\')")
02961             process = cms.Process("Test")
02962             process.a = cms.EDProducer('FooProd', b=cms.vstring('thing'))
02963             t[0][1].do(process)
02964             self.assertEqual(list(process.a.b),['thing','all that'])
02965 
02966             t=replace.parseString('replace a.b += {"all that","and more"}')
02967             self.assertEqual(t[0][0],'a.b')
02968             self.assertEqual(t[0][1].path, ['a','b'])
02969             self.assertEqual(t[0][1].value,['all that','and more'])
02970             self.checkRepr(t[0][1], "a.b.extend([\'all that\', \'and more\'])")
02971             process = cms.Process("Test")
02972             process.a = cms.EDProducer('FooProd', b=cms.vstring('thing'))
02973             t[0][1].do(process)
02974             self.assertEqual(list(process.a.b),['thing','all that','and more'])
02975 
02976             t=replace.parseString('replace a.b += { int32 i = 1 }')
02977             self.assertEqual(t[0][0],'a.b')
02978             self.assertEqual(t[0][1].path, ['a','b'])
02979             self.assertEqual(type(t[0][1].value),cms.PSet)
02980             self.assertEqual(t[0][1].value.i.value(), 1) 
02981             self.checkRepr(t[0][1], "a.b.append(cms.PSet(i=cms.int32(1)))")
02982             process = cms.Process("Test")
02983             process.a = cms.EDProducer('FooProd',
02984                                        b=cms.VPSet((cms.PSet(j=cms.uint32(5)))))
02985             t[0][1].do(process)
02986             self.assertEqual(len(process.a.b),2)
02987             self.assertEqual(process.a.b[1].i.value(),1)
02988             
02989             t=replace.parseString('replace a.b += { { int32 i = 1 } }')
02990             self.assertEqual(t[0][0],'a.b')
02991             self.assertEqual(t[0][1].path, ['a','b'])
02992             self.assertEqual(type(t[0][1].value),cms.VPSet)
02993             self.assertEqual(t[0][1].value[0].i.value(), 1) 
02994             self.checkRepr(t[0][1], "a.b.extend(cms.VPSet(cms.PSet(i=cms.int32(1))))")
02995             process = cms.Process("Test")
02996             process.a = cms.EDProducer('FooProd', b=cms.VPSet((cms.PSet(j=cms.uint32(5)))))
02997             t[0][1].do(process)
02998             self.assertEqual(len(process.a.b),2)
02999             self.assertEqual(process.a.b[1].i.value(),1)
03000 
03001             process = cms.Process("Test")
03002             process.a = cms.EDProducer('FooProd', b=cms.vuint32(2), c=cms.vuint32(1))
03003             t=replace.parseString('replace a.b += a.c')
03004             self.assertEqual(t[0][0],'a.b')
03005             self.assertEqual(t[0][1].path, ['a','b'])
03006             self.assertEqual(t[0][1].value,'a.c')
03007             self.checkRepr(t[0][1], "a.b.append(process.a.c)")
03008             t[0][1].do(process)
03009             self.assertEqual(list(process.a.b),[2,1])
03010             
03011             process = cms.Process("Test")
03012             process.a = cms.EDProducer('FooProd', b=cms.vuint32(2), c=cms.uint32(1))
03013             t=replace.parseString('replace a.b += a.c')
03014             self.assertEqual(t[0][0],'a.b')
03015             self.assertEqual(t[0][1].path, ['a','b'])
03016             self.assertEqual(t[0][1].value,'a.c')
03017             self.checkRepr(t[0][1], "a.b.append(process.a.c)")
03018             t[0][1].do(process)
03019             self.assertEqual(list(process.a.b),[2,1])
03020 
03021             process = cms.Process("Test")
03022             foobar = 'cms.InputTag("foobar","","")'
03023             fooRepr = 'foobar:'
03024             process.a = cms.EDProducer('FooProd', b=cms.InputTag("bar",""))
03025             t = replace.parseString('replace a.b = foobar:')
03026             self.checkRepr(t[0][1], "a.b ='foobar:'")
03027             t[0][1].do(process)
03028             self.assertEqual(process.a.b.configValue(),'foobar')                        
03029 
03030             process = cms.Process("Test")
03031             process.a = cms.EDProducer('FooProd', b=cms.VInputTag((cms.InputTag("bar"))))
03032             t = replace.parseString('replace a.b = {foobar:}')
03033             self.checkRepr(t[0][1], "a.b = ['foobar:']")
03034             t[0][1].do(process)
03035             #self.assertEqual(process.a.b.configValue('',''),'{\nfoobar::\n}\n')                        
03036             self.assertEqual(list(process.a.b),[cms.InputTag('foobar')])                        
03037 
03038             process = cms.Process("Test")
03039             process.a = cms.EDProducer('FooProd', b=cms.VInputTag((cms.InputTag("bar"))))
03040             t = replace.parseString('replace a.b += {foobar:}')
03041             self.checkRepr(t[0][1], "a.b.extend(['foobar:'])")
03042             t[0][1].do(process)
03043             #self.assertEqual(process.a.b.configValue('',''),'{\nfoobar::\n}\n')                        
03044             self.assertEqual(list(process.a.b),[cms.InputTag("bar"),cms.InputTag('foobar')])                        
03045 
03046             process = cms.Process("Test")
03047             process.a = cms.EDProducer("FooProd", b = cms.uint32(1))
03048             t = replace.parseString('replace a.c = 2')
03049             self.assertRaises(pp.ParseBaseException,t[0][1].do,(process))
03050 
03051     unittest.main()
03052 #try:
03053     #onlyParameters.setDebug()
03054 #     test = onlyParameters.parseString(
03055 #"""bool blah = True
03056 #untracked bool foo = False #test
03057 #int32 cut = 1
03058 #bool fii = True""")
03059 #    print test
03060 #except pp.ParseBaseException,pe:
03061 #    print pe
03062 #    print pe.markInputline()
03063 #test = letterstart.parseString("aaa")
03064 #test = letterstart.parseString("aaa_")
03065 
03066 #test = letterstart.parseString("_a")
03067 #print test
03068 

Generated on Tue Jun 9 17:36:27 2009 for CMSSW by  doxygen 1.5.4